From 8d9c13b4d8fddec5c0ea4753a3815f552fd28a1a Mon Sep 17 00:00:00 2001 From: case Date: Sun, 9 Aug 2015 15:45:11 -0400 Subject: [PATCH 001/119] `Hue`, `Saturation`, `Alpha` --- src/components/Sketch/SketchPicker.jsx | 24 --------------- src/components/common/Alpha.jsx | 37 +++++++++++++++++++++++ src/components/common/Hue.jsx | 31 +++++++++++++++++++ src/components/common/Saturation.jsx | 42 ++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 24 deletions(-) delete mode 100644 src/components/Sketch/SketchPicker.jsx create mode 100644 src/components/common/Alpha.jsx create mode 100644 src/components/common/Hue.jsx create mode 100644 src/components/common/Saturation.jsx diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx deleted file mode 100644 index e0e39726..00000000 --- a/src/components/Sketch/SketchPicker.jsx +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; - -var React = require('react'); -var ReactCSS = require('reactcss'); - -class ColorPicker extends ReactCSS.Component { - - classes() { - return { - 'default': { - - }, - }; - } - - render() { - return ( -
Sketch Picker
- ); - } - -} - -module.exports = ColorPicker; diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx new file mode 100644 index 00000000..bd12eb9c --- /dev/null +++ b/src/components/common/Alpha.jsx @@ -0,0 +1,37 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class Alpha extends ReactCSS.Component { + + classes() { + return { + 'default': { + alpha: { + Absolute: '0 0 0 0', + background: '#eee', + overflow: 'hidden', + borderRadius: this.props.radius, + }, + gradient: { + Absolute: '0 0 0 0', + background: 'linear-gradient(to right, rgba(133, 255, 0, 0) 0%, rgba(133, 255, 0, 1) 100%)', + boxShadow: this.props.shadow, + borderRadius: this.props.radius, + }, + }, + }; + } + + render() { + return ( +
+
+
+ ); + } + +} + +module.exports = Alpha; diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx new file mode 100644 index 00000000..8e2c88a9 --- /dev/null +++ b/src/components/common/Hue.jsx @@ -0,0 +1,31 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class Hue extends ReactCSS.Component { + + classes() { + return { + 'default': { + hue: { + Absolute: '0 0 0 0', + background: 'linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)', + overflow: 'hidden', + borderRadius: this.props.radius, + boxShadow: this.props.shadow, + }, + }, + }; + } + + render() { + return ( +
+
+ ); + } + +} + +module.exports = Hue; diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx new file mode 100644 index 00000000..9894cb8e --- /dev/null +++ b/src/components/common/Saturation.jsx @@ -0,0 +1,42 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class Saturation extends ReactCSS.Component { + + classes() { + return { + 'default': { + color: { + Absolute: '0 0 0 0', + background: 'rgb(133, 255, 0)', + overflow: 'hidden', + borderRadius: this.props.radius, + }, + white: { + Absolute: '0 0 0 0', + background: 'linear-gradient(to right, #fff, rgba(255,255,255,0))', + }, + black: { + Absolute: '0 0 0 0', + background: 'linear-gradient(to top, #000, rgba(0,0,0,0))', + boxShadow: this.props.shadow, + }, + }, + }; + } + + render() { + return ( +
+
+
+
+
+ ); + } + +} + +module.exports = Saturation; From 639b0d151b6c5e967a827bd0c1c9174c719ef824 Mon Sep 17 00:00:00 2001 From: case Date: Sun, 9 Aug 2015 20:16:56 -0400 Subject: [PATCH 002/119] h, s, l --- src/components/Color.js | 15 +++- src/components/Sketch/SketchPicker.jsx | 101 +++++++++++++++++++++++++ src/components/common/Alpha.jsx | 14 +++- src/components/common/Hue.jsx | 12 +++ src/components/common/Saturation.jsx | 12 ++- 5 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 src/components/Sketch/SketchPicker.jsx diff --git a/src/components/Color.js b/src/components/Color.js index dad6fbc6..5a6e056e 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -7,6 +7,19 @@ var SketchPicker = require('./Sketch/SketchPicker'); class ColorPicker extends ReactCSS.Component { + constructor() { + super(); + + this.state = { + h: 272, + s: 99, + l: 54, + a: 50, + rgb: [144, 19, 254], + hex: '9013FE', + }; + } + classes() { return { 'default': { @@ -17,7 +30,7 @@ class ColorPicker extends ReactCSS.Component { render() { return ( - + ); } diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx new file mode 100644 index 00000000..22b40d11 --- /dev/null +++ b/src/components/Sketch/SketchPicker.jsx @@ -0,0 +1,101 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +var Saturation = require('../common/Saturation'); +var Hue = require('../common/Hue'); +var Alpha = require('../common/Alpha'); + +class ColorPicker extends ReactCSS.Component { + + classes() { + return { + 'default': { + picker: { + width: '200px', + height: '400px', + padding: '10px', + background: '#fff', + borderRadius: '4px', + boxShadow: '0 0 0 1px rgba(0,0,0,.15), 0 8px 16px rgba(0,0,0,.15)', + }, + saturation: { + width: '100%', + paddingBottom: '75%', + position: 'relative', + }, + Saturation: { + radius: '3px', + shadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', + }, + controls: { + display: 'flex', + }, + sliders: { + padding: '4px 0', + flex: '1', + }, + color: { + width: '24px', + height: '24px', + position: 'relative', + marginTop: '4px', + marginLeft: '4px', + borderRadius: '3px', + }, + activeColor: { + Absolute: '0 0 0 0', + borderRadius: '3px', + background: 'rgba(' + this.props.rgb.join(',') + ', ' + (this.props.a / 100) + ')', + boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', + }, + hue: { + position: 'relative', + height: '10px', + }, + Hue: { + radius: '3px', + shadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', + }, + + alpha: { + position: 'relative', + height: '10px', + marginTop: '4px', + }, + Alpha: { + radius: '3px', + shadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', + }, + }, + }; + } + + render() { + return ( +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
Sketch Picker
+
+ ); + } + +} + +module.exports = ColorPicker; diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index bd12eb9c..8501b508 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -16,10 +16,21 @@ class Alpha extends ReactCSS.Component { }, gradient: { Absolute: '0 0 0 0', - background: 'linear-gradient(to right, rgba(133, 255, 0, 0) 0%, rgba(133, 255, 0, 1) 100%)', + background: 'linear-gradient(to right, rgba(' + this.props.rgb.join(',') + ', 0) 0%, rgba(' + this.props.rgb.join(',') + ', 1) 100%)', boxShadow: this.props.shadow, borderRadius: this.props.radius, }, + slider: { + width: '4px', + borderRadius: '1px', + height: '8px', + boxShadow: '0 0 2px rgba(0, 0, 0, .6)', + background: '#fff', + zIndex: '2', + position: 'absolute', + left: this.props.value + '%', + top: '1px', + }, }, }; } @@ -28,6 +39,7 @@ class Alpha extends ReactCSS.Component { return (
+
); } diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index 8e2c88a9..a59f1f8e 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -15,6 +15,17 @@ class Hue extends ReactCSS.Component { borderRadius: this.props.radius, boxShadow: this.props.shadow, }, + slider: { + width: '4px', + borderRadius: '1px', + height: '8px', + boxShadow: '0 0 2px rgba(0, 0, 0, .6)', + background: '#fff', + zIndex: '2', + position: 'absolute', + left: (this.props.value * 100) / 360 + '%', + top: '1px', + }, }, }; } @@ -22,6 +33,7 @@ class Hue extends ReactCSS.Component { render() { return (
+
); } diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index 9894cb8e..ab4cf0ae 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -10,7 +10,7 @@ class Saturation extends ReactCSS.Component { 'default': { color: { Absolute: '0 0 0 0', - background: 'rgb(133, 255, 0)', + background: 'hsl(' + this.props.h + ',100%, 50%)', overflow: 'hidden', borderRadius: this.props.radius, }, @@ -23,6 +23,15 @@ class Saturation extends ReactCSS.Component { background: 'linear-gradient(to top, #000, rgba(0,0,0,0))', boxShadow: this.props.shadow, }, + circle: { + position: 'absolute', + top: '5px', + right: '12px', + width: '4px', + height: '4px', + boxShadow: '0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0,0,0,.3), 0 0 1px 2px rgba(0,0,0,.4)', + borderRadius: '50%', + }, }, }; } @@ -32,6 +41,7 @@ class Saturation extends ReactCSS.Component {
+
); From 2f79330ab3f62a304d8a7c8468201692703bec19 Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 00:24:47 -0400 Subject: [PATCH 003/119] Color Picker Working! --- .gitignore | 27 ++++++++++++++++++++++ .jscsrc | 5 ++++ package.json | 25 ++++++++++++++++++++ src/components/Color.js | 12 ++++++---- src/components/Sketch/SketchPicker.jsx | 18 +++++++++++---- src/components/common/Alpha.jsx | 24 +++++++++++++++---- src/components/common/Hue.jsx | 23 ++++++++++++++++-- src/components/common/Saturation.jsx | 32 ++++++++++++++++++++++---- 8 files changed, 148 insertions(+), 18 deletions(-) create mode 100644 .gitignore create mode 100644 .jscsrc create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..123ae94d --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 00000000..d6218cd0 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,5 @@ +{ + "preset": "airbnb", + "disallowQuotedKeysInObjects": null, + "validateQuoteMarks": null +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..c525bf41 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "react-color", + "version": "1.0.0", + "description": "", + "main": "src/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/casesandberg/react-color.git" + }, + "author": "", + "license": "MIT", + "bugs": { + "url": "https://github.com/casesandberg/react-color/issues" + }, + "homepage": "https://github.com/casesandberg/react-color#readme", + "dependencies": { + "install": "^0.1.8", + "npm": "^2.13.4", + "react": "^0.13.3", + "tinycolor2": "^1.1.2" + } +} diff --git a/src/components/Color.js b/src/components/Color.js index 5a6e056e..cdc4dfa4 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -14,10 +14,10 @@ class ColorPicker extends ReactCSS.Component { h: 272, s: 99, l: 54, - a: 50, - rgb: [144, 19, 254], - hex: '9013FE', + a: 89, }; + + this.handleChange = this.handleChange.bind(this); } classes() { @@ -28,9 +28,13 @@ class ColorPicker extends ReactCSS.Component { }; } + handleChange(data) { + this.setState(data); + } + render() { return ( - + ); } diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx index 22b40d11..37016e50 100644 --- a/src/components/Sketch/SketchPicker.jsx +++ b/src/components/Sketch/SketchPicker.jsx @@ -9,6 +9,12 @@ var Alpha = require('../common/Alpha'); class ColorPicker extends ReactCSS.Component { + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + classes() { return { 'default': { @@ -47,7 +53,7 @@ class ColorPicker extends ReactCSS.Component { activeColor: { Absolute: '0 0 0 0', borderRadius: '3px', - background: 'rgba(' + this.props.rgb.join(',') + ', ' + (this.props.a / 100) + ')', + background: 'hsla(' + this.props.h + ', ' + this.props.s + '%, ' + this.props.l + '%, ' + (this.props.a / 100) + ')', boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', }, hue: { @@ -72,19 +78,23 @@ class ColorPicker extends ReactCSS.Component { }; } + handleChange(data) { + this.props.onChange(data); + } + render() { return (
- +
- +
- +
diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index 8501b508..1a015777 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -5,6 +5,12 @@ var ReactCSS = require('reactcss'); class Alpha extends ReactCSS.Component { + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + classes() { return { 'default': { @@ -16,7 +22,7 @@ class Alpha extends ReactCSS.Component { }, gradient: { Absolute: '0 0 0 0', - background: 'linear-gradient(to right, rgba(' + this.props.rgb.join(',') + ', 0) 0%, rgba(' + this.props.rgb.join(',') + ', 1) 100%)', + background: 'linear-gradient(to right, hsla(' + this.props.h + ', ' + this.props.s + '%, ' + this.props.l + '%, 0) 0%, hsla(' + this.props.h + ', ' + this.props.s + '%, ' + this.props.l + '%, 1) 100%)', boxShadow: this.props.shadow, borderRadius: this.props.radius, }, @@ -28,18 +34,28 @@ class Alpha extends ReactCSS.Component { background: '#fff', zIndex: '2', position: 'absolute', - left: this.props.value + '%', + left: this.props.a + '%', top: '1px', }, }, }; } + handleChange(e) { + var container = React.findDOMNode(this.refs.container); + var containerWidth = container.clientWidth; + var left = e.pageX - container.getBoundingClientRect().left; + if (left > 0 && left < containerWidth) { + var percent = left * 100 / containerWidth; + this.props.onChange({ a: percent }); + } + } + render() { return ( -
+
-
+
); } diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index a59f1f8e..2549f808 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -5,6 +5,12 @@ var ReactCSS = require('reactcss'); class Hue extends ReactCSS.Component { + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + classes() { return { 'default': { @@ -25,15 +31,28 @@ class Hue extends ReactCSS.Component { position: 'absolute', left: (this.props.value * 100) / 360 + '%', top: '1px', + + // WebkitUserDrag: 'none' }, }, }; } + handleChange(e) { + var container = React.findDOMNode(this.refs.container); + var containerWidth = container.clientWidth; + var left = e.pageX - container.getBoundingClientRect().left; + if (left > 0 && left < containerWidth) { + var percent = left * 100 / containerWidth; + var h = (360 * percent / 100); + this.props.onChange({ h: h }); + } + } + render() { return ( -
-
+
+
); } diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index ab4cf0ae..0a21a5f1 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -2,9 +2,16 @@ var React = require('react'); var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); class Saturation extends ReactCSS.Component { + constructor() { + super(); + + this.handleDrag = this.handleDrag.bind(this); + } + classes() { return { 'default': { @@ -25,23 +32,40 @@ class Saturation extends ReactCSS.Component { }, circle: { position: 'absolute', - top: '5px', - right: '12px', + top: -(tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }).toHsv().v * 100) + 100 + '%', + left: tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }).toHsv().s * 100 + '%', + width: '4px', height: '4px', boxShadow: '0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0,0,0,.3), 0 0 1px 2px rgba(0,0,0,.4)', borderRadius: '50%', + cursor: 'hand', + transform: 'translate(-2px, -2px)', }, }, }; } + handleDrag(e) { + var container = React.findDOMNode(this.refs.container); + var containerWidth = container.clientWidth; + var containerHeight = container.clientHeight; + var left = e.pageX - container.getBoundingClientRect().left; + var top = e.pageY - container.getBoundingClientRect().top; + if (left > 0 && top > 0 && left < containerWidth && top < containerHeight) { + var saturation = left * 100 / containerWidth; + var bright = -(top * 100 / containerHeight) + 100; + var computed = tinycolor({ h: this.props.h, s: saturation, v: bright }).toHsl(); + this.props.onChange({ l: computed.l * 100, s: computed.s * 100 }); + } + } + render() { return ( -
+
-
+
); From ea8a18d75c425428a75788dcd666c42d1825ba4a Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 00:26:05 -0400 Subject: [PATCH 004/119] Saturation Click --- src/components/common/Saturation.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index 0a21a5f1..87cdc4a8 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -9,7 +9,7 @@ class Saturation extends ReactCSS.Component { constructor() { super(); - this.handleDrag = this.handleDrag.bind(this); + this.handleChange = this.handleChange.bind(this); } classes() { @@ -46,7 +46,7 @@ class Saturation extends ReactCSS.Component { }; } - handleDrag(e) { + handleChange(e) { var container = React.findDOMNode(this.refs.container); var containerWidth = container.clientWidth; var containerHeight = container.clientHeight; @@ -62,10 +62,10 @@ class Saturation extends ReactCSS.Component { render() { return ( -
+
-
+
); From a571151b5159265aa382502d04b85651a64b11ae Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 00:49:40 -0400 Subject: [PATCH 005/119] Basic `EditableInput` --- src/components/Sketch/SketchFields.jsx | 68 +++++++++++++++++++++++++ src/components/Sketch/SketchPicker.jsx | 10 ++-- src/components/common/EditableInput.jsx | 32 ++++++++++++ 3 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 src/components/Sketch/SketchFields.jsx create mode 100644 src/components/common/EditableInput.jsx diff --git a/src/components/Sketch/SketchFields.jsx b/src/components/Sketch/SketchFields.jsx new file mode 100644 index 00000000..57248236 --- /dev/null +++ b/src/components/Sketch/SketchFields.jsx @@ -0,0 +1,68 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); + +var EditableInput = require('../common/EditableInput'); + +class ShetchFields extends ReactCSS.Component { + + classes() { + return { + 'default': { + fields: { + display: 'flex', + paddingTop: '4px', + }, + single: { + flex: '1', + paddingLeft: '6px', + }, + double: { + flex: '2', + }, + label: { + display: 'block', + textAlign: 'center', + fontSize: '12px', + color: '#222', + paddingTop: '4px', + paddingBottom: '4px', + }, + }, + }; + } + + render() { + var color = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l, a: this.props.a }); + + return ( +
+
+ + Hex +
+
+ + R +
+
+ + G +
+
+ + B +
+
+ + A +
+
+ ); + } + +} + +module.exports = ShetchFields; diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx index 37016e50..dc4c1e53 100644 --- a/src/components/Sketch/SketchPicker.jsx +++ b/src/components/Sketch/SketchPicker.jsx @@ -6,6 +6,7 @@ var ReactCSS = require('reactcss'); var Saturation = require('../common/Saturation'); var Hue = require('../common/Hue'); var Alpha = require('../common/Alpha'); +var SketchFields = require('./SketchFields'); class ColorPicker extends ReactCSS.Component { @@ -20,8 +21,7 @@ class ColorPicker extends ReactCSS.Component { 'default': { picker: { width: '200px', - height: '400px', - padding: '10px', + padding: '10px 10px 0', background: '#fff', borderRadius: '4px', boxShadow: '0 0 0 1px rgba(0,0,0,.15), 0 8px 16px rgba(0,0,0,.15)', @@ -98,10 +98,12 @@ class ColorPicker extends ReactCSS.Component {
-
+
-
Sketch Picker
+
+ +
); } diff --git a/src/components/common/EditableInput.jsx b/src/components/common/EditableInput.jsx new file mode 100644 index 00000000..d0fc7660 --- /dev/null +++ b/src/components/common/EditableInput.jsx @@ -0,0 +1,32 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class EditableInput extends ReactCSS.Component { + + classes() { + return { + 'default': { + input: { + width: '80%', + padding: '3px 10%', + border: 'none', + boxShadow: 'inset 0 0 0 1px #ddd', + fontSize: '12px', + }, + }, + }; + } + + render() { + return ( +
+ +
+ ); + } + +} + +module.exports = EditableInput; From d3e4513490992dfd3bece720650ce8010d23fba2 Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 01:06:55 -0400 Subject: [PATCH 006/119] Remove the `#` the textbook --- src/components/Sketch/SketchFields.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Sketch/SketchFields.jsx b/src/components/Sketch/SketchFields.jsx index 57248236..15fc8764 100644 --- a/src/components/Sketch/SketchFields.jsx +++ b/src/components/Sketch/SketchFields.jsx @@ -40,7 +40,7 @@ class ShetchFields extends ReactCSS.Component { return (
- + Hex
From f152d4fd987b2b899e9a09831a62ee0e5f1071aa Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 17:21:36 -0400 Subject: [PATCH 007/119] Working Inputs! --- src/components/Sketch/SketchFields.jsx | 46 ++++++++++++++++++++----- src/components/Sketch/SketchPicker.jsx | 2 +- src/components/common/EditableInput.jsx | 46 +++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 11 deletions(-) diff --git a/src/components/Sketch/SketchFields.jsx b/src/components/Sketch/SketchFields.jsx index 15fc8764..ca6ad3ff 100644 --- a/src/components/Sketch/SketchFields.jsx +++ b/src/components/Sketch/SketchFields.jsx @@ -8,6 +8,12 @@ var EditableInput = require('../common/EditableInput'); class ShetchFields extends ReactCSS.Component { + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + classes() { return { 'default': { @@ -25,38 +31,62 @@ class ShetchFields extends ReactCSS.Component { label: { display: 'block', textAlign: 'center', - fontSize: '12px', + fontSize: '11px', color: '#222', - paddingTop: '4px', + paddingTop: '3px', paddingBottom: '4px', }, }, }; } + handleChange(data) { + if (data.hex) { + var color = tinycolor(data.hex); + if (color.isValid()) { + var hsl = color.toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } + } else if (data.r || data.g || data.b) { + var oldColor = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l}).toRgb(); + for (var key in data) { + oldColor[key] = Number(data[key]); + } + + this.props.onChange(tinycolor(oldColor).toHsl()); + } else if (data.a) { + if (data.a < 0) { + data.a = 0; + } else if (data.a > 100) { + data.a = 100; + } + this.props.onChange(data); + } + } + render() { - var color = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l, a: this.props.a }); + var color = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }); return (
- + Hex
- + R
- + G
- + B
- + A
diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx index dc4c1e53..18cb322e 100644 --- a/src/components/Sketch/SketchPicker.jsx +++ b/src/components/Sketch/SketchPicker.jsx @@ -102,7 +102,7 @@ class ColorPicker extends ReactCSS.Component {
- +
); diff --git a/src/components/common/EditableInput.jsx b/src/components/common/EditableInput.jsx index d0fc7660..12f73242 100644 --- a/src/components/common/EditableInput.jsx +++ b/src/components/common/EditableInput.jsx @@ -5,6 +5,17 @@ var ReactCSS = require('reactcss'); class EditableInput extends ReactCSS.Component { + constructor(props) { + super(); + + this.state = { + value: String(props.value).toUpperCase(), + }, + + this.handleChange = this.handleChange.bind(this); + this.handleBlur = this.handleBlur.bind(this); + } + classes() { return { 'default': { @@ -13,16 +24,47 @@ class EditableInput extends ReactCSS.Component { padding: '3px 10%', border: 'none', boxShadow: 'inset 0 0 0 1px #ddd', - fontSize: '12px', + fontSize: '11px', }, }, }; } + componentWillReceiveProps(nextProps) { + var input = React.findDOMNode(this.refs.input); + if (nextProps.value !== this.state.value) { + + if (input === document.activeElement) { + this.setState({ blurValue: String(nextProps.value).toUpperCase() }); + } else { + this.setState({ value: String(nextProps.value).toUpperCase() }); + } + } + } + + handleBlur() { + if (this.state.blurValue) { + this.setState({ value: this.state.blurValue, blurValue: null }); + } + } + + handleChange(e) { + + if (this.props.label !== null) { + var obj = {}; + obj[this.props.label] = e.target.value; + this.props.onChange(obj); + } else { + this.props.onChange(e.target.value); + } + + this.setState({ value: e.target.value }); + } + render() { return (
- +
); } From 6a9757b2eb7b5ff9e7e32fa3a3114eeeeb086acb Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 17:56:00 -0400 Subject: [PATCH 008/119] Move styles out of Input, janky slidable labels --- src/components/Sketch/SketchFields.jsx | 41 ++++++++++++---------- src/components/common/EditableInput.jsx | 45 ++++++++++++++++++++----- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/components/Sketch/SketchFields.jsx b/src/components/Sketch/SketchFields.jsx index ca6ad3ff..cc2013ca 100644 --- a/src/components/Sketch/SketchFields.jsx +++ b/src/components/Sketch/SketchFields.jsx @@ -28,13 +28,25 @@ class ShetchFields extends ReactCSS.Component { double: { flex: '2', }, - label: { - display: 'block', - textAlign: 'center', - fontSize: '11px', - color: '#222', - paddingTop: '3px', - paddingBottom: '4px', + Input: { + style: { + input: { + width: '80%', + padding: '3px 10%', + border: 'none', + boxShadow: 'inset 0 0 0 1px #ddd', + fontSize: '11px', + }, + label: { + display: 'block', + textAlign: 'center', + fontSize: '11px', + color: '#222', + paddingTop: '3px', + paddingBottom: '4px', + textTransform: 'capitalize', + }, + }, }, }, }; @@ -70,24 +82,19 @@ class ShetchFields extends ReactCSS.Component { return (
- - Hex +
- - R +
- - G +
- - B +
- - A +
); diff --git a/src/components/common/EditableInput.jsx b/src/components/common/EditableInput.jsx index 12f73242..3bc2c18d 100644 --- a/src/components/common/EditableInput.jsx +++ b/src/components/common/EditableInput.jsx @@ -13,23 +13,30 @@ class EditableInput extends ReactCSS.Component { }, this.handleChange = this.handleChange.bind(this); + this.handleDrag = this.handleDrag.bind(this); this.handleBlur = this.handleBlur.bind(this); } classes() { return { - 'default': { - input: { - width: '80%', - padding: '3px 10%', - border: 'none', - boxShadow: 'inset 0 0 0 1px #ddd', - fontSize: '11px', + 'user-override': { + input: this.props.style.input, + label: this.props.style.label, + }, + 'dragLabel-true': { + label: { + cursor: 'ew-resize', }, }, }; } + styles() { + return this.css({ + 'user-override': true, + }); + } + componentWillReceiveProps(nextProps) { var input = React.findDOMNode(this.refs.input); if (nextProps.value !== this.state.value) { @@ -61,10 +68,32 @@ class EditableInput extends ReactCSS.Component { this.setState({ value: e.target.value }); } + handleDrag(e) { + if (this.props.dragLabel) { + var container = React.findDOMNode(this.refs.container); + var containerWidth = container.clientWidth; + var left = e.pageX - container.getBoundingClientRect().left; + + var newValue = Math.round(this.props.value + left); + + if (newValue >= 0 && newValue <= this.props.dragMax) { + var obj = {}; + obj[this.props.label] = Math.round(newValue / 1); + this.props.onChange(obj); + } + } + } + render() { + var label; + if (this.props.label) { + label = { this.props.label }; + } + return ( -
+
+ { label }
); } From ff5e7c72d635b2f972fb2ac9be0c0111e338e845 Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 18:20:40 -0400 Subject: [PATCH 009/119] Fixed alpha display --- src/components/Sketch/SketchFields.jsx | 3 ++- src/components/Sketch/SketchPicker.jsx | 4 +++- src/components/common/Alpha.jsx | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/Sketch/SketchFields.jsx b/src/components/Sketch/SketchFields.jsx index cc2013ca..efe585c5 100644 --- a/src/components/Sketch/SketchFields.jsx +++ b/src/components/Sketch/SketchFields.jsx @@ -65,7 +65,8 @@ class ShetchFields extends ReactCSS.Component { oldColor[key] = Number(data[key]); } - this.props.onChange(tinycolor(oldColor).toHsl()); + var hsl = tinycolor(oldColor).toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); } else if (data.a) { if (data.a < 0) { data.a = 0; diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx index 18cb322e..4b859cde 100644 --- a/src/components/Sketch/SketchPicker.jsx +++ b/src/components/Sketch/SketchPicker.jsx @@ -2,6 +2,7 @@ var React = require('react'); var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); var Saturation = require('../common/Saturation'); var Hue = require('../common/Hue'); @@ -17,6 +18,7 @@ class ColorPicker extends ReactCSS.Component { } classes() { + var rgb = tinycolor(this.props).toRgb(); return { 'default': { picker: { @@ -53,7 +55,7 @@ class ColorPicker extends ReactCSS.Component { activeColor: { Absolute: '0 0 0 0', borderRadius: '3px', - background: 'hsla(' + this.props.h + ', ' + this.props.s + '%, ' + this.props.l + '%, ' + (this.props.a / 100) + ')', + background: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + (this.props.a / 100) + ')', boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', }, hue: { diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index 1a015777..1fac61b6 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -2,6 +2,7 @@ var React = require('react'); var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); class Alpha extends ReactCSS.Component { @@ -12,6 +13,7 @@ class Alpha extends ReactCSS.Component { } classes() { + var rgb = tinycolor(this.props).toRgb(); return { 'default': { alpha: { @@ -22,7 +24,7 @@ class Alpha extends ReactCSS.Component { }, gradient: { Absolute: '0 0 0 0', - background: 'linear-gradient(to right, hsla(' + this.props.h + ', ' + this.props.s + '%, ' + this.props.l + '%, 0) 0%, hsla(' + this.props.h + ', ' + this.props.s + '%, ' + this.props.l + '%, 1) 100%)', + background: 'linear-gradient(to right, rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', 0) 0%, rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', 1) 100%)', boxShadow: this.props.shadow, borderRadius: this.props.radius, }, From 432efd6bf700997b83f609d1d96d14559f383ea2 Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 18:27:14 -0400 Subject: [PATCH 010/119] Fix some throttling issues --- src/components/common/Alpha.jsx | 6 ++++-- src/components/common/Hue.jsx | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index 1fac61b6..e985fbae 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -48,8 +48,10 @@ class Alpha extends ReactCSS.Component { var containerWidth = container.clientWidth; var left = e.pageX - container.getBoundingClientRect().left; if (left > 0 && left < containerWidth) { - var percent = left * 100 / containerWidth; - this.props.onChange({ a: percent }); + var percent = Math.round(left * 100 / containerWidth); + if (this.props.a !== percent) { + this.props.onChange({ a: percent }); + } } } diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index 2549f808..80eb38ee 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -45,7 +45,9 @@ class Hue extends ReactCSS.Component { if (left > 0 && left < containerWidth) { var percent = left * 100 / containerWidth; var h = (360 * percent / 100); - this.props.onChange({ h: h }); + if (this.props.value !== h) { + this.props.onChange({ h: h }); + } } } From e99b9f45f3412c22ed184da9d488effbf957e9a1 Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 18:53:48 -0400 Subject: [PATCH 011/119] Mousedown + speed improvements for Saturation --- src/components/common/Alpha.jsx | 2 +- src/components/common/Hue.jsx | 2 +- src/components/common/Saturation.jsx | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index e985fbae..6932dd34 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -57,7 +57,7 @@ class Alpha extends ReactCSS.Component { render() { return ( -
+
diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index 80eb38ee..529363b2 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -53,7 +53,7 @@ class Hue extends ReactCSS.Component { render() { return ( -
+
); diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index 87cdc4a8..eee19e11 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -13,6 +13,8 @@ class Saturation extends ReactCSS.Component { } classes() { + var hsv = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }).toHsv(); + return { 'default': { color: { @@ -32,8 +34,8 @@ class Saturation extends ReactCSS.Component { }, circle: { position: 'absolute', - top: -(tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }).toHsv().v * 100) + 100 + '%', - left: tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }).toHsv().s * 100 + '%', + top: -(hsv.v * 100) + 100 + '%', + left: hsv.s * 100 + '%', width: '4px', height: '4px', @@ -56,13 +58,14 @@ class Saturation extends ReactCSS.Component { var saturation = left * 100 / containerWidth; var bright = -(top * 100 / containerHeight) + 100; var computed = tinycolor({ h: this.props.h, s: saturation, v: bright }).toHsl(); + if (this.props.h !== computed.h || this.props.s !== computed.s) this.props.onChange({ l: computed.l * 100, s: computed.s * 100 }); } } render() { return ( -
+
From a17bde42bc19f2c787dc4fc6680946850a07fe88 Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 19:26:55 -0400 Subject: [PATCH 012/119] `Checkerboard` --- src/components/Color.js | 2 +- src/components/Sketch/SketchPicker.jsx | 3 + src/components/common/Alpha.jsx | 6 +- src/components/common/Checkboard.jsx | 83 ++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/components/common/Checkboard.jsx diff --git a/src/components/Color.js b/src/components/Color.js index cdc4dfa4..57b5d7be 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -14,7 +14,7 @@ class ColorPicker extends ReactCSS.Component { h: 272, s: 99, l: 54, - a: 89, + a: 32, }; this.handleChange = this.handleChange.bind(this); diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx index 4b859cde..1fa01346 100644 --- a/src/components/Sketch/SketchPicker.jsx +++ b/src/components/Sketch/SketchPicker.jsx @@ -8,6 +8,7 @@ var Saturation = require('../common/Saturation'); var Hue = require('../common/Hue'); var Alpha = require('../common/Alpha'); var SketchFields = require('./SketchFields'); +var Checkboard = require('../common/Checkboard'); class ColorPicker extends ReactCSS.Component { @@ -57,6 +58,7 @@ class ColorPicker extends ReactCSS.Component { borderRadius: '3px', background: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + (this.props.a / 100) + ')', boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', + zIndex: '2', }, hue: { position: 'relative', @@ -101,6 +103,7 @@ class ColorPicker extends ReactCSS.Component {
+
diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index 6932dd34..d4a0fa1d 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -4,6 +4,8 @@ var React = require('react'); var ReactCSS = require('reactcss'); var tinycolor = require('tinycolor2'); +var Checkboard = require('../common/Checkboard'); + class Alpha extends ReactCSS.Component { constructor() { @@ -18,7 +20,6 @@ class Alpha extends ReactCSS.Component { 'default': { alpha: { Absolute: '0 0 0 0', - background: '#eee', overflow: 'hidden', borderRadius: this.props.radius, }, @@ -57,7 +58,8 @@ class Alpha extends ReactCSS.Component { render() { return ( -
+
+
diff --git a/src/components/common/Checkboard.jsx b/src/components/common/Checkboard.jsx new file mode 100644 index 00000000..3e029e55 --- /dev/null +++ b/src/components/common/Checkboard.jsx @@ -0,0 +1,83 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class Checkboard extends ReactCSS.Component { + + constructor() { + super(); + + this.state = { + children: [], + }; + } + + classes() { + return { + 'default': { + grid: { + Absolute: '0 0 0 0', + }, + inside: { + position: 'absolute', + left: '50%', + top: '50%', + transform: 'translate(-50%, -50%)', + }, + white: { + width: this.props.size + 'px', + height: this.props.size + 'px', + background: '#fff', + float: 'left', + }, + grey: { + width: this.props.size + 'px', + height: this.props.size + 'px', + background: '#e6e6e6', + float: 'left', + }, + }, + }; + } + + componentDidMount() { + var grid = React.findDOMNode(this.refs.grid); + var inside = React.findDOMNode(this.refs.inside); + var rows = Math.ceil(grid.clientHeight / this.props.size); + var columns = Math.ceil(grid.clientWidth / this.props.size); + + if (columns % 2 == 0) { + columns++; + } + + inside.style.width = columns * this.props.size + 'px'; + + var children = []; + for (var i = 0; i < rows * columns; i++) { + if (i % 2 == 0) { + children.push(
); + } else { + children.push(
); + } + } + this.setState({ children: children }); + } + + render() { + return ( +
+
+ { this.state.children } +
+
+ ); + } + +} + +Checkboard.defaultProps = { + size: 8, +}; + +module.exports = Checkboard; From 9d9b8679aa8bb09e4e86a86a99c3e03bf93645f6 Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 19:44:43 -0400 Subject: [PATCH 013/119] Hue and Alpha slider location tweaks --- src/components/Sketch/SketchPicker.jsx | 6 +++--- src/components/common/Alpha.jsx | 15 ++++++++++++--- src/components/common/Hue.jsx | 14 ++++++++++---- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx index 1fa01346..8bd41017 100644 --- a/src/components/Sketch/SketchPicker.jsx +++ b/src/components/Sketch/SketchPicker.jsx @@ -55,7 +55,7 @@ class ColorPicker extends ReactCSS.Component { }, activeColor: { Absolute: '0 0 0 0', - borderRadius: '3px', + borderRadius: '2px', background: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + (this.props.a / 100) + ')', boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', zIndex: '2', @@ -65,7 +65,7 @@ class ColorPicker extends ReactCSS.Component { height: '10px', }, Hue: { - radius: '3px', + radius: '2px', shadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', }, @@ -75,7 +75,7 @@ class ColorPicker extends ReactCSS.Component { marginTop: '4px', }, Alpha: { - radius: '3px', + radius: '2px', shadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', }, }, diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index d4a0fa1d..c7582949 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -29,6 +29,12 @@ class Alpha extends ReactCSS.Component { boxShadow: this.props.shadow, borderRadius: this.props.radius, }, + container: { + position: 'relative', + zIndex: '2', + height: '100%', + margin: '0 3px', + }, slider: { width: '4px', borderRadius: '1px', @@ -39,6 +45,7 @@ class Alpha extends ReactCSS.Component { position: 'absolute', left: this.props.a + '%', top: '1px', + transform: 'translateX(-2px)', }, }, }; @@ -48,7 +55,7 @@ class Alpha extends ReactCSS.Component { var container = React.findDOMNode(this.refs.container); var containerWidth = container.clientWidth; var left = e.pageX - container.getBoundingClientRect().left; - if (left > 0 && left < containerWidth) { + if (left >= 0 && left <= containerWidth) { var percent = Math.round(left * 100 / containerWidth); if (this.props.a !== percent) { this.props.onChange({ a: percent }); @@ -58,10 +65,12 @@ class Alpha extends ReactCSS.Component { render() { return ( -
+
-
+
+
+
); } diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index 529363b2..caf1e35d 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -21,6 +21,11 @@ class Hue extends ReactCSS.Component { borderRadius: this.props.radius, boxShadow: this.props.shadow, }, + container: { + margin: '0 2px', + position: 'relative', + height: '100%', + }, slider: { width: '4px', borderRadius: '1px', @@ -31,8 +36,7 @@ class Hue extends ReactCSS.Component { position: 'absolute', left: (this.props.value * 100) / 360 + '%', top: '1px', - - // WebkitUserDrag: 'none' + transform: 'translateX(-2px)', }, }, }; @@ -53,8 +57,10 @@ class Hue extends ReactCSS.Component { render() { return ( -
-
+
+
+
+
); } From 2da9d2317aecca9d0585902de8c99ed53801d657 Mon Sep 17 00:00:00 2001 From: case Date: Mon, 10 Aug 2015 21:16:55 -0400 Subject: [PATCH 014/119] Other form of movement to speed it up? --- src/components/common/Saturation.jsx | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index eee19e11..1c11addd 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -36,7 +36,6 @@ class Saturation extends ReactCSS.Component { position: 'absolute', top: -(hsv.v * 100) + 100 + '%', left: hsv.s * 100 + '%', - width: '4px', height: '4px', boxShadow: '0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0,0,0,.3), 0 0 1px 2px rgba(0,0,0,.4)', @@ -48,18 +47,37 @@ class Saturation extends ReactCSS.Component { }; } + // componentDidMount() { + // var circle = React.findDOMNode(this.refs.circle); + // var hsv = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }).toHsv(); + // circle.style.top = -(hsv.v * 100) + 100 + '%'; + // circle.style.left = hsv.s * 100 + '%'; + // } + // + // componentWillReceiveProps(nextProps) { + // var circle = React.findDOMNode(this.refs.circle); + // var hsv = tinycolor({ h: nextProps.h, s: nextProps.s, l: nextProps.l }).toHsv(); + // circle.style.top = -(hsv.v * 100) + 100 + '%'; + // circle.style.left = hsv.s * 100 + '%'; + // } + handleChange(e) { var container = React.findDOMNode(this.refs.container); + + // var circle = React.findDOMNode(this.refs.circle); var containerWidth = container.clientWidth; var containerHeight = container.clientHeight; var left = e.pageX - container.getBoundingClientRect().left; var top = e.pageY - container.getBoundingClientRect().top; if (left > 0 && top > 0 && left < containerWidth && top < containerHeight) { + // circle.style.top = top + 'px'; + // circle.style.left = left + 'px'; var saturation = left * 100 / containerWidth; var bright = -(top * 100 / containerHeight) + 100; var computed = tinycolor({ h: this.props.h, s: saturation, v: bright }).toHsl(); - if (this.props.h !== computed.h || this.props.s !== computed.s) - this.props.onChange({ l: computed.l * 100, s: computed.s * 100 }); + if (this.props.h !== computed.h || this.props.s !== computed.s) { + this.props.onChange({ l: computed.l * 100, s: computed.s * 100 }); + } } } @@ -68,7 +86,7 @@ class Saturation extends ReactCSS.Component {
-
+
); From cf7c39ff12c2e89a27a6ba7bbc8b8f9529e4e87c Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 00:53:13 -0400 Subject: [PATCH 015/119] Stubbed in Photoshop! --- src/components/Color.js | 4 +- src/components/Sketch/SketchFields.jsx | 4 +- src/components/Sketch/SketchPicker.jsx | 4 + src/components/Sketch/SketchPresetColors.jsx | 75 +++++++++ src/components/common/EditableInput.jsx | 5 +- src/components/common/Hue.jsx | 33 +++- src/components/photoshop/PhotoshopFields.jsx | 94 +++++++++++ src/components/photoshop/PhotoshopPicker.jsx | 159 +++++++++++++++++++ src/specs/Color.spec.js | 27 +--- 9 files changed, 371 insertions(+), 34 deletions(-) create mode 100644 src/components/Sketch/SketchPresetColors.jsx create mode 100644 src/components/photoshop/PhotoshopFields.jsx create mode 100644 src/components/photoshop/PhotoshopPicker.jsx diff --git a/src/components/Color.js b/src/components/Color.js index 57b5d7be..6fd28100 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -3,7 +3,7 @@ var React = require('react'); var ReactCSS = require('reactcss'); -var SketchPicker = require('./Sketch/SketchPicker'); +var PhotoshopPicker = require('./photoshop/PhotoshopPicker'); class ColorPicker extends ReactCSS.Component { @@ -34,7 +34,7 @@ class ColorPicker extends ReactCSS.Component { render() { return ( - + ); } diff --git a/src/components/Sketch/SketchFields.jsx b/src/components/Sketch/SketchFields.jsx index efe585c5..06afcf1b 100644 --- a/src/components/Sketch/SketchFields.jsx +++ b/src/components/Sketch/SketchFields.jsx @@ -32,9 +32,9 @@ class ShetchFields extends ReactCSS.Component { style: { input: { width: '80%', - padding: '3px 10%', + padding: '4px 10% 3px', border: 'none', - boxShadow: 'inset 0 0 0 1px #ddd', + boxShadow: 'inset 0 0 0 1px #ccc', fontSize: '11px', }, label: { diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx index 8bd41017..546a01df 100644 --- a/src/components/Sketch/SketchPicker.jsx +++ b/src/components/Sketch/SketchPicker.jsx @@ -8,6 +8,7 @@ var Saturation = require('../common/Saturation'); var Hue = require('../common/Hue'); var Alpha = require('../common/Alpha'); var SketchFields = require('./SketchFields'); +var SketchPresetColors = require('./SketchPresetColors'); var Checkboard = require('../common/Checkboard'); class ColorPicker extends ReactCSS.Component { @@ -109,6 +110,9 @@ class ColorPicker extends ReactCSS.Component {
+
+ +
); } diff --git a/src/components/Sketch/SketchPresetColors.jsx b/src/components/Sketch/SketchPresetColors.jsx new file mode 100644 index 00000000..e3ab294b --- /dev/null +++ b/src/components/Sketch/SketchPresetColors.jsx @@ -0,0 +1,75 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); + +class SketchPresetColors extends ReactCSS.Component { + + constructor() { + super(); + + this.handleClick = this.handleClick.bind(this); + } + + classes() { + return { + 'default': { + colors: { + marginRight: '-10px', + marginLeft: '-10px', + paddingLeft: '10px', + paddingTop: '10px', + borderTop: '1px solid #eee', + }, + li: { + borderRadius: '3px', + overflow: 'hidden', + position: 'relative', + display: 'inline-block', + margin: '0 10px 10px 0', + verticalAlign: 'top', + }, + square: { + borderRadius: '3px', + width: '16px', + height: '16px', + boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15)', + }, + }, + 'no-presets': { + colors: { + display: 'none', + }, + }, + }; + } + + styles() { + return this.css({ + 'no-presets': !this.props.colors || !this.props.colors.length, + }); + } + + handleClick(hex) { + var hsl = tinycolor(hex).toHsl(); + this.props.onClick({ h: hsl.h, s: hsl.s, l: hsl.l, a: 100 }); + } + + render() { + var colors = []; + if (this.props.colors) { + for (var color of this.props.colors) { + colors.push(
); + } + } + + return ( +
+ { colors } +
+ ); + } +} + +module.exports = SketchPresetColors; diff --git a/src/components/common/EditableInput.jsx b/src/components/common/EditableInput.jsx index 3bc2c18d..05fe56cc 100644 --- a/src/components/common/EditableInput.jsx +++ b/src/components/common/EditableInput.jsx @@ -20,8 +20,9 @@ class EditableInput extends ReactCSS.Component { classes() { return { 'user-override': { - input: this.props.style.input, - label: this.props.style.label, + wrap: this.props.style && this.props.style.wrap, + input: this.props.style && this.props.style.input, + label: this.props.style && this.props.style.label, }, 'dragLabel-true': { label: { diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index caf1e35d..c98eae3c 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -39,18 +39,41 @@ class Hue extends ReactCSS.Component { transform: 'translateX(-2px)', }, }, + 'direction-vertical': { + hue: { + background: 'linear-gradient(to top, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)', + }, + slider: { + left: '0', + top: -((this.props.value * 100) / 360) + 100 + '%', + }, + }, }; } handleChange(e) { var container = React.findDOMNode(this.refs.container); var containerWidth = container.clientWidth; + var containerHeight = container.clientHeight; var left = e.pageX - container.getBoundingClientRect().left; - if (left > 0 && left < containerWidth) { - var percent = left * 100 / containerWidth; - var h = (360 * percent / 100); - if (this.props.value !== h) { - this.props.onChange({ h: h }); + var top = e.pageY - container.getBoundingClientRect().top; + + if (this.props.direction === 'vertical') { + console.log('change'); + if (top > 0 && top < containerHeight) { + var percent = -(top * 100 / containerHeight) + 100; + var h = (360 * percent / 100); + if (this.props.value !== h) { + this.props.onChange({ h: h }); + } + } + } else { + if (left > 0 && left < containerWidth) { + var percent = left * 100 / containerWidth; + var h = (360 * percent / 100); + if (this.props.value !== h) { + this.props.onChange({ h: h }); + } } } } diff --git a/src/components/photoshop/PhotoshopFields.jsx b/src/components/photoshop/PhotoshopFields.jsx new file mode 100644 index 00000000..7dce0466 --- /dev/null +++ b/src/components/photoshop/PhotoshopFields.jsx @@ -0,0 +1,94 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +var EditableInput = require('../common/EditableInput'); + +class PhotoshopPicker extends ReactCSS.Component { + + classes() { + return { + 'default': { + fields: { + paddingTop: '5px', + paddingBottom: '9px', + width: '80px', + }, + divider: { + height: '5px', + }, + Input: { + style: { + wrap: { + display: 'flex', + }, + input: { + flex: '1', + order: '2', + height: '18px', + border: '1px solid #888888', + boxShadow: 'inset 0 1px 1px rgba(0,0,0,.1), 0 1px 0 0 #ECECEC', + marginBottom: '5px', + fontSize: '13px', + paddingLeft: '3px', + marginRight: '10px', + }, + label: { + width: '34px', + order: '1', + textTransform: 'uppercase', + fontSize: '13px', + height: '18px', + lineHeight: '22px', + }, + }, + }, + Hex: { + style: { + wrap: { + display: 'flex', + }, + input: { + flex: '1', + order: '2', + height: '18px', + border: '1px solid #888888', + boxShadow: 'inset 0 1px 1px rgba(0,0,0,.1), 0 1px 0 0 #ECECEC', + marginBottom: '6px', + fontSize: '13px', + paddingLeft: '3px', + }, + label: { + width: '14px', + order: '1', + textTransform: 'uppercase', + fontSize: '13px', + height: '18px', + lineHeight: '22px', + }, + }, + }, + }, + }; + } + + render() { + return ( +
+ + + +
+ + + +
+ +
+ ); + } + +} + +module.exports = PhotoshopPicker; diff --git a/src/components/photoshop/PhotoshopPicker.jsx b/src/components/photoshop/PhotoshopPicker.jsx new file mode 100644 index 00000000..64145179 --- /dev/null +++ b/src/components/photoshop/PhotoshopPicker.jsx @@ -0,0 +1,159 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); + +var Saturation = require('../common/Saturation'); +var Hue = require('../common/Hue'); +var PhotoshopFields = require('./PhotoshopFields'); + +class PhotoshopPicker extends ReactCSS.Component { + + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + + classes() { + var rgb = tinycolor(this.props).toRgb(); + return { + 'default': { + picker: { + background: '#DCDCDC', + borderRadius: '4px', + boxShadow: '0 0 0 1px rgba(0,0,0,.25), 0 8px 16px rgba(0,0,0,.15)', + }, + head: { + backgroundImage: 'linear-gradient(-180deg, #F0F0F0 0%, #D4D4D4 100%)', + borderBottom: '1px solid #B1B1B1', + boxShadow: 'inset 0 1px 0 0 rgba(255,255,255,.2), inset 0 -1px 0 0 rgba(0,0,0,.02)', + height: '23px', + lineHeight: '24px', + borderRadius: '4px 4px 0 0', + fontSize: '13px', + color: '#4D4D4D', + textAlign: 'center', + }, + body: { + padding: '15px 15px 0', + display: 'flex', + }, + saturation: { + width: '256px', + height: '256px', + position: 'relative', + border: '2px solid #B3B3B3', + borderBottom: '2px solid #F0F0F0', + }, + hue: { + position: 'relative', + height: '256px', + width: '19px', + marginLeft: '10px', + border: '2px solid #B3B3B3', + borderBottom: '2px solid #F0F0F0', + }, + Hue: { + direction: 'vertical', + }, + controls: { + width: '180px', + marginLeft: '10px', + }, + + top: { + display: 'flex', + }, + previews: { + width: '60px', + }, + swatches: { + border: '1px solid #B3B3B3', + borderBottom: '1px solid #F0F0F0', + marginBottom: '2px', + marginTop: '1px', + }, + new: { + height: '34px', + background: 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')', + boxShadow: 'inset 1px 0 0 #000, inset -1px 0 0 #000, inset 0 1px 0 #000', + }, + current: { + height: '34px', + background: 'green', + boxShadow: 'inset 1px 0 0 #000, inset -1px 0 0 #000, inset 0 -1px 0 #000', + }, + label: { + fontSize: '14px', + color: '#000', + textAlign: 'center', + }, + actions: { + flex: '1', + marginLeft: '20px', + }, + button: { + backgroundImage: 'linear-gradient(-180deg, #FFFFFF 0%, #E6E6E6 100%)', + border: '1px solid #878787', + borderRadius: '2px', + height: '20px', + boxShadow: '0 1px 0 0 #EAEAEA', + fontSize: '14px', + color: '#000', + lineHeight: '20px', + textAlign: 'center', + marginBottom: '10px', + }, + acceptButton: { + Extend: 'button', + boxShadow: '0 0 0 1px #878787', + }, + }, + }; + } + + handleChange(data) { + this.props.onChange(data); + } + + render() { + return ( +
+
+ Color Picker +
+
+
+ +
+
+ +
+
+
+
+
new
+
+
+
+
+
current
+
+
+
OK
+
Cancel
+ + +
+
+
+
+
+ ); + } + +} + +module.exports = PhotoshopPicker; diff --git a/src/specs/Color.spec.js b/src/specs/Color.spec.js index e3a54e55..8ba4f008 100644 --- a/src/specs/Color.spec.js +++ b/src/specs/Color.spec.js @@ -2,26 +2,6 @@ var Harness = require('react-harness'); var Color = require('./../components/Color'); -Color.propTypes = { - tabs: Harness.PropTypes.array.examples([ - [{ - label: 'cool', - callback: function() { - console.log('cool'); - }, - }, { - label: 'tabs', - callback: function() { - console.log('tabs'); - }, - },], - ['cool', 'tabs'], ['foo', 'bar', 'longer'], ['foo', 'bar', 'way longer', 'even', 'still'], - ]), - align: Harness.PropTypes.oneOf(['none', 'justify', 'left', 'center']), - color: Harness.PropTypes.string.examples(['#fff', '#FFEB3B']), - background: Harness.PropTypes.string.examples(['transparent', '#4A90E2']), -}; - module.exports = { label: 'Color', desc: 'Lorem Ipsum', @@ -30,9 +10,10 @@ module.exports = { instances: { 'default': { - tabs: ['foo', 'bar'], - color: '#333', - background: '#eee', + presetColors: ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#BD10E0', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF'], + }, + 'No Presets': { + presetColors: false, }, }, }; From 868b9b45f7e2a97bb9ec504b4404d642650d38f4 Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 01:11:49 -0400 Subject: [PATCH 016/119] symbols --- src/components/photoshop/PhotoshopFields.jsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/components/photoshop/PhotoshopFields.jsx b/src/components/photoshop/PhotoshopFields.jsx index 7dce0466..afa62e86 100644 --- a/src/components/photoshop/PhotoshopFields.jsx +++ b/src/components/photoshop/PhotoshopFields.jsx @@ -14,6 +14,7 @@ class PhotoshopPicker extends ReactCSS.Component { paddingTop: '5px', paddingBottom: '9px', width: '80px', + position: 'relative', }, divider: { height: '5px', @@ -69,6 +70,17 @@ class PhotoshopPicker extends ReactCSS.Component { }, }, }, + fieldSymbols: { + position: 'absolute', + top: '5px', + right: '-7px', + fontSize: '13px', + }, + symbol: { + height: '20px', + lineHeight: '22px', + paddingBottom: '7px', + }, }, }; } @@ -85,6 +97,11 @@ class PhotoshopPicker extends ReactCSS.Component {
+
+
°
+
%
+
%
+
); } From b77b1e49b837be9dbac22cd924c987ef1d8b5bcc Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 01:43:20 -0400 Subject: [PATCH 017/119] Pass down real data + overflow fix --- src/components/Sketch/SketchPicker.jsx | 3 +++ src/components/common/Alpha.jsx | 1 - src/components/common/Hue.jsx | 1 - src/components/common/Saturation.jsx | 1 - src/components/photoshop/PhotoshopFields.jsx | 18 +++++++++------ src/components/photoshop/PhotoshopPicker.jsx | 3 ++- .../photoshop/PhotoshopSaturationPicker.jsx | 23 +++++++++++++++++++ 7 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 src/components/photoshop/PhotoshopSaturationPicker.jsx diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/Sketch/SketchPicker.jsx index 546a01df..fdce807c 100644 --- a/src/components/Sketch/SketchPicker.jsx +++ b/src/components/Sketch/SketchPicker.jsx @@ -34,6 +34,7 @@ class ColorPicker extends ReactCSS.Component { width: '100%', paddingBottom: '75%', position: 'relative', + overflow: 'hidden', }, Saturation: { radius: '3px', @@ -64,6 +65,7 @@ class ColorPicker extends ReactCSS.Component { hue: { position: 'relative', height: '10px', + overflow: 'hidden', }, Hue: { radius: '2px', @@ -74,6 +76,7 @@ class ColorPicker extends ReactCSS.Component { position: 'relative', height: '10px', marginTop: '4px', + overflow: 'hidden', }, Alpha: { radius: '2px', diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index c7582949..ea373e00 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -20,7 +20,6 @@ class Alpha extends ReactCSS.Component { 'default': { alpha: { Absolute: '0 0 0 0', - overflow: 'hidden', borderRadius: this.props.radius, }, gradient: { diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index c98eae3c..091e438d 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -17,7 +17,6 @@ class Hue extends ReactCSS.Component { hue: { Absolute: '0 0 0 0', background: 'linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)', - overflow: 'hidden', borderRadius: this.props.radius, boxShadow: this.props.shadow, }, diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index 1c11addd..7e1514bd 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -20,7 +20,6 @@ class Saturation extends ReactCSS.Component { color: { Absolute: '0 0 0 0', background: 'hsl(' + this.props.h + ',100%, 50%)', - overflow: 'hidden', borderRadius: this.props.radius, }, white: { diff --git a/src/components/photoshop/PhotoshopFields.jsx b/src/components/photoshop/PhotoshopFields.jsx index afa62e86..42de8368 100644 --- a/src/components/photoshop/PhotoshopFields.jsx +++ b/src/components/photoshop/PhotoshopFields.jsx @@ -2,6 +2,7 @@ var React = require('react'); var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); var EditableInput = require('../common/EditableInput'); @@ -86,17 +87,20 @@ class PhotoshopPicker extends ReactCSS.Component { } render() { + var hsv = tinycolor(this.props).toHsv(); + var rgb = tinycolor(this.props).toRgb(); + var hex = tinycolor(this.props).toHex(); return (
- - - + + +
- - - + + +
- +
°
%
diff --git a/src/components/photoshop/PhotoshopPicker.jsx b/src/components/photoshop/PhotoshopPicker.jsx index 64145179..63ef328f 100644 --- a/src/components/photoshop/PhotoshopPicker.jsx +++ b/src/components/photoshop/PhotoshopPicker.jsx @@ -46,6 +46,7 @@ class PhotoshopPicker extends ReactCSS.Component { position: 'relative', border: '2px solid #B3B3B3', borderBottom: '2px solid #F0F0F0', + overflow: 'hidden', }, hue: { position: 'relative', @@ -145,7 +146,7 @@ class PhotoshopPicker extends ReactCSS.Component {
OK
Cancel
- +
diff --git a/src/components/photoshop/PhotoshopSaturationPicker.jsx b/src/components/photoshop/PhotoshopSaturationPicker.jsx new file mode 100644 index 00000000..c8f454ce --- /dev/null +++ b/src/components/photoshop/PhotoshopSaturationPicker.jsx @@ -0,0 +1,23 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class PhotoshopPicker extends ReactCSS.Component { + + classes() { + return { + 'default': { + }, + }; + } + + render() { + return ( +
+ ); + } + +} + +module.exports = PhotoshopPicker; From 06a9138f37e94584f81481afda8d6ecbbd178bc0 Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 01:53:08 -0400 Subject: [PATCH 018/119] color checks --- src/components/Sketch/SketchFields.jsx | 1 + src/components/photoshop/PhotoshopFields.jsx | 52 +++++++++++++++++--- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/components/Sketch/SketchFields.jsx b/src/components/Sketch/SketchFields.jsx index 06afcf1b..c3ac4c6f 100644 --- a/src/components/Sketch/SketchFields.jsx +++ b/src/components/Sketch/SketchFields.jsx @@ -73,6 +73,7 @@ class ShetchFields extends ReactCSS.Component { } else if (data.a > 100) { data.a = 100; } + this.props.onChange(data); } } diff --git a/src/components/photoshop/PhotoshopFields.jsx b/src/components/photoshop/PhotoshopFields.jsx index 42de8368..e4b375ab 100644 --- a/src/components/photoshop/PhotoshopFields.jsx +++ b/src/components/photoshop/PhotoshopFields.jsx @@ -8,6 +8,12 @@ var EditableInput = require('../common/EditableInput'); class PhotoshopPicker extends ReactCSS.Component { + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + classes() { return { 'default': { @@ -86,21 +92,53 @@ class PhotoshopPicker extends ReactCSS.Component { }; } + handleChange(data) { + if (data['#']) { + var color = tinycolor(data['#']); + if (color.isValid()) { + var hsl = color.toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } + } else if (data.r || data.g || data.b) { + var oldColor = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l}).toRgb(); + for (var key in data) { + oldColor[key] = Number(data[key]); + } + + var color = tinycolor(oldColor); + if (color.isValid()) { + var hsl = color.toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } + } else if (data.h || data.s || data.v) { + var oldColor = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l}).toHsv(); + for (var key in data) { + oldColor[key] = Number(data[key]); + } + + var color = tinycolor(oldColor); + if (color.isValid()) { + var hsl = color.toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } + } + } + render() { var hsv = tinycolor(this.props).toHsv(); var rgb = tinycolor(this.props).toRgb(); var hex = tinycolor(this.props).toHex(); return (
- - - + + +
- - - + + +
- +
°
%
From 17cbe9cc802ecb5442e06285086b8c358213e165 Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 02:17:57 -0400 Subject: [PATCH 019/119] Custom Saturation Pointer --- src/components/common/Saturation.jsx | 15 ++++++- src/components/photoshop/PhotoshopPicker.jsx | 3 +- .../photoshop/PhotoshopPointerCircle.jsx | 41 +++++++++++++++++++ .../photoshop/PhotoshopSaturationPicker.jsx | 23 ----------- 4 files changed, 56 insertions(+), 26 deletions(-) create mode 100644 src/components/photoshop/PhotoshopPointerCircle.jsx delete mode 100644 src/components/photoshop/PhotoshopSaturationPicker.jsx diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index 7e1514bd..7e896cc0 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -31,10 +31,12 @@ class Saturation extends ReactCSS.Component { background: 'linear-gradient(to top, #000, rgba(0,0,0,0))', boxShadow: this.props.shadow, }, - circle: { + pointer: { position: 'absolute', top: -(hsv.v * 100) + 100 + '%', left: hsv.s * 100 + '%', + }, + circle: { width: '4px', height: '4px', boxShadow: '0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0,0,0,.3), 0 0 1px 2px rgba(0,0,0,.4)', @@ -81,11 +83,20 @@ class Saturation extends ReactCSS.Component { } render() { + + var pointer =
; + + if (this.props.pointer) { + pointer = ; + } + return (
-
+
+ { pointer } +
); diff --git a/src/components/photoshop/PhotoshopPicker.jsx b/src/components/photoshop/PhotoshopPicker.jsx index 63ef328f..e95f43c6 100644 --- a/src/components/photoshop/PhotoshopPicker.jsx +++ b/src/components/photoshop/PhotoshopPicker.jsx @@ -7,6 +7,7 @@ var tinycolor = require('tinycolor2'); var Saturation = require('../common/Saturation'); var Hue = require('../common/Hue'); var PhotoshopFields = require('./PhotoshopFields'); +var PhotoshopPointerCircle = require('./PhotoshopPointerCircle'); class PhotoshopPicker extends ReactCSS.Component { @@ -127,7 +128,7 @@ class PhotoshopPicker extends ReactCSS.Component {
- +
diff --git a/src/components/photoshop/PhotoshopPointerCircle.jsx b/src/components/photoshop/PhotoshopPointerCircle.jsx new file mode 100644 index 00000000..1aaba1d1 --- /dev/null +++ b/src/components/photoshop/PhotoshopPointerCircle.jsx @@ -0,0 +1,41 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class PhotoshopPointerCircle extends ReactCSS.Component { + + classes() { + return { + 'default': { + picker: { + width: '12px', + height: '12px', + borderRadius: '6px', + boxShadow: 'inset 0 0 0 1px #fff', + transform: 'translate(-6px, -6px)', + }, + }, + 'black-outline': { + picker: { + boxShadow: 'inset 0 0 0 1px #000', + }, + }, + }; + } + + styles() { + return this.css({ + 'black-outline': this.props.l > 50, + }); + } + + render() { + return ( +
+ ); + } + +} + +module.exports = PhotoshopPointerCircle; diff --git a/src/components/photoshop/PhotoshopSaturationPicker.jsx b/src/components/photoshop/PhotoshopSaturationPicker.jsx deleted file mode 100644 index c8f454ce..00000000 --- a/src/components/photoshop/PhotoshopSaturationPicker.jsx +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -var React = require('react'); -var ReactCSS = require('reactcss'); - -class PhotoshopPicker extends ReactCSS.Component { - - classes() { - return { - 'default': { - }, - }; - } - - render() { - return ( -
- ); - } - -} - -module.exports = PhotoshopPicker; From 50756e25beced2b1d09cb25c133c46ec27e98a2a Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 02:42:41 -0400 Subject: [PATCH 020/119] Custom Hue Pointer --- src/components/Color.js | 4 +- src/components/common/Hue.jsx | 22 +++++-- .../{PhotoshopPicker.jsx => Photoshop.jsx} | 3 +- src/components/photoshop/PhotoshopPointer.jsx | 66 +++++++++++++++++++ 4 files changed, 86 insertions(+), 9 deletions(-) rename src/components/photoshop/{PhotoshopPicker.jsx => Photoshop.jsx} (96%) create mode 100644 src/components/photoshop/PhotoshopPointer.jsx diff --git a/src/components/Color.js b/src/components/Color.js index 6fd28100..6ef52d1e 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -3,7 +3,7 @@ var React = require('react'); var ReactCSS = require('reactcss'); -var PhotoshopPicker = require('./photoshop/PhotoshopPicker'); +var Photoshop = require('./photoshop/Photoshop'); class ColorPicker extends ReactCSS.Component { @@ -34,7 +34,7 @@ class ColorPicker extends ReactCSS.Component { render() { return ( - + ); } diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index 091e438d..a42b5719 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -25,16 +25,18 @@ class Hue extends ReactCSS.Component { position: 'relative', height: '100%', }, + pointer: { + zIndex: '2', + position: 'absolute', + left: (this.props.value * 100) / 360 + '%', + top: '1px', + }, slider: { width: '4px', borderRadius: '1px', height: '8px', boxShadow: '0 0 2px rgba(0, 0, 0, .6)', background: '#fff', - zIndex: '2', - position: 'absolute', - left: (this.props.value * 100) / 360 + '%', - top: '1px', transform: 'translateX(-2px)', }, }, @@ -42,7 +44,7 @@ class Hue extends ReactCSS.Component { hue: { background: 'linear-gradient(to top, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)', }, - slider: { + pointer: { left: '0', top: -((this.props.value * 100) / 360) + 100 + '%', }, @@ -78,10 +80,18 @@ class Hue extends ReactCSS.Component { } render() { + var pointer =
; + + if (this.props.pointer) { + pointer = ; + } + return (
-
+
+ { pointer } +
); diff --git a/src/components/photoshop/PhotoshopPicker.jsx b/src/components/photoshop/Photoshop.jsx similarity index 96% rename from src/components/photoshop/PhotoshopPicker.jsx rename to src/components/photoshop/Photoshop.jsx index e95f43c6..9e490035 100644 --- a/src/components/photoshop/PhotoshopPicker.jsx +++ b/src/components/photoshop/Photoshop.jsx @@ -8,6 +8,7 @@ var Saturation = require('../common/Saturation'); var Hue = require('../common/Hue'); var PhotoshopFields = require('./PhotoshopFields'); var PhotoshopPointerCircle = require('./PhotoshopPointerCircle'); +var PhotoshopPointer = require('./PhotoshopPointer'); class PhotoshopPicker extends ReactCSS.Component { @@ -131,7 +132,7 @@ class PhotoshopPicker extends ReactCSS.Component {
- +
diff --git a/src/components/photoshop/PhotoshopPointer.jsx b/src/components/photoshop/PhotoshopPointer.jsx new file mode 100644 index 00000000..e9fb3398 --- /dev/null +++ b/src/components/photoshop/PhotoshopPointer.jsx @@ -0,0 +1,66 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class PhotoshopPointerCircle extends ReactCSS.Component { + + classes() { + return { + 'default': { + triangle: { + width: 0, + height: 0, + borderStyle: 'solid', + borderWidth: '4px 0 4px 6px', + borderColor: 'transparent transparent transparent #fff', + position: 'absolute', + top: '1px', + left: '1px', + }, + triangleBorder: { + width: 0, + height: 0, + borderStyle: 'solid', + borderWidth: '5px 0 5px 8px', + borderColor: 'transparent transparent transparent #555', + }, + + left: { + Extend: 'triangleBorder', + transform: 'translate(-13px, -4px)', + }, + leftInside: { + Extend: 'triangle', + transform: 'translate(-8px, -5px)', + }, + + right: { + Extend: 'triangleBorder', + transform: 'translate(20px, -14px) rotate(180deg)', + }, + rightInside: { + Extend: 'triangle', + transform: 'translate(-8px, -5px)', + }, + }, + }; + } + + render() { + return ( +
+
+
+
+ +
+
+
+
+ ); + } + +} + +module.exports = PhotoshopPointerCircle; From a324fcdce863d7f69a1a4839d6dd527602b1417e Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 02:53:31 -0400 Subject: [PATCH 021/119] Rename SketchPicker --- src/components/Color.js | 3 ++- src/components/{Sketch/SketchPicker.jsx => sketch/Sketch.jsx} | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename src/components/{Sketch/SketchPicker.jsx => sketch/Sketch.jsx} (100%) diff --git a/src/components/Color.js b/src/components/Color.js index 6ef52d1e..c7ede7e4 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -4,6 +4,7 @@ var React = require('react'); var ReactCSS = require('reactcss'); var Photoshop = require('./photoshop/Photoshop'); +var Sketch = require('./sketch/Sketch'); class ColorPicker extends ReactCSS.Component { @@ -34,7 +35,7 @@ class ColorPicker extends ReactCSS.Component { render() { return ( - + ); } diff --git a/src/components/Sketch/SketchPicker.jsx b/src/components/sketch/Sketch.jsx similarity index 100% rename from src/components/Sketch/SketchPicker.jsx rename to src/components/sketch/Sketch.jsx From 44031c6dd5910b541b0c7fd997340f22133a677f Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 02:55:05 -0400 Subject: [PATCH 022/119] Change css so warning does now throw --- src/components/common/EditableInput.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/common/EditableInput.jsx b/src/components/common/EditableInput.jsx index 05fe56cc..a32170c9 100644 --- a/src/components/common/EditableInput.jsx +++ b/src/components/common/EditableInput.jsx @@ -20,9 +20,9 @@ class EditableInput extends ReactCSS.Component { classes() { return { 'user-override': { - wrap: this.props.style && this.props.style.wrap, - input: this.props.style && this.props.style.input, - label: this.props.style && this.props.style.label, + wrap: this.props.style && this.props.style.wrap ? this.props.style.wrap : {}, + input: this.props.style && this.props.style.input ? this.props.style.input : {}, + label: this.props.style && this.props.style.label ? this.props.style.label : {}, }, 'dragLabel-true': { label: { From 35e0eea5c42edfbbdadf02e5944362df7f66e967 Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 04:49:30 -0400 Subject: [PATCH 023/119] Chrome! --- src/components/Color.js | 3 +- src/components/chrome/Chrome.jsx | 123 +++++++++++++++++++++++++ src/components/chrome/ChromeFields.jsx | 77 ++++++++++++++++ 3 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 src/components/chrome/Chrome.jsx create mode 100644 src/components/chrome/ChromeFields.jsx diff --git a/src/components/Color.js b/src/components/Color.js index c7ede7e4..2f4f49a7 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -5,6 +5,7 @@ var ReactCSS = require('reactcss'); var Photoshop = require('./photoshop/Photoshop'); var Sketch = require('./sketch/Sketch'); +var Chrome = require('./chrome/Chrome'); class ColorPicker extends ReactCSS.Component { @@ -35,7 +36,7 @@ class ColorPicker extends ReactCSS.Component { render() { return ( - + ); } diff --git a/src/components/chrome/Chrome.jsx b/src/components/chrome/Chrome.jsx new file mode 100644 index 00000000..5b74980d --- /dev/null +++ b/src/components/chrome/Chrome.jsx @@ -0,0 +1,123 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); + +var Saturation = require('../common/Saturation'); +var Hue = require('../common/Hue'); +var Alpha = require('../common/Alpha'); +var Checkboard = require('../common/Checkboard'); +var ChromeFields = require('./ChromeFields'); + +class Chrome extends ReactCSS.Component { + + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + + classes() { + var rgb = tinycolor(this.props).toRgb(); + + return { + 'default': { + picker: { + background: '#fff', + borderRadius: '2px', + boxShadow: '0 0 2px rgba(0,0,0,.3), 0 4px 8px rgba(0,0,0,.3)', + width: '225px', + fontFamily: 'Menlo', + }, + saturation: { + width: '100%', + paddingBottom: '55%', + position: 'relative', + borderRadius: '2px 2px 0 0', + overflow: 'hidden', + }, + + body: { + padding: '16px 16px 12px', + }, + controls: { + display: 'flex', + }, + color: { + width: '32px', + }, + swatch: { + marginTop: '6px', + width: '16px', + height: '16px', + borderRadius: '8px', + position: 'relative', + overflow: 'hidden', + }, + active: { + Absolute: '0 0 0 0', + zIndex: 2, + borderRadius: '8px', + boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.1)', + background: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + (this.props.a / 100) + ')', + }, + toggles: { + flex: '1', + }, + hue: { + height: '10px', + position: 'relative', + marginBottom: '8px', + }, + Hue: { + radius: '2px', + }, + alpha: { + height: '10px', + position: 'relative', + overflow: 'hidden', + }, + Alpha: { + radius: '2px', + }, + }, + }; + } + + handleChange(data) { + this.props.onChange(data); + } + + render() { + return ( +
+
+ +
+
+
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
+
+ ); + } + +} + +module.exports = Chrome; diff --git a/src/components/chrome/ChromeFields.jsx b/src/components/chrome/ChromeFields.jsx new file mode 100644 index 00000000..14ed6f25 --- /dev/null +++ b/src/components/chrome/ChromeFields.jsx @@ -0,0 +1,77 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); + +var EditableInput = require('../common/EditableInput'); + +class ChromeFields extends ReactCSS.Component { + + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + + classes() { + return { + 'default': { + wrap: { + paddingTop: '16px', + display: 'flex', + }, + fields: { + flex: '1', + }, + toggle: { + width: '32px', + textAlign: 'right', + }, + Input: { + style: { + input: { + fontSize: '11px', + color: '#333', + width: '100%', + borderRadius: '2px', + border: 'none', + boxShadow: 'inset 0 0 0 1px #dadada', + height: '21px', + textAlign: 'center', + }, + label: { + textTransform: 'uppercase', + fontSize: '11px', + lineHeight: '11px', + color: '#969696', + textAlign: 'center', + display: 'block', + marginTop: '12px', + }, + }, + }, + }, + }; + } + + handleChange(data) { + this.props.onChange(data); + } + + render() { + return ( +
+
+ +
+
+ | +
+
+ ); + } + +} + +module.exports = ChromeFields; From 9606927f0a6167b4a9099dcc0675bcd096eeef08 Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 05:04:49 -0400 Subject: [PATCH 024/119] Expand Button --- src/components/chrome/ChromeFields.jsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/chrome/ChromeFields.jsx b/src/components/chrome/ChromeFields.jsx index 14ed6f25..e014bfdf 100644 --- a/src/components/chrome/ChromeFields.jsx +++ b/src/components/chrome/ChromeFields.jsx @@ -28,6 +28,11 @@ class ChromeFields extends ReactCSS.Component { width: '32px', textAlign: 'right', }, + icon: { + marginRight: '-4px', + marginTop: '12px', + cursor: 'pointer', + }, Input: { style: { input: { @@ -66,7 +71,11 @@ class ChromeFields extends ReactCSS.Component {
- | +
+ + + +
); From ee8294b2087d87f2f87f67e1f13a12ae47cb41d4 Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 05:57:11 -0400 Subject: [PATCH 025/119] Working Chrome Picker! --- src/components/chrome/Chrome.jsx | 2 +- src/components/chrome/ChromeFields.jsx | 139 +++++++++++++++++++++++-- 2 files changed, 134 insertions(+), 7 deletions(-) diff --git a/src/components/chrome/Chrome.jsx b/src/components/chrome/Chrome.jsx index 5b74980d..39c75133 100644 --- a/src/components/chrome/Chrome.jsx +++ b/src/components/chrome/Chrome.jsx @@ -112,7 +112,7 @@ class Chrome extends ReactCSS.Component {
- +
); diff --git a/src/components/chrome/ChromeFields.jsx b/src/components/chrome/ChromeFields.jsx index e014bfdf..090204c3 100644 --- a/src/components/chrome/ChromeFields.jsx +++ b/src/components/chrome/ChromeFields.jsx @@ -8,10 +8,18 @@ var EditableInput = require('../common/EditableInput'); class ChromeFields extends ReactCSS.Component { - constructor() { + constructor(props) { super(); + this.state = { + view: 'hex', + }; + this.handleChange = this.handleChange.bind(this); + this.toggleViews = this.toggleViews.bind(this); + this.handleChange = this.handleChange.bind(this); + this.hideHighlight = this.hideHighlight.bind(this); + this.showHighlight = this.showHighlight.bind(this); } classes() { @@ -23,15 +31,34 @@ class ChromeFields extends ReactCSS.Component { }, fields: { flex: '1', + display: 'flex', + marginLeft: '-6px', + }, + field: { + paddingLeft: '6px', + width: '100%', }, toggle: { width: '32px', textAlign: 'right', + position: 'relative', }, icon: { marginRight: '-4px', marginTop: '12px', cursor: 'pointer', + position: 'relative', + zIndex: '2', + }, + iconHighlight: { + position: 'absolute', + width: '24px', + height: '28px', + background: '#eee', + borderRadius: '4px', + top: '10px', + left: '12px', + display: 'none', }, Input: { style: { @@ -64,18 +91,118 @@ class ChromeFields extends ReactCSS.Component { this.props.onChange(data); } + componentDidMount() { + // if (this.props.a === 100 && this.state.view !== 'hex') { + // this.setState({ view: 'hex' }); + // } else if (this.state.view !== 'rgb' && this.state.view !== 'hsl') { + // this.setState({ view: 'rgb' }); + // } + } + + toggleViews() { + if (this.state.view === 'hex') { + this.setState({ view: 'rgb' }); + } else if (this.state.view === 'rgb') { + this.setState({ view: 'hsl' }); + } else if (this.state.view === 'hsl') { + this.setState({ view: 'hex' }); + } + } + + handleChange(data) { + if (data.hex) { + var color = tinycolor(data.hex); + if (color.isValid()) { + var hsl = color.toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } + } else if (data.r || data.g || data.b) { + var oldColor = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l}).toRgb(); + for (var key in data) { + oldColor[key] = Number(data[key]); + } + + var hsl = tinycolor(oldColor).toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } else if (data.a) { + if (data.a < 0) { + data.a = 0; + } else if (data.a > 1) { + data.a = 1; + } else { + data.a = Math.round(data.a * 100); + } + + this.props.onChange(data); + } else if (data.h || data.s || data.l) { + for (var key in data) { + data[key] = data[key].replace('%', ''); + } + + this.props.onChange(data); + } + } + + showHighlight() { + React.findDOMNode(this.refs.iconHighlight).style.display = 'block'; + } + + hideHighlight() { + React.findDOMNode(this.refs.iconHighlight).style.display = 'none'; + } + render() { + var color = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }); + + var fields; + if (this.state.view === 'hex') { + fields =
+
+ +
+
; + } else if (this.state.view === 'rgb') { + fields =
+
+ +
+
+ +
+
+ +
+
+ +
+
; + } else if (this.state.view === 'hsl') { + fields =
+
+ +
+
+ +
+
+ +
+
+ +
+
; + } + return (
-
- -
+ { fields }
-
- +
+
+
); From 0d26cb64047638f6592e45ab8344df4179bcf57c Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 20:39:23 -0400 Subject: [PATCH 026/119] Chrome Pointers + Hue Custom Pointer! --- src/components/chrome/Chrome.jsx | 14 +++++---- src/components/chrome/ChromeFields.jsx | 24 ++++++++------ src/components/chrome/ChromePointer.jsx | 31 +++++++++++++++++++ src/components/chrome/ChromePointerCircle.jsx | 30 ++++++++++++++++++ src/components/common/Alpha.jsx | 26 +++++++++++++--- src/components/common/Hue.jsx | 2 +- 6 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 src/components/chrome/ChromePointer.jsx create mode 100644 src/components/chrome/ChromePointerCircle.jsx diff --git a/src/components/chrome/Chrome.jsx b/src/components/chrome/Chrome.jsx index 39c75133..8afc4fd6 100644 --- a/src/components/chrome/Chrome.jsx +++ b/src/components/chrome/Chrome.jsx @@ -9,6 +9,8 @@ var Hue = require('../common/Hue'); var Alpha = require('../common/Alpha'); var Checkboard = require('../common/Checkboard'); var ChromeFields = require('./ChromeFields'); +var ChromePointer = require('./ChromePointer'); +var ChromePointerCircle = require('./ChromePointerCircle'); class Chrome extends ReactCSS.Component { @@ -35,9 +37,10 @@ class Chrome extends ReactCSS.Component { paddingBottom: '55%', position: 'relative', borderRadius: '2px 2px 0 0', - overflow: 'hidden', }, - + Saturation: { + radius: '2px 2px 0 0', + }, body: { padding: '16px 16px 12px', }, @@ -76,7 +79,6 @@ class Chrome extends ReactCSS.Component { alpha: { height: '10px', position: 'relative', - overflow: 'hidden', }, Alpha: { radius: '2px', @@ -93,7 +95,7 @@ class Chrome extends ReactCSS.Component { return (
- +
@@ -105,10 +107,10 @@ class Chrome extends ReactCSS.Component {
- +
- +
diff --git a/src/components/chrome/ChromeFields.jsx b/src/components/chrome/ChromeFields.jsx index 090204c3..c05093fb 100644 --- a/src/components/chrome/ChromeFields.jsx +++ b/src/components/chrome/ChromeFields.jsx @@ -92,11 +92,11 @@ class ChromeFields extends ReactCSS.Component { } componentDidMount() { - // if (this.props.a === 100 && this.state.view !== 'hex') { - // this.setState({ view: 'hex' }); - // } else if (this.state.view !== 'rgb' && this.state.view !== 'hsl') { - // this.setState({ view: 'rgb' }); - // } + if (this.props.a === 100 && this.state.view !== 'hex') { + this.setState({ view: 'hex' }); + } else if (this.state.view !== 'rgb' && this.state.view !== 'hsl') { + this.setState({ view: 'rgb' }); + } } toggleViews() { @@ -105,7 +105,11 @@ class ChromeFields extends ReactCSS.Component { } else if (this.state.view === 'rgb') { this.setState({ view: 'hsl' }); } else if (this.state.view === 'hsl') { - this.setState({ view: 'hex' }); + if (this.props.a === 100) { + this.setState({ view: 'hex' }); + } else { + this.setState({ view: 'rgb' }); + } } } @@ -179,16 +183,16 @@ class ChromeFields extends ReactCSS.Component { } else if (this.state.view === 'hsl') { fields =
- +
- +
- +
- +
; } diff --git a/src/components/chrome/ChromePointer.jsx b/src/components/chrome/ChromePointer.jsx new file mode 100644 index 00000000..a7206ede --- /dev/null +++ b/src/components/chrome/ChromePointer.jsx @@ -0,0 +1,31 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class ChromePointer extends ReactCSS.Component { + + classes() { + return { + 'default': { + picker: { + width: '12px', + height: '12px', + borderRadius: '6px', + transform: 'translate(-6px, -1px)', + backgroundColor: 'rgb(248, 248, 248)', + boxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.37)', + }, + }, + }; + } + + render() { + return ( +
+ ); + } + +} + +module.exports = ChromePointer; diff --git a/src/components/chrome/ChromePointerCircle.jsx b/src/components/chrome/ChromePointerCircle.jsx new file mode 100644 index 00000000..fda84519 --- /dev/null +++ b/src/components/chrome/ChromePointerCircle.jsx @@ -0,0 +1,30 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class ChromePointerCircle extends ReactCSS.Component { + + classes() { + return { + 'default': { + picker: { + width: '12px', + height: '12px', + borderRadius: '6px', + boxShadow: 'inset 0 0 0 1px #fff', + transform: 'translate(-6px, -6px)', + }, + }, + }; + } + + render() { + return ( +
+ ); + } + +} + +module.exports = ChromePointerCircle; diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index ea373e00..b1cb2956 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -22,6 +22,10 @@ class Alpha extends ReactCSS.Component { Absolute: '0 0 0 0', borderRadius: this.props.radius, }, + checkboard: { + Absolute: '0 0 0 0', + overflow: 'hidden', + }, gradient: { Absolute: '0 0 0 0', background: 'linear-gradient(to right, rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', 0) 0%, rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', 1) 100%)', @@ -34,15 +38,17 @@ class Alpha extends ReactCSS.Component { height: '100%', margin: '0 3px', }, + pointer: { + zIndex: '2', + position: 'absolute', + left: this.props.a + '%', + }, slider: { width: '4px', borderRadius: '1px', height: '8px', boxShadow: '0 0 2px rgba(0, 0, 0, .6)', background: '#fff', - zIndex: '2', - position: 'absolute', - left: this.props.a + '%', top: '1px', transform: 'translateX(-2px)', }, @@ -63,12 +69,22 @@ class Alpha extends ReactCSS.Component { } render() { + var pointer =
; + + if (this.props.pointer) { + pointer = ; + } + return (
- +
+ +
-
+
+ { pointer } +
); diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index a42b5719..3d4ebce3 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -29,9 +29,9 @@ class Hue extends ReactCSS.Component { zIndex: '2', position: 'absolute', left: (this.props.value * 100) / 360 + '%', - top: '1px', }, slider: { + top: '1px', width: '4px', borderRadius: '1px', height: '8px', From 5897f437891fe023a5d1c23fc9a247b7a635ae87 Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 21:28:22 -0400 Subject: [PATCH 027/119] Init Docs --- docs/components/home/Home.jsx | 18 ++++++++++++ docs/components/home/HomeDocumentation.jsx | 32 +++++++++++++++++++++ docs/components/home/HomeFeature.jsx | 30 +++++++++++++++++++ docs/documentation/01-about.md | 10 +++++++ docs/documentation/index.js | 4 +++ docs/images/bg.jpg | Bin 0 -> 124062 bytes docs/index.js | 11 +++++++ package.json | 3 ++ src/specs/Color.spec.js | 19 ------------ src/specs/index.js | 4 --- 10 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 docs/components/home/Home.jsx create mode 100644 docs/components/home/HomeDocumentation.jsx create mode 100644 docs/components/home/HomeFeature.jsx create mode 100644 docs/documentation/01-about.md create mode 100644 docs/documentation/index.js create mode 100644 docs/images/bg.jpg create mode 100644 docs/index.js delete mode 100644 src/specs/Color.spec.js delete mode 100644 src/specs/index.js diff --git a/docs/components/home/Home.jsx b/docs/components/home/Home.jsx new file mode 100644 index 00000000..32b85f41 --- /dev/null +++ b/docs/components/home/Home.jsx @@ -0,0 +1,18 @@ +'use strict'; + +var React = require('react'); + +var HomeFeature = require('./HomeFeature'); +var HomeDocumentation = require('./HomeDocumentation'); + +module.exports = class Home extends React.Component { + + render() { + return ( +
+ + +
+ ); + } +}; diff --git a/docs/components/home/HomeDocumentation.jsx b/docs/components/home/HomeDocumentation.jsx new file mode 100644 index 00000000..8e5652ec --- /dev/null +++ b/docs/components/home/HomeDocumentation.jsx @@ -0,0 +1,32 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +var { Container, Grid } = require('react-basic-layout'); +var { Raised } = require('react-material-design'); +var Docs = require('react-docs'); + +var documentation = require('../../documentation'); + +class HomeDocumentation extends ReactCSS.Component { + + classes() { + return { + 'default': { + }, + }; + } + + render() { + return ( +
+ + Body + +
+ ); + } +} + +module.exports = HomeDocumentation; diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx new file mode 100644 index 00000000..04e5e4cc --- /dev/null +++ b/docs/components/home/HomeFeature.jsx @@ -0,0 +1,30 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var ColorPicker = require('react-color'); + +var { Container, Grid } = require('../layout'); +var { Raised } = require('react-material-design'); + +class HomeFeature extends ReactCSS.Component { + + classes() { + return { + 'default': { + }, + }; + } + + render() { + return ( +
+ + feature + +
+ ); + } +} + +module.exports = HomeFeature; diff --git a/docs/documentation/01-about.md b/docs/documentation/01-about.md new file mode 100644 index 00000000..c66d47a0 --- /dev/null +++ b/docs/documentation/01-about.md @@ -0,0 +1,10 @@ +--- +id: about +title: About +--- + +**7 Different Pickers** - Sketch, Photoshop, Chrome and more + +**Popup or Block** - They can either be popped up or always visible + +**Make Your Own** - Use the building block components to make your own diff --git a/docs/documentation/index.js b/docs/documentation/index.js new file mode 100644 index 00000000..64ffa69c --- /dev/null +++ b/docs/documentation/index.js @@ -0,0 +1,4 @@ + +module.exports = { + '01-about': require('./01-about.md'), +}; diff --git a/docs/images/bg.jpg b/docs/images/bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8f49f6ee5937597b3042388dac00bf9bb1ef225c GIT binary patch literal 124062 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

4v+cSf?n z0E)5(EiokNqhXXWS8~FM7u%VGaSm95b9)&mld)#^Jc~|%YwJpd5u&~p_9;UMC0}aW zWOKy9ufTA{{7CEAb*j+22be_@olc>)*9R-_>Q2N;ncf^&a#PjxYXPB&Y>ohjxN8hD znMym%=%}|$58k}gaSUYde!cv2MJz+Pq@=6bROh0rbSq=ZL=h92ygA%xxu0Ajkf-Rn zZ1tpdF2JBe+0%G_BO$Z(89i+I!qb)6q2qQ5%ez2dM#Q>39lP0?z9X`<4Nsuz7FNVsxN%R+Dw6+u z!WDo+pIsvndjm!Q1g?}fa{)7tMJ5{>av7tTf9agxcdlwWS^lqBvgv1!PloTto7n8; zGrU|@+)xL(7gcT9u5tUfg{Mx+|C9jUqW^-M>!B-Vk!2Kf66?vcjh=re(eZYx&Qj$n zTGko*$%L>&73rmzeIeNdAZ5k9f+GOdN`UKo+aH&M00;J=o!I1FQ6L&)WqU4Y-tuDr z*_1uMr($cd?Ax_b4#P3>=VWHAN!%)~xdFomQfk04BvW=Bz+h00EtV+7PIeTo9$hLT z-XmzFkTkji2cMfk>wD9U8bd0t60P6uLmP9qUU3!MmBrUuhsLy7nmDua<&x=F>sMEc zY3|e52WUgOWb;26=I1d*x5qlMt}-#Drm2cuY(~)ujO5;SS$0^8eRbVHaZ5Hvkk~fb z{K#{x#mEun5u8Wyv~{!z?Xhmr5*cAF$rU*;;KsE$-~Q;AH7CoHo1-V*ojuFCGu-vl zbGpjoZo)_xuNGw$`vG)IRNn?boJnazWx6<6HEXA>Z@orgnL?JkwMTUsbqM&mL!Bs5#Tf4-hiehI&WOZ)vhJVlxF<~DUhPm_LZ}@;wP>sNb8Jsbxy0T1#H4> z3cJYBpFo{RSaGx|uUU~1I)IeQgaBVK`61QDC=Y0naGi4SDe($QkbQD7HuQcif;El) z%1rQ3ktNIGQM$fQU7XME;64DuvE2pT8eXHX5yV-)o2UPlHMqaUkTSSY}j@ zDPpnXIYI<9@XTbpAhP&C4+IBi@ua{fX1EDshz%Z&Z1{eu<|BJyBK&pxPq9C6 zPswKI3y6yE0##Ie4=C}rjIYLN(*!ij1{_1vxCfs~jIryV0c4F9&8jzxe1433nK z0px~iR&6O-a))U+VU4Cp4>StMAd?XkKD!m$bXySHAedPSbL)Ve3UZfJtZ*9N69>#?R9@4eUDpW?M8zy&MV_7NJG-L@R~T zBYgk4rg8J5cotgI96iRs^o(rXlEV>L`Fjm^zYN@6(+-Ceyqu!GM}7JB z?>XQ^RwrB~mPN{=Or^^Xz;cK1UK73whbIoUag)0bDX z7qucW=q7@90K&0XdcoH}za@Eu>-*3jQ2*|<@vtqrO$!N+6?kfCT{3_1 z5ZXED>^w3TW-CsDM=jmhLf^cn#9RItnL}I;^g8GSWwQBafjEF4QI??8(^+u_`9%-2 zGx^6UUUm3G0zZRctd*qX#Eq)t$ZW z#S4c#tx(#4z=x$y@89yj+=o~ z*0Wv|k#_gU!uqyPjDa|_e4k%1d)fA7T5C|lz zc+hX-vO&N$^~d!!#4`l0GKLU>Dx8?YYgUS@A9!C^Nqx_ISeSlCEMH%~^6&0c|m zr+eEYu`Mm}Et5v5Mu9G_FDoD(`6c273GqM9C1`yFti*uu?)FC#lyW6 z_ME2d6ivBmYYqdEG$vO<;WuXiT5ZXR*((YyqDX#8Lf3-I!AmkhOS>W?6pG2NA-%~#*2BbF>6TEM-4o4 zHv>%z#m-KXOY!{ zRsH~ZhdN6|5<_1C5-nQrwwVAs(y0BfHOLIPBl}@lY~U{S+vVNK4_k#-oXb5gP(sCA zP&+vY?B_pPm{0ZyjR>|*tGr55p--*GS8b;&KRVaTakvaRVD0S3`{(RuN;PKPIAf(i3S``Q+L zkyVSVPvoSWwv|_m?97!59!ChQpzybVSBRLJWACN4yYju?F}V|EZe`9+)XjI=rXb1XAQU4&I5Gy3>`=V~K5IrCW)mug2bW5eiZi4Hf6<&xJJ z_e(?4hyLF*2uSU5q*y>oBj6VwGffINWv=bEmsbjZsuxu}G@vRbI)?Zaza8*&)tr*` zqg;VDuD0(u5kZhha=1yI<;D7iLRlc@Wa=_PbZ3{!kh%dL8v+DXq*xTFHZwSd-lYS- zu%jQ!M#9hMp?Asqn-q+k+XBv(gNhQ6Y{2iu!T6EF!#?3|+aKGLB#3Duq)(tA5^L9@P`)Ll!jNF-V-cu zIX7|wt0U)axM90JD-?*D^DMy$N3sx!#9f2}6VF~L^})11KfCu_*3L~HhO3PmhnqV- z(PBH)1>lsNaUat9i%>+ZUH``Z2EPltZI{}mK8 zqr}rg2aM>50o4uHLqRNUwEy2(P%yepi+50s1sAz#gyZ@}&o zjtrrY68i`DE3M6>z_Ng_hAYNaV@9mECW=k}BnUFS2hhx7b<;bn8>-Bxg_AA1bh+Fa z+8FKPf-w-~RckF2xB`#hnD;N`htEubSckARmv0P_Y-lZn{ z(ll~0I@EtIW^h@!=V9C#d9XRRyeMbh95cWD7ebSFXn1<#t(Ry@9WJv@s9>M@*pMfMn@xBGU@M&UQvMy)eQ zeD0~k?UcD@jCT#^e@(^gO3W!_|6F&{{bQp*wphEHT0i$wVPtUuqZqVeBf_giM}(;G zCAaY<#-#;QHy>qj@gR&h(^mM6HSM=kX^Q7)w%xqe|3X48%lGVO-A(Xq2)_jt3@!!Jz2=bSR*&4IO^nYn;Pj=MCT+1z8cK6aj%Ea5XxN&Y} zOqwW(SfW9^;}>|Bur)V4ed7ALjU&<&HazKmIBCoK*nX@u_r^Co`5Qx7n^4xT_&FrF zatidC98{`C{i2Px+X%%)Ro6vC*10L)3>E5sdJ}{rWft@mOi-w@Jld74sHB4hvXDbS zdrzx?u+jya!o5((iiDYHvBw|LqbmDGtapryUjgMd_Boj7W+$|!(Ltn}!U;}hKul2t zO0fUENtO?M`ey(H=W#x$4*z*lhCqXypggM0LoTN&9Ic36(3co-oC{QK_&(gwt?R;B zePmwPpt(9VoUxl-;QFkjdZA{SCWLDFFx~c#Am-Owmcn7=V#sn~){;h{j)tFHrUnj> z^uK!7JG5dn!q0wJ=?SXYV-+uMW`9`zb-eogWR17l^G~G*9ves8{rfrfzZoc#%n?_P zLj<5{6jt+}#Ril~gK+$UNswcOy1x_LDQZfyj2uQLrasO)h-o+*gR9gsB{BZ)94*FM zJ*i!Fs6YF6DN?n0tBJ5vBHi#Z;p4^HoY4`hrOHf3pyKxt? zrSI`R?sl{%pR$naaWyZQ3Qb*F zekFWO zU$Dhq18^j|(2$(kgP9?Qhj}2`7#N zwv3jvp)L#6z`RX!lRl}4(Rv`{FwLk)Rz4ax3XfDndPOdX8I1@@M9HOGi=&Stexw1B z0`dv;Dac^+Sy`2O!w8E9z|lTUgpCocfo( z{|bj+UGD#G_qH6bXysQM@I7n)qTHObi7 zySe@9h(#-hnq!H*!v(jRgTtoMn_8=!V^ck>3v)LkO~uaKrv|zc3~Dk6W5Q61ny39_ zdCr!6y2%9&r1+nu{&_24s&)^El$EifB(bxhm-K^E9~wG$)Ykw?-Sa&?kE1Tueh;oSW`}EHWE4R4(DenJ)V3sL5MhoZ-YJXM}FKc4ZSu zZQNjVhbmogwngN;*3JXAreG`~$@a%hxGs-!pwIIV39n;IpkEdi=~1^9ACG>u$5FF# z>>&35YDr$wm7^PdN1jtqh1)}bgALF7`@1TDC30f)xD|b(cj< zfTILZ2EjnGz@*x?KUTZ6r;H zYi<8$8{N)T-~?6AZf`4%$xhZPf)>%s0!`v^qAUSvTn42eDIouh9|WWyaB1&Xe+#8j zb1CXRRCao?6)l+OO5@{m;mEFtfbn>U0;ki>^REvi?Ktat0~6h&Sg29c?@Z1>=TQ|l`ee)2`-%XC+ZIJ zst(Xx<`V_db_RX}H-8j1G1@p5sYne;KURJfH8KWYZ1~prv~9R*J!fq*=ZAfcr4Hbu zfoVv8sp1-1w0T@N{-DlESKpO|8;N2pI#jc$GVl9wUd8S8X=@`6@DJc8I-5Jq>vujG zP#umb*g8dZM12_xCI))IwEtf2|NV$_5#bp){_id=xmB9fttfnmR*)1#>Yrn`qm-kP zTFFQ`RLZGE%IvS&EiV#u#s?&3OA}DfI7|BV3Im>6ZLEDi;vGO0HDX5{ zHdWQ8a=U6JtMcDg^lwHzPtqxHUo?MO+Ks7C5!=_| z$0{_or+3=CN0h&K@UzYCH8%^m1@!H17Ya>A zSX54M{MS)|sJG$Q9UZ15C6g?%=BXpOqtyFH53C1EsXXiGy;9Q*R?yqLs=qWpk&`4r zuF>*bqlM#m+Wma|duk1S``p9py2d3(b8I2k?=8ybE#JS|1IIW!??LUcMU$yZoix=% zD;uTh>>q2>0{rw}v$=kI8%!ehso}$WWqj)v1%r;lu#rhmkrGn0{Yku88q3ExQ+Q6L zMBouHJmIER%*%i`k)J%!*>=R2Y_cpf3;yL}=RM7{Cn;b|g$TruXT8fiI`itJY)l!* zp0CTx*in)g>0ZeA-ZJ0L#p)J?K=#&`Uf5GJ{oeUwuZ;FaM1m%y^7izHqbf0jM%abW za@Tn~<%t(&1lwX3yx>C(IGtOI2^_0$cO5PivhJE}jl9c?nA7Rla(wis%FrKU<)iu3 z)UL2C?qHowknUJW(d*hH3&Hj2!978DAIU_-wq?x3(c}>{-o5Fu`^09;h2*h^Vh6Wo z2pDW9(aKWJ7f(yH{Td|wi0Hil9&`97sh}RP-amqdBCyZmxdEe%BiP(GK4u*)J5e7E zE)nhIvH(*lc7wZ?>8RD%ukydIQHd%+5xV-?D5NX0V_HnhN!{fLRu#h+wJk$bjTD%l z56LoS93DGQ6FTdoi7^&)b-_ep zhw^gMj0``6aDWrP@y{UTzf1hT9&a8A1H9(HcCK-X2EXjS&ioPb-{mIIz`5SVmz=Fw zGC;y*yjbEIzs?jAiT3!lzR|UaD#<-3cSbrC4R(x-jIFzxjJVYtvSS_UoRNkt)+h1H z)XA?VBPc9uniiJh_`Q1)p+fzpzoBxl|Iau%f1)98&@vAQYsjG+AFjoHTN(705c{G3H z6~DvqTdQ!z9sS~4_Iu@*VUOcQf4nl%g5>g{AQ2lMc&e-dh6tBa=6^Gsru)*&7q!Y`en`^!CnT8$Qd%D zQp|mc;hyurq;|AX$wzi&|BlfhbcFt&)ZFL;N-n}#AJw%}iL#QK6gQirR4v=r$$gYQ z@4cE<3Alb+pOE?An;#Ll6?t5Q{qv z&R!i12!&_otdg_2!CKVahdo@sFV^R!#6%1XZZ52(IGuQTD3Cej-=(FLQUl`)iCu;2 z@4EKfw(D1y^KLt2g@zlS=)4*+wXL7eOQF6!X6k<1UvWs$qjHMufO5MWVc+w>h%K}I z11TLTE%>_u%oU%QVp_Y02p1?d`Qp+-!u;ZoaN@gowZ6dJ4~=1kFs%Bxk!Xio-lcep z(x1eoNYnjtC0?d*QK>F%kRj_wD#x#1>g2gAx7fcjin_>4N%5Ta64`vZRfiOwH~5YR zB(nvzuHpr=ZW=qCU?WJ$K(1zBQ!86|jiVw+Gl3NkQPY)qKU2O33YmSBfDbMrIEs+4 zM#J_aX*a2nstISccO^>MwWW=-8t8j1RkoPtx(Sxd04b01`Dk=r0apAzdZKn~9eLjM zwuQv&O~>$E4;9f{8ttzJ$7cQ$xIxr*9(s)cK{xh;tQ5#CN#d1rVk3mPp_))?ropPJ z>Rx#WABZYOM(W(vR^`>oF>~8x#p`8MO;ebN*&PAw6bjMqpr&rVJQ6XaI5Df@BKy8j z8$bLfA;wMi|Fe?++4=9X^q)OwxO@8tiZ|fG_|N7i1#&zy!zhASR(QnidJc|Wge}vq zLj8pTN3GM;FR+%A*lpou6UnEbP8~TdN-$hW(Xj^N&I^%l?hzFB03fQfXZhmTQx(FO z4-ZLvxFmrH{rYE~`KUeX$E3L=U-?HZw_?$IUfwRkz!vn;qZoF%53TQWfdDc{l)>sX zP&xG#tR)oCk#7YZDUdf2e`TCxKPH6*B-@cokZwLKN*2JjG3Yfd^hOvlpgata_ee5G z>a&9dYQsT4U%Ks9$CaLis@B`+LTg8b7@Q!@jABWZ~}q6h1y`4R7?h{-K9)=!+Qfy zjM6ywm0K9eFO7%Q>~_={*2Lh=TN%{{?|eF^FdmnYrORS@a(N~RgZkm2Y!nqCI}&wb zFfXPA0~F_s_1b!8Y0TqZ@%HDrj|v&y8{HgQ7vY<4c`c};=iA3ntLO0>Mb<@{4vMo9+jJ*f8K z`xKZADt=1_?S+wSh7YQ*ldT!U5#6VPF@Oz#lzx_Q^4_*Ee|*KRT>dZQ+^eCVV)sHk z75*1OAu0PkXSmR+p!kKll~9vS1wO=Av#oH%v-WNKC4I#jtQTAJP$9VQ>0ouU=27aZ zOPR&9XN88=ebaD5kI;Z~cL7DGAH(;QH4)>VIr-1NgmHUlqJ&;=V<%(GB?gxS4_0+5Nf8+;lMQS zq}*A{sJ}+B3@)sg5|~C>z2f5fCMcgk7LsX62Nk3if6i{dFsIC>rr!~gmh*Znnp~ya z{UU|9q*Hz`r0*1OY&3at-&tf6b5>MmHxH=hYk+57J)~d+HE^<|qXkw@|NqMOYPJ6F zbR6vB@}<9g^`#Qa`|=+^2+ZwkfTOoQJ;L?l!Gn-8S95B1I;!V2EWWq%R)!fvRCAjaylMq&Mw%AVYZ=5MDyxcvr;nSMQHdSAFGc_iUJIZe`Z zBzk1F>H-}TX_hSUaqIkOpTgh-SxXLqUb~YlZ!ND~I1vvlLRNHNNMwS~xdJ#M0@@v6 ztZZr;UEwKYIU?Zn=;RE(aeC;j8_{diW=F6i*~Aojkj`=3 z0LKh1E@BkJ%_-mj-TAJoh2G>YMOg>W6gR;Hvdt$yx=+m>XXr%&Mvk1#XAN$LX-@g* z1M&QLGpB7>TAh}GSbB$jB|&f!39EJ{gie6;3j75vE+WX1FHM4XuKtO)O?b~MA7v|@ z*@b1Y0~+PAmch%iG_3lD+v9gkBuETC*4seQ%(T0%XzjdgCESO8erQ%})B!L+*hJ&4 zYlb}}I$x!IF{(Y`Y?7eKS?6~*LMA^>V;G+;cWe_n9iARraVX!6H}01Y%9l>+7x=Zb z2NNtu;_sI#y@-jev|wG^KPduTUD9Ujb>ifGm&b_pJuhvpDbE(o%BH;dY2J{HiJv;b z-lJ$Tqq>!HbyL`2DqrhMhSt%?`5g)*#phfyxIZYTcNFv6b+w$7 zbK{_xaw`!J*2(r&!Dg5`^^_aD!IUUAfH+`^HSQaf-wqON=)42W7q1Yj4zB z{Fk|GX+)t%^;AqZMq3_l4rC0U2(Z-ko5+Z$!?w#l^o}};?$yVH3311K)FCwSzkWmXS@>095OPLu_i!bk4rrLucpKoa?j#U=Ugs z7hEa-*XCoI@#N@#9ldrxTqJD#$<-0of99sm2>ps7*MzV5?YKCZ`CZy(<}O&cb}C8z zpa5Vp+$BR7kJU_lm`OfNwJR#Y{zUIbcyzhNrN1g1g`xHjP@FyXX~l-Bm?p~ZJjU7% z4+*`>O*?@G#Ux`DJ0=wSX@BCoy`__ntxFEyq~rUb*Ga`#<*fwBl}7Nd{ve>ced~ut zn1v+4!Pf0Sb{jcULF11qr4)rBS=z8q@CqPp18%`IZj%k@4npDS+^FxD<( z*wtwmCnk0lF^@Z~*dCA$DbT;Lm1n8>4Lp()o*&h@1RL!1M_{>U9&bHEMr|xEcEV<+ zV}A=b2qBo(d94uZZ>r`PDYZ;O#ZDhCuKl)ur!sp;iB0=hK+1|&Afv<+Nf`HHTzSNq zbJAs3zs-BQGGg-Am6ejV4L-OV;z&V=d?9z*7jAy@F4Xr)Up5SR#pY@&I84ss#ndp; z#Qx5!ZcML#9U3iavu|}!B9lj9l;iU16`wLJx#{kU63kx7v!?9m`4kh8A1w*?9B1k4 zbciNLE(L%j*ygP08lmrWEcv9oHWrf1MZQ5d*10m14vrX|M7On8oc4RbQP46d>zbp* zA6?AU>5by8{q)7>i^#XpsWgNOBcB<{i{DGcsJjgC|17ANIe44=hv|@KyrOX`s?KT= zWv`{#=f$W)q=WoGC+6VT6VTuRMkarsO$lfMhUeU%W`O(`_VvHkD){o=781II zI0AIM|7=RWDp^XRdaqJ$sN@41lB>f>IKIpeXhGwTQOXyTym&-eei+P#gj(9*@#;)u zp5VCS>e4P||M}i$R;`qK$y2$#!d&c_F+D8vjL#TqCL^~P#DP4{$)mT+hX-?wo+~Xq zo}KCj>t@w1%`|t~*WO7=Z(zp9j@M4knfeH z&V7ro=ASii@MyKKzdgO7V2llM{Twny)hU|4pwji9KzpT8iX)$$NCQ3nY#JH22TTwq zM{3zcubZ zC1~pYW2WKf?|$J!r_%R`Vu_T5{lv|Ammkp)MQWLc#1X3SGQtFt+uv#qtPQ94pRO%N zC5z44abk0a=JM++D>EzjdK4etRlU({NTpT3u{8i}$majlFFdGR=dV|GFH+L5j)<#v zG*y4>%x$VpyeqH91Lq0NiRt5I&F_iB_t$^|w<(+KS^qKZ@^(?dhepeTN&TAv$Wng4 z)Cz4g+^d9&5Cw*$G(SC^QHo{uqpWe{g^m7J)mj=`S9Bk6+;^=77}UeQJok;7uLj-Q z&ukmb^$Zg7*P<1*xV4o(QwweC7v!KNTC;SMKrO2o|IJ^!5LW;W<%pI42Ke#lx8wvs zL0{UpH%sI8-g3%!J4OZLZPYW1ljI<#I+5n~7w)@Q?}ye#%FQo-KD%w7hWS~mSBw?+ zYLU;Qa@sx#)dXw%qlnpb#!u(;s*{p;3R*k-D|&BTmr3hMLJp~z?pDs1J=#ErAS;pT zo+;kLS;2TcKX1$2^2PO~kfpjM(%rQEWk!=ki$#ioK+x)9Q~meK;$Y?1zA@uF!)I?PhPNB--OZ29=hym3p@Snw>u%iPEUCKktp7pN2yG*RFO?#28?ZwDON(qMkj=qBKdYE65 zQf?H7Oc2pE7ZWe%q>}ZS->9!6vnEIrEbok{q%g|k^sBbHO7_sugs!b?OOhC3u#VbT zwXtk|%*nE+n(;Py;U)sqzIUa7I9qYe(_ljqfRf3>u(%?P-?}t1v%WRncVqqZ8awq+ z$Ii&VrHQ^tzItpH4b62;cW7{fyBcrW+l{Tcq*BZU~Up0v3{*7G6`sz z?`O(@Yu}(=M%}^eqmx=hCh65oAkHI_+q$^LH;Eryb7l#U0u;ah*M@TuY(^IHpGg9sSM!d=1%B2u)tK8$1x=@2K26O}p!734Cs}41?KS z<&Y-I^od?~CAg?j4dpEN>xo+VCocjyc676*P@*W(TJwF6_GP2+Cx~aw%o}IzhUwzX2;Za^ioOnv(*bUt|hYQ ztbK9ApL=P>WwX^tIE}Z_`04mC9Q&jj6;ab7xMY}zuImUix(NLpJNpOKCNbWfq2QKe zy1a`G&-I@7qW|4)W6@VuPGyi(xK~$n4zu2Bu`JP_7&Ca7r7g|SnExv|)hzFpP(O## zeS2A{TTGACa96?zhb@^O70Dl@o6A{FB*`a$3DIwlqQtRo+_B|KqDmK{+|NS|9RMS({7u+o8xFCI=uvpGVgzQBCnDtzhg+qk zOqX2wo8m^^j(V-Yef;0av6r@mKT|L+Yqr$bKh z0rU+2_&S;+Wm>NYth zurPESHPo;?tH8D5aHgEgL}U8w;l|nue51k z_(I{J?jy}y4W>LL{orJ@AB@ShP>39h1@@bsH_4~3!cx5hkRJ73x?F#-m+a1^Zd|>e zdPa*f95((!+yhoo9qk8hOl>8OXbJNG_gmFRlnh%@1zYxW38EVg>VdjDEUPY<1&0e+ zcW-#c*L7jO7ViGjv;I?z?qeeaR<%TMdAndX)i!6I{;WSmvxSAxp?9%n@!n{i4<{E5~Dk& ze`u~UqZcLQLt@C!r9J87ZGbjawpTZ&N~FG+6MTMD%ud{C@kO)-TD1xrovo$}t5*nK zEm6PmK{+eJJv4*IdJBd=SJ~Oz#BfQXP>M7ZqDmU}vjs0k6F%G<7rxuDKOHDth^&lD z>{y)(bTF<>r&{6g^5&>4E_F*aqE_eeSuq{Fm$P0()=-=%$I3G!Q_k>|jLd1djrfJ$(CmE^Aa%voN z_(&3QxqRl@;N#KV#({?3YHQ~S4|QZljRaY_@Nw1!Uu-=fuk6)0`hN5qh8_<{pCZ^6j9)OBzV!J~9f*;Ie+YHaDM zdmrEt~CBx@9TAT;>M_ll7+zBqd_&j zNR|i4S%bSN9*)Kn9*7Jx9$@p}uZ=#U)YA6&N#y&_M+AW^SFO|ETzOi)=bRiW>{*0) zG9lnmvQ8tRRwJ&=hUZW^I9o{>;XEc<^BN#84_2D=R@@H9ne;79DTp_X)=wv}^NFMT z7ipC(Yx_FYD&foR$3A(<%@TTrgQ$q)V@kb=`l8Dri^yY~V%5%H8_B zK@uc4oEywKeCyJtU8s8;uWRFeX|Mw4`3q5P{M}(_ATa?u)wC@6<8_OQnuh16x1os$ zaMj{s3i(5E`luMA#lusgjXwj4!^OeH0WuEPOL$ppk(1SqLWAeZHk9NJs|D+H6g?yPSG87ei z>Pi!0;OsqorEZjFnl!Q+r$+qg7dfePW1M?{iqMW)dmQZem8Dl51J=Ac{wT?WOy)Sz zjlXbczy8=T)Eg!1g261cJhE=B7xbL6eU&#PSg(gr*Y>U~KG^9qxha2~uurGlmVgA|J@!h*zqA3%o%!vbz`(I@L%@^@`@NiinHiR|O z6u6-KI#L)%+lBj22MGc}lE>eBzf$9^Cy9|W+ur4x3rQGq&%I3C#Y&bo2takiY^Ea) z^AnvT=K2EC+xz5tpP1jTOf{41R=DoYvP$}}Z zinX;nWCYgRK)V0HfLje>j>hM=O^*vXbl4C+7d8it&YXl%^8wfB(9h!H_AU3SGDQ%7 zmIS+FP6%?w0lQ^E=z#eJSQlUegR&rC48VR-y{zXHH0?K(#i45$J0T5@C zvq{Z$Kj^Q`I93t9edCWENtnT)0+F_ZMWpaFvS$=4ZJFG&S>T`*X=jnwNGVyIj9sTiyjgP@|Jw(LZ3flnyGC9T5 zoLgp~z7}_`Tr>?s9V&E#GJhH_|QWMZDuw%K9QCB>sy{$4-;PNwR z95p^kX^PpNa8EByC)j*SEV~TPiG)%w=ZsqIE1Zxq2q<+etdUw6yVO;-$Ty9^iMOFL zL3=Zdg?~Yk>P~zEozqgc+-^(0jsaE01Q+9oT;&~qn>xj>XBURrqBgDRkSliUkuQhV zzSh{`*gGm!=t&}zwIM2Q+S`z2otNJ}!NtAw32{MHR4%pqlPJNeJr57$t68puWuqj| zkapLNe5UQL7OOprIt+~pm5?Th@MXR3Us+~?a?vkufuc5m@Ct5aNI>u|_*E5n)FkMz zdm%VYac&eeKJduh;tLkmio{cw0Fm>AiCVz708)+r7r#RI$aT2Q?C{=-2tPDRJS?O6 z(c2sICFoTsxYEsyyNk`Af$;YS8(6}Hkb=n5N5ss)yFg5L`5~c6g^U=YO}$D3_k#pz zMgY2m=56$DsgyYpFYH>2)A{gTx(eKPB1()#3Ix*|lRMJu>sL9R9T~rYu{1@S$#L(M zjMth_J?c5i*|h-4-&(9dOL?P3EdL3J>q4MX+?IGK5l4{vjNairiqn+kLwK%$ER#S3 zOUsKSWGrV-Gqfz7a~997XK<*fcj9C!Vc}{*(i341yIA<9W2BYiW`K@O-X^S;E5Vif z*Hqx#*E(7yVU_&$_3<)GohL%&@`t>lqaSw3Szhwh@X4Wf%A{2)gk!BNU6%$9Tyt#| z_?`)B8%mSJzvceyPjH_YmtPV9hf_GRW^_gXo+kh@P+Cfg)rI6pN5C z94S=>XM%{KEF4w{oRn2;WI%acVZoneTWN?&uaTLm;q_C&-)W74yY|Z^zE0O-1K{Ml;V?knSXN? zYA9e)%TK9}{rrEb*!4%UHVjg8WCjQ@PazhnWsmzDBC1aeKRKxu0lfx-M@P)$ zNQ&uRoW75TX8I9SsW{|4wb_g5n*JENFz-W66M(is)bg@D1sO@?AKu2-JDIq%%ksgAQL&0b-uAt+ zowJ5->-U-O=&@Rq%i)v!&$T_dYg(2*J}`ytKor6*x@FyHPf`PXxRWQ&C&@nC&X!YhkMjS z3%x9B5-bic={n;XuTK-K7qy#1B}8@m8U-5+c9WUql3AbE3o5x=Qb_gZD_SRE5WA;h zGe%2MygPgG3CTv`cd}|7jreKX9AweXBWJ?O(0tTNwNbISNtIOTfE6Nol6hM%O^ixy zpK9y+QCZbk%j2z;7VRdaXY_~_LYPGq-C8c`X$+<^u7-VqGF6oNTn^|F*Iy#mSGLSg zoq58kp}o8sex!%86`{5`0dO`VwxJ5-P08)9iEXb0D+zv3SZF~&{z+vKwzmU-B|HG4 zgu{AE!)h3(i-Lt+j5+HAAxNC@-#+WJ3mu7BZgW)o%{;my>@X^>H{L&(H54WNRh#6C z#jIq4?Ad}=q34Ww;c!#A;fL%)xa>*vR_xuIaWyjr`WyNYcOL6UekHvOcN8Lirt8BL zSMC?rlJ7T|oa&iZv7a5nzMhc(X77vJ@hI(tZ~r}Wpw2xdK+*FsJsmR3zN6J1=wc_W zr5>2dM4EfGWKg*<+p)sPp-ZU5BR$B_SwBT3Km)(h=*~(!Hkfk4CUJ|x=1W<>{)q0e zlQ&N!f0<2qbLkwr_t2bc&$u3v=GuGbm;=5aU8YRb+F%@k;B`KFA)nj1x_iSe_eVb2 zQSE9_VpH?(7}Ocj=POsfb{yf_qEq&fCJQ?Jv-(q@XTm_AbVJwp!mL-V8*I98rtzAp z7N~o2?i-*zm&9X#0@uE8@}1*Z8@|*a@MA4SuS-HC-ySYVr3#*OBwmx91Kqv|Ck}bv4HKE{|uLqOHrz; zRva4@rCtr+Qm{wZxLv-ONs_3MG*K3@(n&xFgZ|5+!8U+Uh8wIgN)IT|<4gEkC>GO1 z-M2IlBW`GeFuZ4hgYG)2^EAGbOTcP-$wd%TsUZp!Vyw%!jBu5g$y{>CGnw zS1Qx?hwaw+=zDypzxD99ncXSLz|D}4rPsulEmS91e8asI{9ir)3y&8gG|aov$mzuU zn)d`OSKD=T7+8%eOct{bCOr?c2-9mk`SyI*%qMD5y!_k8-ZnNVjtA)xJ}@!g+vB0( zTJ#^Z7Yp1H)81s$N!UEpdEZ@U2?Rg|fZyeieH$PbN1N(fcr4VV@IAGeq#mzjXrtXd z>yyqfe+SE+>8E}B9dDh4k5OW#yTv@=F(NuKLcb05Qj2f2nlh57N8W)h=8l9d8jtm_ z*SB!F{8)FPv<-86kR38!descMpaB=rL1vxH@4Ci=`n&5ds&q;Vx_<9B(;A1hl{%-M z%7BB01M<;JRF#JR_r}<9v_&1f$A%V9)mDB(Y`kg8R zu2#NQ0KrnNi^`S2+ItDCgLM9of*T>?A!M9oV}=13?Eg%fKEEBcE}$=`5GR?f4`|cyo+$lq>2ua5mk#{bZQm6oa31q zY&-f$4(-Z$v(y9`BCg!q1Z6{rT5`tEmY|A>9=*l8L(iifUivGJ6#`-V=s zr1U#8rcQD2g`!Z$>eJ*f_)N`=c;ZsTc;a`U?4DWLV(OrXhazrwJ}_1~SQnJK2iGFQR;qh{P z#j8`=xz|LBE>7Mu+?+7TMw}>%HhPOu340?+du>;4=Sq!8qHNLl5%Ry9CKsm##B28T zZSPUdTx)cgyVhlX4Jnd4`Fb)WeRbgXsJJpkt={yp*ePWMXVy}RhOM>>so8?-(C|aj z8lF`Y`*-(O9rA@k^sl+wUwodjQ?i_aRT`(1I7)BOj)Np}0sV0bV6Z@Ni6L=V-vb~} zh3#SuxpJd$fux=vYS91LDg*426AK%VG7H7g$S$D#Qk0d22l2;RXaAvl;Q~q3FJA-H zA-him33ov_E-O;Vc!hg$Wu0t3A4$qb<&=Ws296)9RCFV%grWuMcnhFU3Ok}+@O;m#xrMcHMN zxOO4tFAj2x(P}e;s|;`?=YG#AnOY%ba(!wjs3=8u2P+i#72htti>B)5Hc#xH3(3=mHtf|ls-dO^=z)GL$L>OPXSSA>?<@>u zYlLKs)r0k^R6A2IF>q4jcR$)_-{4f_;SjZY+Z9-KZ^Ei@wXFB+2&;C^PY}BDqYl}X zG>&tac80{fZ_!2ZVp?T}xTcPYGC`ONNg) zHCF>IV*E79N#-O1ZKFgoS?lcR1)@ElwBLB(I5|2Y4BvpmHe(YVdz>|^JsX7scaELH zKbl)RG>lJA*l=0$W->2<`Y?*Tw<+mRm)HqD0~ihfDmA%Aw}dEAX%u}}Y0%SMW)VRk zAz|+%=&*CT?(CkBIW&SCwC!V3q9Wp_FMUD4V1JonD)!}9)6&4n?w$ZkOFa-N? zElOvGvUAdo5*nWQQ9r+=HpJuC&;f4?=XshP*AUm|VZFvfTd8vX$5Yie-#mCGwvWX`0i6m@yil7gbzpE{^GH9_1+O`%2XY*k^o~4`>x2)=i968zQ z3yH<_YM%>zwc{CX=BVi3w^3c(WWRPLt=B_mX<>JR)jFf{_o7b2iQ8k{irpXehL4qA z41US4Pihlae!fOV7$+~R|JyFFf8^S>-CqzJ(SLLcJ)m1m!^$;^>pOhCHGh3ECf{f1 zFRK(y*>c^S%lpbtXbz~&Sp+FiEO(%o1;t; z=1#fl)9OxtRjo3J(`3Tc$%NOVq+?+8>i9BG|190~DB{c@9&%GB6si{FOc? z;@N#)nX(`29q^xBi6^iX@Ls}DDp?^ z(E~q{MmFx8d`YPPbIAX;J7O8ES#GHlsJ^X{*>GpXKxkdMXBn;Tp_Xjzm&oYA?x{2G(>lOfhop~(4zbp6z>c?yB>}?OW zAC|i}&{bhN=Qg$?91h|Z7?vaS5srI>RPl};^qp>=q@@N`lpuwlIQ`XBL|2fbq~0qt z`S7=kisAKHX0rc^l&dLYs0zD;bz47`*LErSg_@Z1;x6AueX$jGF_=cLetZ=JG0GEK z7p#P-mAdY0bZ?d)jRCuwoaU$#3)b+;STjy zBhy2L_iAQ?7d>eUe|njxC^q|^OxxbMt8$l*Do_jZo|t(6SCEcpr-(bCGFan!cbB8_ z*S!k$d4*u3J6{g6j>$cR#r>AVh)7csXTwQVQ=84aI336v;J)`#Q&bXabI#?LYYGth zaLNMA2lrBi;dWXzU__niDEXu{!+K-)*1!y0eW@^i-a@0is zaoBr!LG{EbPwe4C&Z~acv37}AzWcfmAF}v|y>n5!STO_9rymqA8Q25Zu_0(zIMQ^k zxGp^&=P0O5a{XmpOuS>R$(&%?VY2AU+~pZ|B`PP(A#`HJx~jxmM|9}7Q@V8-ldeHb zmEGoK+j&tsl94a!BdRujKgHpp9Cd*NDkpM?;hMc0r`*%qS|1h%4cDu%R1vaf++|tgKx}c5h%K|z>wVc`58nZn$BZroY z*DIrxsK>TAWyDfW)`?wR1Z)O5DY|?ZUnR^HBGQUmEWf9lAmS@E49b}MCch&nEe~I143DQXaeWIj4{GqRT}M{Q7=$i%i$&uf<4nl^@%BX)KAjo{e|e zx=&AXVZItH%q)FCZsgR|YIB6(i z)oj}TGV;x(&gIn1sj^xn+IHR9YUCageUMOM93~FC+hQ^NG0oMQbhK%QXEw(IvkT*I z`3OZCcxrA;pq9LL){ZW+M?GqnYI8iSSzMZW%b0(y(=$xz{ji57qfEY6aClAS%N_f0 z5yx@Ca&nO}(@_KVi<5lo^MiMv*rEjvs3xUBuIWI8Tyz%wP@N7(J>Ljr)RXV&dg$NA z{lz-7-NO?qI}KlpnV$q35z`Eh*@Y#q`d#hn5crs|a5fs}bVIEyJrPul9^MdX3ku-pYVna)v(8#+o}2h1#>ZnBZV<_rmgNPgjl8q22Hx^ZAf7^{^3RzP z{{LL!pSAvL`EYrXb_-J*o^i(o!J>E~&UQp{0D3>UyvMo>cF5Ldx7oot)t7*3i68mY z;KN&X_|bLdyu9FhL|1}`{ZpW`C_IP|VBj?CL?tsm$NCecdNxDt#u)8PIla6An W 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 ZQGZ3myamp~4=h-%2!=<$_xo%7e*lF!Io1FG literal 0 HcmV?d00001 diff --git a/docs/index.js b/docs/index.js new file mode 100644 index 00000000..c2dc632f --- /dev/null +++ b/docs/index.js @@ -0,0 +1,11 @@ +'use strict'; + +var React = require('react'); +require('../node_modules/normalize.css/normalize.css'); + +var Home = require('./components/home/Home'); + +React.render( + React.createElement(Home), + document.getElementById('root') +); diff --git a/package.json b/package.json index c525bf41..1fb2884d 100644 --- a/package.json +++ b/package.json @@ -21,5 +21,8 @@ "npm": "^2.13.4", "react": "^0.13.3", "tinycolor2": "^1.1.2" + }, + "devDependencies": { + "normalize.css": "^3.0.3" } } diff --git a/src/specs/Color.spec.js b/src/specs/Color.spec.js deleted file mode 100644 index 8ba4f008..00000000 --- a/src/specs/Color.spec.js +++ /dev/null @@ -1,19 +0,0 @@ - -var Harness = require('react-harness'); -var Color = require('./../components/Color'); - -module.exports = { - label: 'Color', - desc: 'Lorem Ipsum', - - component: Color, - - instances: { - 'default': { - presetColors: ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#BD10E0', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF'], - }, - 'No Presets': { - presetColors: false, - }, - }, -}; diff --git a/src/specs/index.js b/src/specs/index.js deleted file mode 100644 index a86c301b..00000000 --- a/src/specs/index.js +++ /dev/null @@ -1,4 +0,0 @@ - -module.exports = { - ColorPicker: require('./Color.spec'), -}; From a39d12d8daabc129e52fb10ade7bfd0f7d9ba016 Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 21:28:29 -0400 Subject: [PATCH 028/119] Modules Dump --- .../components/Container.jsx | 29 +++ .../react-basic-layout/components/Grid.jsx | 36 +++ modules/react-basic-layout/index.js | 5 + modules/react-docs/components/Code.jsx | 144 ++++++++++++ modules/react-docs/components/Docs.jsx | 20 ++ modules/react-docs/components/Markdown.jsx | 99 ++++++++ .../react-docs/components/MarkdownTitle.jsx | 71 ++++++ modules/react-docs/helpers/markdown.js | 85 +++++++ modules/react-docs/index.js | 2 + modules/react-material-design/index.js | 6 + .../src/components/Link.jsx | 42 ++++ .../src/components/Raised.jsx | 94 ++++++++ .../src/components/Tab.jsx | 65 ++++++ .../src/components/Tabs.jsx | 215 ++++++++++++++++++ .../src/components/Tile.jsx | 85 +++++++ 15 files changed, 998 insertions(+) create mode 100644 modules/react-basic-layout/components/Container.jsx create mode 100644 modules/react-basic-layout/components/Grid.jsx create mode 100644 modules/react-basic-layout/index.js create mode 100644 modules/react-docs/components/Code.jsx create mode 100644 modules/react-docs/components/Docs.jsx create mode 100644 modules/react-docs/components/Markdown.jsx create mode 100644 modules/react-docs/components/MarkdownTitle.jsx create mode 100644 modules/react-docs/helpers/markdown.js create mode 100644 modules/react-docs/index.js create mode 100644 modules/react-material-design/index.js create mode 100644 modules/react-material-design/src/components/Link.jsx create mode 100644 modules/react-material-design/src/components/Raised.jsx create mode 100644 modules/react-material-design/src/components/Tab.jsx create mode 100644 modules/react-material-design/src/components/Tabs.jsx create mode 100644 modules/react-material-design/src/components/Tile.jsx diff --git a/modules/react-basic-layout/components/Container.jsx b/modules/react-basic-layout/components/Container.jsx new file mode 100644 index 00000000..68712377 --- /dev/null +++ b/modules/react-basic-layout/components/Container.jsx @@ -0,0 +1,29 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class Container extends ReactCSS.Component { + + classes() { + return { + 'default': { + container: { + maxWidth: this.props.width + 'px', + padding: '0 20px', + margin: '0 auto', + }, + }, + }; + } + + render() { + return

{ this.props.children }
; + } +} + +Container.defaultProps = { + width: 960, +}; + +module.exports = Container; diff --git a/modules/react-basic-layout/components/Grid.jsx b/modules/react-basic-layout/components/Grid.jsx new file mode 100644 index 00000000..51093f23 --- /dev/null +++ b/modules/react-basic-layout/components/Grid.jsx @@ -0,0 +1,36 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var context = require('react-context'); + +class Grid extends ReactCSS.Component { + + classes() { + return { + 'default': { + grid: { + position: 'relative', + }, + left: { + position: 'absolute', + width: '130px', + }, + main: { + paddingLeft: '150px', + }, + }, + }; + } + + render() { + return ( +
+
{ this.props.children[0] }
+
{ this.props.children[1] }
+
+ ); + } +} + +module.exports = Grid; diff --git a/modules/react-basic-layout/index.js b/modules/react-basic-layout/index.js new file mode 100644 index 00000000..d07d73f0 --- /dev/null +++ b/modules/react-basic-layout/index.js @@ -0,0 +1,5 @@ + +module.exports = { + Container: require('./components/Container'), + Grid: require('./components/Grid'), +}; diff --git a/modules/react-docs/components/Code.jsx b/modules/react-docs/components/Code.jsx new file mode 100644 index 00000000..9455fe0a --- /dev/null +++ b/modules/react-docs/components/Code.jsx @@ -0,0 +1,144 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var markdown = require('../../helpers/markdown'); +var context = require('react-context'); + +var { Tile } = require('react-material-design'); + +class Code extends ReactCSS.Component { + + constructor() { + super(); + } + + classes() { + return { + 'default': { + shortCodeBlock: { + display: 'inline-block', + }, + shortCode: { + padding: '14px 16px', + }, + head: { + borderRadius: '2px 2px 0 0', + background: '#fafafa', + }, + files: { + display: 'inline-block', + }, + Files: { + align: 'none', + color: '#666', + }, + center: { + fontFamily: 'Monaco', + fontSize: '14px', + lineHeight: '19px', + color: 'rgba(0,0,0,.77)', + }, + numbers: { + fontSize: '14px', + lineHeight: '19px', + display: 'inline-block', + textAlign: 'right', + color: 'rgba(0,0,0,.20)', + userSelect: 'none', + paddingLeft: '7px', + }, + }, + 'condensed': { + Tile: { + condensed: true, + }, + center: { + paddingTop: '16px', + paddingBottom: '16px', + fontSize: '13px', + lineHeight: '15px', + overflowX: 'scroll', + }, + numbers: { + paddingTop: '16px', + fontSize: '13px', + lineHeight: '15px', + }, + }, + 'borders': { + code: { + borderTop: '1px solid #eee', + borderBottom: '1px solid #eee', + }, + }, + }; + } + + styles() { + return this.css({ + 'condensed': this.context.width < 500, + }); + } + + render() { + var code = markdown.getBody(this.props.file); + var args = markdown.getArgs(this.props.file); + var colorCoded = markdown.renderCode('```\n' + code + '```').trim(); + var lineCount = colorCoded.split('\n').length; + + var lines; + if (args.lineDecoration) { + lines = args.lineDecoration; + } else { + lines = []; + for (var i = 1; i < lineCount; i++) { + lines.push(
{ i }
); + } + } + + return ( +
+ + + + +
+ { lines } +
+
+ +
+
+ + +
+ ); + } +} + +Code.contextTypes = context.subscribe(['width']); + +module.exports = Code; diff --git a/modules/react-docs/components/Docs.jsx b/modules/react-docs/components/Docs.jsx new file mode 100644 index 00000000..e82ac9ae --- /dev/null +++ b/modules/react-docs/components/Docs.jsx @@ -0,0 +1,20 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class Docs extends ReactCSS.Component { + + classes() { + return { + 'default': { + }, + }; + } + + render() { + return
docs
; + } +} + +module.exports = Docs; diff --git a/modules/react-docs/components/Markdown.jsx b/modules/react-docs/components/Markdown.jsx new file mode 100644 index 00000000..1905e345 --- /dev/null +++ b/modules/react-docs/components/Markdown.jsx @@ -0,0 +1,99 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var markdown = require('../../helpers/markdown'); + +var Code = require('./Code'); + +module.exports = class Markdown extends ReactCSS.Component { + + classes() { + return { + 'default': { + markdown: { + fontSize: '17px', + lineHeight: '24px', + color: 'rgba(0,0,0,.47)', + }, + }, + }; + } + + shouldComponentUpdate() { + return false; + } + + render() { + var children = this.props.children; + + var newLines = children; + + var codes = []; + for (var i = 0; i < markdown.isCode(children).length; i++) { + var codeBlock = markdown.isCode(children)[i]; + newLines = newLines.replace(codeBlock[1], '|Code:' + i + '|'); + codes[i] = ; + } + + var markdownFile = []; + for (var i = 0; i < newLines.split('\n').length; i++) { + var line = newLines.split('\n')[i]; + if (markdown.isCodeBlock(line)) { + markdownFile.push(
{ codes[ markdown.codeNumber(line) ] }
); + } else { + markdownFile.push(
); + } + } + + return ( +
+ + + { markdownFile } + +
+ ); + } +}; diff --git a/modules/react-docs/components/MarkdownTitle.jsx b/modules/react-docs/components/MarkdownTitle.jsx new file mode 100644 index 00000000..f96ad244 --- /dev/null +++ b/modules/react-docs/components/MarkdownTitle.jsx @@ -0,0 +1,71 @@ +/* jshint node: true, esnext: true */ +"use strict"; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +module.exports = class MarkdownTitle extends ReactCSS.Component { + + constructor() { + super(); + this.state = { + hover: false, + }; + this.handleHover = this.handleHover.bind(this); + } + + classes() { + return { + 'default': { + link: { + opacity: '0', + textDecoration: 'none', + fill: '#2A5881', + transition: 'opacity 200ms linear', + }, + }, + 'hovered': { + link: { + opacity: '1', + }, + }, + }; + } + + styles() { + return this.css({ + 'hovered': this.state.hover, + }); + } + + handleHover(e) { + if (e.type === 'mouseenter') { + this.setState({ hover: true }); + } else if (e.type === 'mouseleave') { + this.setState({ hover: false }); + } + } + + render() { + var linkSvg = { + __html: ` + + + + `, + }; + + var title; + if (this.props.isHeadline) { + title =

{ this.props.title }

; + } else { + title =

{ this.props.title }

; + } + + return ( +
+ { title } +
+ ); + } +}; diff --git a/modules/react-docs/helpers/markdown.js b/modules/react-docs/helpers/markdown.js new file mode 100644 index 00000000..d3b2f1cf --- /dev/null +++ b/modules/react-docs/helpers/markdown.js @@ -0,0 +1,85 @@ +'use strict'; + +var Remarkable = require('remarkable'); +var hljs = require('highlight.js'); +var regularMd = new Remarkable(); +var codeMd = new Remarkable({ + highlight: function(str) { + try { + return hljs.highlight('javascript', str).value; + } + catch (err) { + console.log(err); + } + }, +}); + +module.exports = { + + render: function(text) { + return regularMd.render(text); + }, + + renderCode: function(text) { + return codeMd.render(text); + }, + + getArgs: function(code) { + var args = {}; + if (code.indexOf('---') > -1) { + var match = /---([\s\S]*?)---\n([\s\S]*)/.exec(code); + var argSplit = match[1].trim().split('\n'); + + for (var i = 0; i < argSplit.length; i++) { + var arg = argSplit[i]; + var regex = /(.+?): (.+)/.exec(arg); + args[regex[1]] = regex[2]; + } + + code = match[2]; + } + + return args; + }, + + getBody: function(code) { + if (code.indexOf('---') > -1) { + var match = /---([\s\S]*?)---\n([\s\S]*)/.exec(code); + return match[2]; + } else { + return code; + } + }, + + isCode: function(text) { + var array = []; + var reg = new RegExp(/(```.*\n([\s\S]*?)```)/g); + var match; + while ((match = reg.exec(text)) !== null) { + array.push(match); + } + + return array; + }, + + isCodeBlock: function(string) { + if (string.indexOf('|Code:') > -1) { + return true; + } else { + return false; + } + }, + + isSubSection: function(string) { + if (string.split('-')[0].indexOf('.') === -1) { + return true ; + } else { + return false; + } + }, + + codeNumber: function(string) { + return /\|Code:(.+?)\|/.exec(string)[1]; + }, + +}; diff --git a/modules/react-docs/index.js b/modules/react-docs/index.js new file mode 100644 index 00000000..c9460af0 --- /dev/null +++ b/modules/react-docs/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./components/Docs.jsx'); diff --git a/modules/react-material-design/index.js b/modules/react-material-design/index.js new file mode 100644 index 00000000..65874b5f --- /dev/null +++ b/modules/react-material-design/index.js @@ -0,0 +1,6 @@ +module.exports = { + Raised: require('./src/components/Raised'), + Tile: require('./src/components/Tile'), + + Tabs: require('./src/components/Tabs'), +}; diff --git a/modules/react-material-design/src/components/Link.jsx b/modules/react-material-design/src/components/Link.jsx new file mode 100644 index 00000000..921d0b62 --- /dev/null +++ b/modules/react-material-design/src/components/Link.jsx @@ -0,0 +1,42 @@ +'use strict'; + +var React = require('react'); +var _ = require('lodash'); + +class Link extends React.Component { + + constructor() { + super(); + this.handleClick = this.handleClick.bind(this); + } + + handleClick(e) { + if (this.props.onClick) { + this.props.onClick(e, this.props.callbackValue); + } + } + + render() { + + var a; + if (_.isString(this.props.onClick)) { + a =
{ this.props.children }; + } else { + a = { this.props.children }; + } + + return a; + } +} + +// Link.propTypes = +// onClick: React.PropTypes.oneOfType( +// React.PropTypes.string, +// React.PropTypes.func +// ); + +Link.defaultProps = { + newTab: false, +}; + +module.exports = Link; diff --git a/modules/react-material-design/src/components/Raised.jsx b/modules/react-material-design/src/components/Raised.jsx new file mode 100644 index 00000000..d9405069 --- /dev/null +++ b/modules/react-material-design/src/components/Raised.jsx @@ -0,0 +1,94 @@ +/* jshint node: true, esnext: true */ +"use strict"; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class Raised extends ReactCSS.Component { + + classes() { + return { + 'default': { + wrap: { + position: 'relative', + }, + content: { + position: 'relative', + }, + bg: { + Absolute: '0 0 0 0', + boxShadow: '0 ${ this.props.zDepth }px ${ this.props.zDepth * 4 }px rgba(0,0,0,.24)', + borderRadius: this.props.radius, + background: this.props.background, + }, + }, + 'zDepth-0': { + bg: { + boxShadow: 'none', + }, + }, + + 'zDepth-1': { + bg: { + boxShadow: '0 2px 10px rgba(0,0,0,.12), 0 2px 5px rgba(0,0,0,.16)', + }, + }, + 'zDepth-2': { + bg: { + boxShadow: '0 6px 20px rgba(0,0,0,.19), 0 8px 17px rgba(0,0,0,.2)', + }, + }, + 'zDepth-3': { + bg: { + boxShadow: '0 17px 50px rgba(0,0,0,.19), 0 12px 15px rgba(0,0,0,.24)', + }, + }, + 'zDepth-4': { + bg: { + boxShadow: '0 25px 55px rgba(0,0,0,.21), 0 16px 28px rgba(0,0,0,.22)', + }, + }, + 'zDepth-5': { + bg: { + boxShadow: '0 40px 77px rgba(0,0,0,.22), 0 27px 24px rgba(0,0,0,.2)', + }, + }, + 'square': { + bg: { + borderRadius: '0', + }, + }, + 'circle': { + bg: { + borderRadius: '50%', + }, + }, + }; + } + + render() { + return ( +
+
+
{ this.props.children }
+
+ ); + } +} + +Raised.propTypes = { + background: React.PropTypes.string, + zDepth: React.PropTypes.oneOf(['0', '1', '2', '3', '4', '5', 0, 1, 2, 3, 4, 5]), + radius: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.number, + ]), +}; + +Raised.defaultProps = { + background: '#fff', + zDepth: '1', + radius: '2px', +}; + +module.exports = Raised; diff --git a/modules/react-material-design/src/components/Tab.jsx b/modules/react-material-design/src/components/Tab.jsx new file mode 100644 index 00000000..eecd546f --- /dev/null +++ b/modules/react-material-design/src/components/Tab.jsx @@ -0,0 +1,65 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class Tab extends ReactCSS.Component { + + constructor() { + super(); + + this.handleClick = this.handleClick.bind(this); + } + + classes() { + return { + 'default': { + tab: { + color: this.props.inactive || this.props.color, + cursor: 'pointer', + paddingLeft: '12px', + paddingRight: '12px', + height: '48px', + lineHeight: '48px', + textAlign: 'center', + fontSize: '14px', + textTransform: this.props.capitalize === false ? '' : 'uppercase', + fontWeight: '500', + whiteSpace: 'nowrap', + opacity: '.47', + transition: 'opacity 100ms linear', + }, + }, + 'selected': { + tab: { + color: this.props.color, + opacity: '.87', + }, + }, + }; + } + + handleClick() { + if (this.props.selectable !== false) { + this.props.onClick(this.props.tab); + } + } + + render() { + return ( +
{ this.props.children }
+ ); + } + +} + +Tab.propTypes = { + selected: React.PropTypes.bool, +}; + +Tab.defaultProps = { + selected: false, + color: '#fff', +}; + +module.exports = Tab; diff --git a/modules/react-material-design/src/components/Tabs.jsx b/modules/react-material-design/src/components/Tabs.jsx new file mode 100644 index 00000000..60a57544 --- /dev/null +++ b/modules/react-material-design/src/components/Tabs.jsx @@ -0,0 +1,215 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var _ = require('lodash'); + +var Tab = require('./Tab'); +var Link = require('./Link'); + +// var Ink = require('./Ink'); + +// var context = { +// primaryColor: '#2196F3', +// accentColor: '#E91E63', +// theme: 'light' +// } + +class Tabs extends ReactCSS.Component { + + constructor(props) { + super(); + + var selectedTab; + if (props.selectedTab < (props.tabs && props.tabs.length)) { + selectedTab = props.selectedTab; + } else { + selectedTab = 0; + } + + this.state = { + selectedTab: selectedTab, + }; + + this.handleClick = this.handleClick.bind(this); + this.slide = this.slide.bind(this); + } + + classes() { + return { + 'default': { + tabs: { + position: 'relative', + background: this.props.background, + }, + tabWrap: { + display: 'flex', + }, + tab: { + justifyContent: 'flex-start', + minWidth: '68px', + maxWidth: '240px', + }, + Tab: { + color: this.props.color, + inactive: this.props.inactive, + capitalize: this.props.capitalize, + }, + indicator: { + height: '0', + position: 'absolute', + bottom: '0', + left: '0', + background: this.props.color, + transition: 'all 200ms linear', + }, + }, + 'scrollable': { + tabs: { + overflowX: 'scroll', + }, + tabWrap: { + paddingLeft: '60px', + justifyContent: 'flex-start', + width: '400%', + }, + tab: { + width: 'auto', + }, + }, + 'align-justify': { + tabWrap: { + justifyContent: 'space-between', + }, + tab: { + width: `${ 100 / this.props.tabs.length }%`, + }, + }, + 'align-left': { + tabWrap: { + paddingLeft: '60px', + justifyContent: 'flex-start', + }, + tab: { + width: 'auto', + }, + }, + 'align-center': { + tabWrap: { + justifyContent: 'center', + }, + tab: { + width: 'auto', + }, + }, + }; + } + + styles() { + return this.css({ + 'scrollable': this.props.width / this.props.tabs.length < 72, + }); + } + + handleClick(tab) { + if (this.props.onChange) { + this.props.onChange(tab); + } + + this.setState({ + selectedTab: tab, + }); + } + + slide() { + if (this.props.tabs.length) { + var containerNode = this.refs.tabs.getDOMNode(); + var containerLeft = containerNode.scrollLeft; + var containerRight = containerNode.offsetWidth + containerNode.scrollLeft; + + var selectedNode = this.refs['tab-' + this.state.selectedTab] && this.refs['tab-' + this.state.selectedTab].getDOMNode(); + var selectedLeft = selectedNode && selectedNode.getBoundingClientRect().left - containerNode.getBoundingClientRect().left + containerNode.scrollLeft; + var selectedRight = selectedNode && selectedLeft + selectedNode.offsetWidth; + + // scroll right if tab is off screen + if (selectedRight > containerRight) { + containerNode.scrollLeft += (selectedRight - containerRight); + } + + // scroll left if tab is off screen + if (selectedLeft < containerLeft) { + containerNode.scrollLeft -= (containerLeft - selectedLeft); + } + + // slide the indicator + var indicator = React.findDOMNode(this.refs.indicator); + indicator.style.left = selectedLeft + 'px'; + indicator.style.width = selectedNode.offsetWidth + 'px'; + indicator.style.height = '2px'; + } + } + + componentDidMount() { + this.slide(); + } + + componentWillReceiveProps(nextProps) { + if (nextProps.selectedTab !== this.state.selectedTab) { + this.setState({ selectedTab: nextProps.selectedTab }); + } + } + + componentWillUpdate(nextProps, nextState) { + if (nextState.selectedTab >= (nextProps.tabs && nextProps.tabs.length)) { + nextState.selectedTab = nextProps.tabs.length - 1; + } + } + + componentDidUpdate() { + this.slide(); + } + + render() { + var tabs = []; + for (var i = 0; i < this.props.tabs.length; i++) { + var tab = this.props.tabs[i]; + + var label; + var callback; + var callbackValue; + var newTab; + if (_.isString(tab)) { + label = tab; + callback = null; + } else { + label = tab.label; + callback = tab.onClick; + callbackValue = tab.callbackValue; + newTab = tab.newTab; + } + + tabs.push(
+ + { label } + +
); + } + + return ( +
+
+ { tabs } +
+
+
+ ); + } +} + +Tabs.defaultProps = { + selectedTab: 0, + background: 'transparent', + color: '#fff', +}; + +module.exports = Tabs; diff --git a/modules/react-material-design/src/components/Tile.jsx b/modules/react-material-design/src/components/Tile.jsx new file mode 100644 index 00000000..bebed086 --- /dev/null +++ b/modules/react-material-design/src/components/Tile.jsx @@ -0,0 +1,85 @@ +/* jshint node: true, esnext: true */ +"use strict"; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +module.exports = class Tile extends ReactCSS.Component { + + classes() { + return { + 'default': { + tile: { + fontSize: '16px', + padding: '16px', + display: 'flex', + justifyContent: 'space-between', + color: this.props.color, + }, + primary: { + display: 'flex', + width: '100%', + }, + sidebar: { + minWidth: '56px', + maxWidth: '56px', + flexBasis: '56', // 72 minus 16 + }, + content: { + background: 'none', + flex: '1', + maxWidth: '95%', + }, + secondary: { + flexBasis: '42', + textAlign: 'center', + }, + sidebarIcon: { + marginTop: '-12px', + marginLeft: '-12px', + marginBottom: '-12px', + }, + }, + 'divider': { + tile: { + boxShadow: 'inset 0 -1px 0 rgba(0,0,0,.12)', + }, + }, + 'condensed': { + tile: { + paddingBottom: '0', + paddingTop: '0', + }, + sidebar: { + minWidth: '28px', + maxWidth: '28px', + flexBasis: '28', + }, + }, + }; + } + + styles() { + return this.css({ + 'clickable': this.props.onClick, + }); + } + + render() { + var [ sidebar, content ] = this.props.children; + + return ( +
+ +
+
+ { sidebar } +
+
+ { content } +
+
+
+ ); + } +}; From 8d184ac6c0c072ac71f5dbcdc31276d9e0fc9e23 Mon Sep 17 00:00:00 2001 From: case Date: Tue, 11 Aug 2015 23:11:13 -0400 Subject: [PATCH 029/119] Gulp! --- docs/components/home/HomeFeature.jsx | 4 +- gulpfile.js | 29 +++++++++++++ index.html | 27 ++++++++++++ .../react-basic-layout/components/Grid.jsx | 1 - package.json | 17 +++++++- src/index.js | 2 +- webpack.config.js | 43 +++++++++++++++++++ 7 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 gulpfile.js create mode 100644 index.html create mode 100644 webpack.config.js diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index 04e5e4cc..fb78e1cf 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -4,7 +4,7 @@ var React = require('react'); var ReactCSS = require('reactcss'); var ColorPicker = require('react-color'); -var { Container, Grid } = require('../layout'); +var { Container, Grid } = require('react-basic-layout'); var { Raised } = require('react-material-design'); class HomeFeature extends ReactCSS.Component { @@ -20,7 +20,7 @@ class HomeFeature extends ReactCSS.Component { return (
- feature + Feature
); diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 00000000..077f6dd6 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,29 @@ +var gulp = require('gulp'); +var gutil = require('gulp-util'); +var webpack = require('webpack'); +var WebpackDevServer = require('webpack-dev-server'); +var webpackConfig = require('./webpack.config.js'); + +gulp.task('docs', function(callback) { + var port = 9100; + var docs = Object.create(webpackConfig); + + docs.entry = ['webpack-dev-server/client?http://localhost:' + port, 'webpack/hot/dev-server', docs.entry[0]]; + + docs.devtool = 'eval'; + docs.debug = true; + + new WebpackDevServer(webpack(docs), { + publicPath: '/' + docs.output.publicPath, + hot: true, + stats: { + cached: false, + cachedAssets: false, + colors: true, + exclude: ['node_modules', 'components'], + }, + }).listen(port, 'localhost', function(err) { + if (err) throw new gutil.PluginError('webpack-dev-server', err); + gutil.log('[webpack-dev-server]', 'http://localhost:' + port + '/'); + }); +}); diff --git a/index.html b/index.html new file mode 100644 index 00000000..e913c24c --- /dev/null +++ b/index.html @@ -0,0 +1,27 @@ + + + + + + + + + React Color + + + + +
+ + + + + + diff --git a/modules/react-basic-layout/components/Grid.jsx b/modules/react-basic-layout/components/Grid.jsx index 51093f23..e4fadc3e 100644 --- a/modules/react-basic-layout/components/Grid.jsx +++ b/modules/react-basic-layout/components/Grid.jsx @@ -2,7 +2,6 @@ var React = require('react'); var ReactCSS = require('reactcss'); -var context = require('react-context'); class Grid extends ReactCSS.Component { diff --git a/package.json b/package.json index 1fb2884d..2ec50b30 100644 --- a/package.json +++ b/package.json @@ -18,11 +18,26 @@ "homepage": "https://github.com/casesandberg/react-color#readme", "dependencies": { "install": "^0.1.8", + "lodash": "^3.10.1", "npm": "^2.13.4", "react": "^0.13.3", + "reactcss": "^0.3.2", "tinycolor2": "^1.1.2" }, "devDependencies": { - "normalize.css": "^3.0.3" + "babel-core": "^5.8.22", + "babel-loader": "^5.3.2", + "css-loader": "^0.15.6", + "gulp": "^3.9.0", + "gulp-util": "^3.0.6", + "html-loader": "^0.3.0", + "jsx-loader": "^0.13.2", + "normalize.css": "^3.0.3", + "react-context": "0.0.1", + "react-hot-loader": "^1.2.8", + "react-map-styles": "^0.2.0", + "style-loader": "^0.12.3", + "webpack": "^1.11.0", + "webpack-dev-server": "^1.10.1" } } diff --git a/src/index.js b/src/index.js index 7c8d4f51..32472599 100644 --- a/src/index.js +++ b/src/index.js @@ -1,2 +1,2 @@ -module.exports = require('./components/ColorPicker'); +module.exports = require('./components/Color'); diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 00000000..d81ef893 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,43 @@ +var path = require('path'); +var webpack = require('webpack'); + +module.exports = { + entry: ['./docs/index.js'], + output: { + path: path.join(__dirname, 'build'), + filename: 'bundle.js', + publicPath: 'build/', + }, + module: { + loaders: [ + { + test: /\.js$/, + exclude: /node_modules/, + loaders: ['react-hot-loader', 'babel-loader'], + }, { + test: /\.jsx$/, + exclude: /node_modules/, + loaders: ['react-hot-loader', 'jsx-loader', 'babel-loader', 'react-map-styles'], + }, { + test: /\.css$/, + loaders: ['style-loader', 'css-loader'], + }, { + test: /\.md$/, + loaders: ['html-loader'], + }, + ], + }, + resolve: { + alias: { + 'react-color': path.resolve(__dirname, './src/index.js'), + 'react': path.resolve(__dirname, './node_modules/react'), + }, + extensions: ['', '.js', '.jsx'], + fallback: [path.resolve(__dirname, './modules')], + }, + plugins: [ + new webpack.HotModuleReplacementPlugin({quiet: true}), + new webpack.NoErrorsPlugin(), + ], + quiet: true, +}; From 59b31102f6d02085aa3c6eca0862c6cb8b7f5311 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 00:12:50 -0400 Subject: [PATCH 030/119] Feature Stubbed --- docs/components/home/Home.jsx | 15 ++- docs/components/home/HomeFeature.jsx | 86 +++++++++++++++++- docs/images/bg-2.jpg | Bin 0 -> 124548 bytes .../react-basic-layout/components/Grid.jsx | 22 +++++ src/components/Color.js | 24 +++-- src/components/chrome/Chrome.jsx | 1 + src/components/common/Hue.jsx | 1 - src/components/photoshop/Photoshop.jsx | 1 + 8 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 docs/images/bg-2.jpg diff --git a/docs/components/home/Home.jsx b/docs/components/home/Home.jsx index 32b85f41..189b0703 100644 --- a/docs/components/home/Home.jsx +++ b/docs/components/home/Home.jsx @@ -1,15 +1,26 @@ 'use strict'; var React = require('react'); +var ReactCSS = require('reactcss'); var HomeFeature = require('./HomeFeature'); var HomeDocumentation = require('./HomeDocumentation'); -module.exports = class Home extends React.Component { +module.exports = class Home extends ReactCSS.Component { + + classes() { + return { + 'default': { + home: { + fontFamily: 'Roboto', + }, + }, + }; + } render() { return ( -
+
diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index fb78e1cf..e86b9265 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -7,11 +7,60 @@ var ColorPicker = require('react-color'); var { Container, Grid } = require('react-basic-layout'); var { Raised } = require('react-material-design'); +var green = { + h: 122, + s: 39, + l: 49, + a: 100, +}; + class HomeFeature extends ReactCSS.Component { classes() { return { 'default': { + graphic: { + height: '580px', + background: 'url("http://localhost:9100/docs/images/bg-2.jpg")', + backgroundPosition: 'center center', + backgroundSize: 'cover', + }, + logo: { + paddingTop: '40px', + }, + square: { + width: '24px', + height: '24px', + background: 'rgba(8, 30, 6, .87)', + }, + title: { + paddingTop: '40px', + fontSize: '52px', + color: '#253727', + }, + subtitle: { + fontSize: '20px', + lineHeight: '27px', + color: '#425655', + paddingTop: '15px', + fontWeight: '300', + width: '320px', + }, + star: { + paddingTop: '20px', + }, + + chrome: { + paddingTop: '40px', + }, + over: { + position: 'absolute', + marginTop: '40px', + }, + + under: { + paddingTop: '100px', + }, }, }; } @@ -19,9 +68,40 @@ class HomeFeature extends ReactCSS.Component { render() { return (
- - Feature - +
+ + +
+
+
+
+
React Color
+
A Collection of Color Pickers from Sketch, Photoshop, Chrome & more
+
+ +
+
+
+ +
+ +
+ +
+ +
+
+ +
+
+
+ +
+
+ + Other Color Pickers + +
); } diff --git a/docs/images/bg-2.jpg b/docs/images/bg-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ef56e844555dfe3f76adb39eaaa47ade3dd5a448 GIT binary patch literal 124548 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 Qkt+7--WU>p{%hp_0HjCdHvj+t literal 0 HcmV?d00001 diff --git a/modules/react-basic-layout/components/Grid.jsx b/modules/react-basic-layout/components/Grid.jsx index e4fadc3e..2331def1 100644 --- a/modules/react-basic-layout/components/Grid.jsx +++ b/modules/react-basic-layout/components/Grid.jsx @@ -19,6 +19,28 @@ class Grid extends ReactCSS.Component { paddingLeft: '150px', }, }, + 'preset-one': { + left: { + width: 'auto', + position: 'relative', + paddingRight: '260px', + }, + main: { + position: 'absolute', + right: '0', + top: '0', + width: '225px', + }, + }, + 'preset-two': { + left: { + width: '220px', + position: 'absolute', + }, + main: { + paddingLeft: '267px', + }, + }, }; } diff --git a/src/components/Color.js b/src/components/Color.js index 2f4f49a7..776bb9d2 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -9,14 +9,14 @@ var Chrome = require('./chrome/Chrome'); class ColorPicker extends ReactCSS.Component { - constructor() { + constructor(props) { super(); this.state = { - h: 272, - s: 99, - l: 54, - a: 32, + h: 149, + s: 23, + l: 47, + a: 100, }; this.handleChange = this.handleChange.bind(this); @@ -35,9 +35,17 @@ class ColorPicker extends ReactCSS.Component { } render() { - return ( - - ); + var picker = ; + + if (this.props.type === 'sketch') { + picker = ; + } else if (this.props.type === 'photoshop') { + picker = ; + } else if (this.props.type === 'chrome') { + picker = ; + } + + return picker; } } diff --git a/src/components/chrome/Chrome.jsx b/src/components/chrome/Chrome.jsx index 8afc4fd6..873817ca 100644 --- a/src/components/chrome/Chrome.jsx +++ b/src/components/chrome/Chrome.jsx @@ -37,6 +37,7 @@ class Chrome extends ReactCSS.Component { paddingBottom: '55%', position: 'relative', borderRadius: '2px 2px 0 0', + overflow: 'hidden', }, Saturation: { radius: '2px 2px 0 0', diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index 3d4ebce3..577e91a7 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -60,7 +60,6 @@ class Hue extends ReactCSS.Component { var top = e.pageY - container.getBoundingClientRect().top; if (this.props.direction === 'vertical') { - console.log('change'); if (top > 0 && top < containerHeight) { var percent = -(top * 100 / containerHeight) + 100; var h = (360 * percent / 100); diff --git a/src/components/photoshop/Photoshop.jsx b/src/components/photoshop/Photoshop.jsx index 9e490035..426da54b 100644 --- a/src/components/photoshop/Photoshop.jsx +++ b/src/components/photoshop/Photoshop.jsx @@ -26,6 +26,7 @@ class PhotoshopPicker extends ReactCSS.Component { background: '#DCDCDC', borderRadius: '4px', boxShadow: '0 0 0 1px rgba(0,0,0,.25), 0 8px 16px rgba(0,0,0,.15)', + width: '513px', }, head: { backgroundImage: 'linear-gradient(-180deg, #F0F0F0 0%, #D4D4D4 100%)', From 4d78d09da83bf93ad76b8274cd6c6cc78254973f Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 01:42:40 -0400 Subject: [PATCH 031/119] Swatches theme --- docs/components/home/HomeFeature.jsx | 45 +++++++++ .../react-basic-layout/components/Grid.jsx | 9 ++ src/components/Color.js | 9 +- src/components/swatches/Swatches.jsx | 92 +++++++++++++++++++ src/components/swatches/SwatchesColor.jsx | 68 ++++++++++++++ src/components/swatches/SwatchesGroup.jsx | 50 ++++++++++ 6 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 src/components/swatches/Swatches.jsx create mode 100644 src/components/swatches/SwatchesColor.jsx create mode 100644 src/components/swatches/SwatchesGroup.jsx diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index e86b9265..2f7c6b22 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -61,6 +61,29 @@ class HomeFeature extends ReactCSS.Component { under: { paddingTop: '100px', }, + + tempPadding: { + height: '100px', + }, + + slider: { + height: '50px', + overflow: 'hidden', + }, + + split: { + display: 'flex', + }, + compact: { + width: '240px', + height: '140px', + overflow: 'hidden', + }, + material: { + width: '141px', + height: '140px', + overflow: 'hidden', + }, }, }; } @@ -86,6 +109,28 @@ class HomeFeature extends ReactCSS.Component {
+ + +
+
+ +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
diff --git a/modules/react-basic-layout/components/Grid.jsx b/modules/react-basic-layout/components/Grid.jsx index 2331def1..7ee999f1 100644 --- a/modules/react-basic-layout/components/Grid.jsx +++ b/modules/react-basic-layout/components/Grid.jsx @@ -41,6 +41,15 @@ class Grid extends ReactCSS.Component { paddingLeft: '267px', }, }, + 'preset-three': { + left: { + width: '415px', + position: 'absolute', + }, + main: { + paddingLeft: '455px', + }, + }, }; } diff --git a/src/components/Color.js b/src/components/Color.js index 776bb9d2..a44b2f4b 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -6,6 +6,7 @@ var ReactCSS = require('reactcss'); var Photoshop = require('./photoshop/Photoshop'); var Sketch = require('./sketch/Sketch'); var Chrome = require('./chrome/Chrome'); +var Swatches = require('./swatches/Swatches'); class ColorPicker extends ReactCSS.Component { @@ -13,9 +14,9 @@ class ColorPicker extends ReactCSS.Component { super(); this.state = { - h: 149, - s: 23, - l: 47, + h: 174, + s: 100, + l: 29, a: 100, }; @@ -43,6 +44,8 @@ class ColorPicker extends ReactCSS.Component { picker = ; } else if (this.props.type === 'chrome') { picker = ; + } else if (this.props.type === 'swatches') { + picker = ; } return picker; diff --git a/src/components/swatches/Swatches.jsx b/src/components/swatches/Swatches.jsx new file mode 100644 index 00000000..f72bbe2b --- /dev/null +++ b/src/components/swatches/Swatches.jsx @@ -0,0 +1,92 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); +var material = require('material-colors'); + +var { Raised } = require('react-material-design'); +var SwatchesGroup = require('./SwatchesGroup'); + +class Swatches extends ReactCSS.Component { + + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + + classes() { + var rgb = tinycolor(this.props).toRgb(); + return { + 'default': { + picker: { + width: '320px', + height: '240px', + overflowY: 'scroll', + }, + body: { + padding: '16px 0 6px 16px', + }, + + clear: { + clear: 'both', + }, + }, + }; + } + + handleChange(data) { + var color = tinycolor(data); + if (color.isValid()) { + var hsl = color.toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } + } + + render() { + var hex = tinycolor(this.props).toHex(); + + var groups = []; + for (var group of this.props.colors) { + groups.push(); + } + + return ( + +
+
+ { groups } +
+
+
+ + ); + } + +} + +Swatches.defaultProps = { + colors: [ + [material.red['900'], material.red['700'], material.red['500'], material.red['300'], material.red['100']], + [material.pink['900'], material.pink['700'], material.pink['500'], material.pink['300'], material.pink['100']], + [material.purple['900'], material.purple['700'], material.purple['500'], material.purple['300'], material.purple['100']], + [material.deepPurple['900'], material.deepPurple['700'], material.deepPurple['500'], material.deepPurple['300'], material.deepPurple['100']], + [material.indigo['900'], material.indigo['700'], material.indigo['500'], material.indigo['300'], material.indigo['100']], + [material.blue['900'], material.blue['700'], material.blue['500'], material.blue['300'], material.blue['100']], + [material.lightBlue['900'], material.lightBlue['700'], material.lightBlue['500'], material.lightBlue['300'], material.lightBlue['100']], + [material.cyan['900'], material.cyan['700'], material.cyan['500'], material.cyan['300'], material.cyan['100']], + [material.teal['900'], material.teal['700'], material.teal['500'], material.teal['300'], material.teal['100']], + [material.green['900'], material.green['700'], material.green['500'], material.green['300'], material.green['100']], + [material.lightGreen['900'], material.lightGreen['700'], material.lightGreen['500'], material.lightGreen['300'], material.lightGreen['100']], + [material.lime['900'], material.lime['700'], material.lime['500'], material.lime['300'], material.lime['100']], + [material.yellow['900'], material.yellow['700'], material.yellow['500'], material.yellow['300'], material.yellow['100']], + [material.amber['900'], material.amber['700'], material.amber['500'], material.amber['300'], material.amber['100']], + [material.orange['900'], material.orange['700'], material.orange['500'], material.orange['300'], material.orange['100']], + [material.deepOrange['900'], material.deepOrange['700'], material.deepOrange['500'], material.deepOrange['300'], material.deepOrange['100']], + [material.brown['900'], material.brown['700'], material.brown['500'], material.brown['300'], material.brown['100']], + [material.blueGrey['900'], material.blueGrey['700'], material.blueGrey['500'], material.blueGrey['300'], material.blueGrey['100']], + ], +}; + +module.exports = Swatches; diff --git a/src/components/swatches/SwatchesColor.jsx b/src/components/swatches/SwatchesColor.jsx new file mode 100644 index 00000000..78206cf8 --- /dev/null +++ b/src/components/swatches/SwatchesColor.jsx @@ -0,0 +1,68 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class SwatchesColor extends ReactCSS.Component { + + constructor() { + super(); + + this.handleClick = this.handleClick.bind(this); + } + + classes() { + return { + 'default': { + color: { + width: '40px', + height: '24px', + cursor: 'pointer', + background: this.props.color, + marginBottom: '1px', + }, + check: { + fill: '#fff', + marginLeft: '8px', + opacity: '0', + }, + }, + 'first': { + color: { + overflow: 'hidden', + borderRadius: '2px 2px 0 0', + }, + }, + 'last': { + color: { + overflow: 'hidden', + borderRadius: '0 0 2px 2px', + }, + }, + active: { + check: { + opacity: '1', + }, + }, + }; + } + + handleClick() { + this.props.onClick(this.props.color); + } + + render() { + return ( +
+
+ + + +
+
+ ); + } + +} + +module.exports = SwatchesColor; diff --git a/src/components/swatches/SwatchesGroup.jsx b/src/components/swatches/SwatchesGroup.jsx new file mode 100644 index 00000000..d99623e2 --- /dev/null +++ b/src/components/swatches/SwatchesGroup.jsx @@ -0,0 +1,50 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +var SwatchesColor = require('./SwatchesColor'); + +class SwatchesGroup extends ReactCSS.Component { + + constructor() { + super(); + + this.handleClick = this.handleClick.bind(this); + } + + classes() { + return { + 'default': { + group: { + paddingBottom: '10px', + width: '40px', + float: 'left', + marginRight: '10px', + }, + }, + }; + } + + handleClick(data) { + this.props.onClick(data); + } + + render() { + var colors = []; + for (var i = 0; i < this.props.group.length; i++) { + var color = this.props.group[i]; + + colors.push(); + } + + return ( +
+ { colors } +
+ ); + } + +} + +module.exports = SwatchesGroup; From 7adc26586830bc3a87ba1f5436409f56e21e7290 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 02:25:08 -0400 Subject: [PATCH 032/119] `Slider` theme --- docs/components/home/HomeFeature.jsx | 3 +- src/components/Color.js | 3 ++ src/components/slider/Slider.jsx | 54 ++++++++++++++++++++ src/components/slider/SliderPointer.jsx | 31 +++++++++++ src/components/slider/SliderSwatch.jsx | 53 +++++++++++++++++++ src/components/slider/SliderSwatches.jsx | 65 ++++++++++++++++++++++++ 6 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 src/components/slider/Slider.jsx create mode 100644 src/components/slider/SliderPointer.jsx create mode 100644 src/components/slider/SliderSwatch.jsx create mode 100644 src/components/slider/SliderSwatches.jsx diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index 2f7c6b22..9a37ffa0 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -67,8 +67,7 @@ class HomeFeature extends ReactCSS.Component { }, slider: { - height: '50px', - overflow: 'hidden', + paddingBottom: '40px', }, split: { diff --git a/src/components/Color.js b/src/components/Color.js index a44b2f4b..5c3ad112 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -7,6 +7,7 @@ var Photoshop = require('./photoshop/Photoshop'); var Sketch = require('./sketch/Sketch'); var Chrome = require('./chrome/Chrome'); var Swatches = require('./swatches/Swatches'); +var Slider = require('./slider/Slider'); class ColorPicker extends ReactCSS.Component { @@ -46,6 +47,8 @@ class ColorPicker extends ReactCSS.Component { picker = ; } else if (this.props.type === 'swatches') { picker = ; + } else if (this.props.type === 'slider') { + picker = ; } return picker; diff --git a/src/components/slider/Slider.jsx b/src/components/slider/Slider.jsx new file mode 100644 index 00000000..e88af5ef --- /dev/null +++ b/src/components/slider/Slider.jsx @@ -0,0 +1,54 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); + +var Hue = require('../common/Hue'); +var SliderSwatches = require('./SliderSwatches'); +var SliderPointer = require('./SliderPointer'); + +class Swatches extends ReactCSS.Component { + + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + + classes() { + return { + 'default': { + slider: { + }, + hue: { + height: '12px', + position: 'relative', + }, + Hue: { + radius: '2px', + }, + }, + }; + } + + handleChange(data) { + this.props.onChange(data); + } + + render() { + return ( +
+
+ +
+
+ +
+
+ ); + } + +} + +module.exports = Swatches; diff --git a/src/components/slider/SliderPointer.jsx b/src/components/slider/SliderPointer.jsx new file mode 100644 index 00000000..9ae0dee6 --- /dev/null +++ b/src/components/slider/SliderPointer.jsx @@ -0,0 +1,31 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class SliderPointer extends ReactCSS.Component { + + classes() { + return { + 'default': { + picker: { + width: '14px', + height: '14px', + borderRadius: '6px', + transform: 'translate(-7px, -1px)', + backgroundColor: 'rgb(248, 248, 248)', + boxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.37)', + }, + }, + }; + } + + render() { + return ( +
+ ); + } + +} + +module.exports = SliderPointer; diff --git a/src/components/slider/SliderSwatch.jsx b/src/components/slider/SliderSwatch.jsx new file mode 100644 index 00000000..d24b414a --- /dev/null +++ b/src/components/slider/SliderSwatch.jsx @@ -0,0 +1,53 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class SliderSwatch extends ReactCSS.Component { + + constructor() { + super(); + + this.handleClick = this.handleClick.bind(this); + } + + classes() { + return { + 'default': { + swatch: { + height: '12px', + background: 'hsl(' + this.props.h + ', 50%, ' + this.props.offset + '%)', + }, + }, + 'first': { + swatch: { + borderRadius: '2px 0 0 2px', + }, + }, + 'last': { + swatch: { + borderRadius: '0 2px 2px 0', + }, + }, + active: { + swatch: { + transform: 'scaleY(1.8)', + borderRadius: '3.6px/2px', + }, + }, + }; + } + + handleClick() { + this.props.onClick({ h: this.props.h, s: 50, l: this.props.offset }); + } + + render() { + return ( +
+ ); + } + +} + +module.exports = SliderSwatch; diff --git a/src/components/slider/SliderSwatches.jsx b/src/components/slider/SliderSwatches.jsx new file mode 100644 index 00000000..ca45a169 --- /dev/null +++ b/src/components/slider/SliderSwatches.jsx @@ -0,0 +1,65 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +var SliderSwatch = require('./SliderSwatch'); + +class SliderSwatches extends ReactCSS.Component { + + constructor() { + super(); + + this.handleClick = this.handleClick.bind(this); + } + + classes() { + return { + 'default': { + swatches: { + marginRight: '-4px', + marginTop: '20px', + }, + swatch: { + width: '19.65%', + marginRight: '1px', + float: 'left', + }, + clear: { + clear: 'both', + }, + }, + }; + } + + handleClick(data) { + this.props.onClick(data); + } + + render() { + console.log(this.props.l, this.props.s); + return ( +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ ); + } + +} + +module.exports = SliderSwatches; From ad28bb8e1a240002e399840fd97ee5b4bee901e5 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 03:10:44 -0400 Subject: [PATCH 033/119] `Material` theme --- docs/components/home/HomeFeature.jsx | 12 +- .../react-basic-layout/components/Grid.jsx | 3 +- src/components/Color.js | 3 + src/components/material/Material.jsx | 110 ++++++++++++++++++ 4 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 src/components/material/Material.jsx diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index 9a37ffa0..1cd28f0c 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -72,15 +72,15 @@ class HomeFeature extends ReactCSS.Component { split: { display: 'flex', + justifyContent: 'space-between', + alignItems: 'flex-end', + position: 'absolute', + bottom: '0', + width: '100%', }, compact: { width: '240px', - height: '140px', - overflow: 'hidden', - }, - material: { - width: '141px', - height: '140px', + height: '100px', overflow: 'hidden', }, }, diff --git a/modules/react-basic-layout/components/Grid.jsx b/modules/react-basic-layout/components/Grid.jsx index 7ee999f1..508a7532 100644 --- a/modules/react-basic-layout/components/Grid.jsx +++ b/modules/react-basic-layout/components/Grid.jsx @@ -43,8 +43,9 @@ class Grid extends ReactCSS.Component { }, 'preset-three': { left: { - width: '415px', + width: '410px', position: 'absolute', + height: '100%', }, main: { paddingLeft: '455px', diff --git a/src/components/Color.js b/src/components/Color.js index 5c3ad112..f3c80f25 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -8,6 +8,7 @@ var Sketch = require('./sketch/Sketch'); var Chrome = require('./chrome/Chrome'); var Swatches = require('./swatches/Swatches'); var Slider = require('./slider/Slider'); +var Material = require('./material/Material'); class ColorPicker extends ReactCSS.Component { @@ -49,6 +50,8 @@ class ColorPicker extends ReactCSS.Component { picker = ; } else if (this.props.type === 'slider') { picker = ; + } else if (this.props.type === 'material') { + picker = ; } return picker; diff --git a/src/components/material/Material.jsx b/src/components/material/Material.jsx new file mode 100644 index 00000000..7bdfe8ce --- /dev/null +++ b/src/components/material/Material.jsx @@ -0,0 +1,110 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); + +var { Raised } = require('react-material-design'); +var EditableInput = require('../common/EditableInput'); + +class Material extends ReactCSS.Component { + + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + + classes() { + return { + 'default': { + material: { + width: '98px', + height: '98px', + padding: '16px', + fontFamily: 'Roboto', + }, + Input: { + style: { + wrap: { + position: 'relative', + }, + input: { + width: '100%', + marginTop: '12px', + fontSize: '15px', + color: '#333', + padding: '0', + border: '0', + borderBottom: '1px solid #eee', + outline: 'none', + height: '30px', + }, + label: { + position: 'absolute', + top: '0', + left: '0', + fontSize: '11px', + color: '#999999', + textTransform: 'capitalize', + }, + }, + }, + split: { + display: 'flex', + marginRight: '-10px', + paddingTop: '12px', + }, + third: { + flex: '1', + paddingRight: '10px', + }, + }, + }; + } + + handleChange(data) { + if (data.hex) { + var color = tinycolor(data.hex); + if (color.isValid()) { + var hsl = color.toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } + } else if (data.r || data.g || data.b) { + var oldColor = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l}).toRgb(); + for (var key in data) { + oldColor[key] = Number(data[key]); + } + + var hsl = tinycolor(oldColor).toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } + } + + render() { + var rgb = tinycolor(this.props).toRgb(); + var hex = tinycolor(this.props).toHex(); + + return ( + +
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ ); + } + +} + +module.exports = Material; From 4ff8df51d3b7c8cf11c0b527ea8f77d02e644e43 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 03:31:48 -0400 Subject: [PATCH 034/119] Attempted Global Colors /: --- docs/components/home/HomeFeature.jsx | 28 +++++++++++++------ src/components/Color.js | 42 ++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index 1cd28f0c..153f5336 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -7,15 +7,21 @@ var ColorPicker = require('react-color'); var { Container, Grid } = require('react-basic-layout'); var { Raised } = require('react-material-design'); -var green = { - h: 122, - s: 39, - l: 49, - a: 100, -}; - class HomeFeature extends ReactCSS.Component { + constructor() { + super(); + + // this.state = { + // h: 174, + // s: 100, + // l: 29, + // a: 100, + // }; + + // this.handleChange = this.handleChange.bind(this); + } + classes() { return { 'default': { @@ -87,6 +93,12 @@ class HomeFeature extends ReactCSS.Component { }; } + // handleChange(data) { + // if (data !== this.state) { + // this.setState(data); + // } + // } + render() { return (
@@ -104,7 +116,7 @@ class HomeFeature extends ReactCSS.Component {
- +
diff --git a/src/components/Color.js b/src/components/Color.js index f3c80f25..46642513 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -16,6 +16,10 @@ class ColorPicker extends ReactCSS.Component { super(); this.state = { + // h: props.h, + // s: props.s, + // l: props.l, + // a: props.a, h: 174, s: 100, l: 29, @@ -34,24 +38,39 @@ class ColorPicker extends ReactCSS.Component { } handleChange(data) { - this.setState(data); + if (this.props.onChange) { + this.props.onChange(this.state); + } else { + this.setState(data); + } } + // componentWillReceiveProps(nextProps) { + // if (nextProps.h) { + // this.setState({ + // h: nextProps.h, + // s: nextProps.s, + // l: nextProps.l, + // a: nextProps.a, + // }); + // } + // } + render() { - var picker = ; + var picker = ; if (this.props.type === 'sketch') { - picker = ; + picker = ; } else if (this.props.type === 'photoshop') { - picker = ; + picker = ; } else if (this.props.type === 'chrome') { - picker = ; + picker = ; } else if (this.props.type === 'swatches') { - picker = ; + picker = ; } else if (this.props.type === 'slider') { - picker = ; + picker = ; } else if (this.props.type === 'material') { - picker = ; + picker = ; } return picker; @@ -59,4 +78,11 @@ class ColorPicker extends ReactCSS.Component { } +// ColorPicker.defaultProps = { +// h: 174, +// s: 100, +// l: 29, +// a: 100, +// }; + module.exports = ColorPicker; From be71ae6368b389e7600bcc5ab1502d9ba8145cb2 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 04:40:08 -0400 Subject: [PATCH 035/119] `Compact` theme --- docs/components/home/HomeFeature.jsx | 5 -- src/components/Color.js | 19 ++-- src/components/compact/Compact.jsx | 78 ++++++++++++++++ src/components/compact/CompactColor.jsx | 59 ++++++++++++ src/components/compact/CompactFields.jsx | 110 +++++++++++++++++++++++ src/components/sketch/Sketch.jsx | 9 +- src/components/slider/SliderSwatches.jsx | 1 - 7 files changed, 264 insertions(+), 17 deletions(-) create mode 100644 src/components/compact/Compact.jsx create mode 100644 src/components/compact/CompactColor.jsx create mode 100644 src/components/compact/CompactFields.jsx diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index 153f5336..002d0db1 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -84,11 +84,6 @@ class HomeFeature extends ReactCSS.Component { bottom: '0', width: '100%', }, - compact: { - width: '240px', - height: '100px', - overflow: 'hidden', - }, }, }; } diff --git a/src/components/Color.js b/src/components/Color.js index 46642513..fdb9f8ca 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -9,6 +9,7 @@ var Chrome = require('./chrome/Chrome'); var Swatches = require('./swatches/Swatches'); var Slider = require('./slider/Slider'); var Material = require('./material/Material'); +var Compact = require('./compact/Compact'); class ColorPicker extends ReactCSS.Component { @@ -57,23 +58,25 @@ class ColorPicker extends ReactCSS.Component { // } render() { - var picker = ; + var Picker = Sketch; if (this.props.type === 'sketch') { - picker = ; + Picker = Sketch; } else if (this.props.type === 'photoshop') { - picker = ; + Picker = Photoshop; } else if (this.props.type === 'chrome') { - picker = ; + Picker = Chrome; } else if (this.props.type === 'swatches') { - picker = ; + Picker = Swatches; } else if (this.props.type === 'slider') { - picker = ; + Picker = Slider; } else if (this.props.type === 'material') { - picker = ; + Picker = Material; + } else if (this.props.type === 'compact') { + Picker = Compact; } - return picker; + return ; } } diff --git a/src/components/compact/Compact.jsx b/src/components/compact/Compact.jsx new file mode 100644 index 00000000..995625f9 --- /dev/null +++ b/src/components/compact/Compact.jsx @@ -0,0 +1,78 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); + +var { Raised } = require('react-material-design'); +var CompactColor = require('./CompactColor'); +var CompactFields = require('./CompactFields'); + +class Compact extends ReactCSS.Component { + + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + + classes() { + return { + 'default': { + Compact: { + background: '#EBEBEB', + radius: '4px', + }, + compact: { + paddingTop: '5px', + paddingLeft: '5px', + width: '240px', + }, + + clear: { + clear: 'both', + }, + }, + }; + } + + handleChange(data) { + if (data.hex) { + var color = tinycolor(data.hex); + if (color.isValid()) { + var hsl = color.toHsl(); + this.props.onChange({ h: hsl.h, s: hsl.s, l: hsl.l }); + } + } + } + + render() { + var hex = tinycolor(this.props).toHex(); + + var colors = []; + for (var color of this.props.colors) { + colors.push(); + } + + return ( + +
+ { colors } +
+ +
+ + ); + } +} + +Compact.defaultProps = { + colors: ['#4D4D4D', '#999999', '#FFFFFF', '#F44E3B', '#FE9200', '#FCDC00', + '#DBDF00', '#A4DD00', '#68CCCA', '#73D8FF', '#AEA1FF', '#FDA1FF', + '#333333', '#808080', '#cccccc', '#D33115', '#E27300', '#FCC400', + '#B0BC00', '#68BC00', '#16A5A5', '#009CE0', '#7B64FF', '#FA28FF', + '#000000', '#666666', '#B3B3B3', '#9F0500', '#C45100', '#FB9E00', + '#808900', '#167D00', '#0C797D', '#0062B1', '#653294', '#AB149E',], +}; + +module.exports = Compact; diff --git a/src/components/compact/CompactColor.jsx b/src/components/compact/CompactColor.jsx new file mode 100644 index 00000000..ae195f2d --- /dev/null +++ b/src/components/compact/CompactColor.jsx @@ -0,0 +1,59 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +class CompactColor extends ReactCSS.Component { + + constructor() { + super(); + + this.handleClick = this.handleClick.bind(this); + } + + classes() { + return { + 'default': { + color: { + background: this.props.color, + width: '15px', + height: '15px', + float: 'left', + marginRight: '5px', + marginBottom: '5px', + position: 'relative', + }, + dot: { + Absolute: '5px 5px 5px 5px', + background: '#fff', + borderRadius: '50%', + opacity: '0', + }, + }, + 'active': { + dot: { + opacity: '1', + }, + }, + 'color-#FFFFFF': { + dot: { + background: '#000', + }, + }, + }; + } + + handleClick() { + this.props.onClick({ hex: this.props.color }); + } + + render() { + return ( +
+
+
+ ); + } +} + +module.exports = CompactColor; diff --git a/src/components/compact/CompactFields.jsx b/src/components/compact/CompactFields.jsx new file mode 100644 index 00000000..42f52319 --- /dev/null +++ b/src/components/compact/CompactFields.jsx @@ -0,0 +1,110 @@ +'use strict'; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); + +var EditableInput = require('../common/EditableInput'); + +class CompactColor extends ReactCSS.Component { + + constructor() { + super(); + + this.handleChange = this.handleChange.bind(this); + } + + classes() { + var hex = tinycolor(this.props).toHex(); + + return { + 'default': { + fields: { + display: 'flex', + paddingBottom: '6px', + paddingRight: '5px', + position: 'relative', + }, + active: { + position: 'absolute', + top: '6px', + left: '5px', + height: '9px', + width: '9px', + background: '#' + hex, + }, + Hex: { + style: { + wrap: { + flex: '6', + position: 'relative', + }, + input: { + width: '80%', + padding: '0', + paddingLeft: '20%', + border: 'none', + outline: 'none', + background: 'none', + fontSize: '12px', + color: '#333', + height: '16px', + }, + label: { + display: 'none', + }, + }, + }, + RGB: { + style: { + wrap: { + flex: '3', + position: 'relative', + }, + input: { + width: '70%', + padding: '0', + paddingLeft: '30%', + border: 'none', + outline: 'none', + background: 'none', + fontSize: '12px', + color: '#333', + height: '16px', + }, + label: { + position: 'absolute', + top: '3px', + left: '0', + lineHeight: '16px', + textTransform: 'uppercase', + fontSize: '12px', + color: '#999', + }, + }, + }, + }, + }; + } + + handleChange(data) { + this.props.onChange(data); + } + + render() { + var hex = tinycolor(this.props).toHex(); + var rgb = tinycolor(this.props).toRgb(); + + return ( +
+
+ + + + +
+ ); + } +} + +module.exports = CompactColor; diff --git a/src/components/sketch/Sketch.jsx b/src/components/sketch/Sketch.jsx index fdce807c..f32cd292 100644 --- a/src/components/sketch/Sketch.jsx +++ b/src/components/sketch/Sketch.jsx @@ -11,7 +11,7 @@ var SketchFields = require('./SketchFields'); var SketchPresetColors = require('./SketchPresetColors'); var Checkboard = require('../common/Checkboard'); -class ColorPicker extends ReactCSS.Component { +class Sketch extends ReactCSS.Component { constructor() { super(); @@ -119,7 +119,10 @@ class ColorPicker extends ReactCSS.Component {
); } - } -module.exports = ColorPicker; +Sketch.defaultProps = { + presetColors: ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#BD10E0', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF'], +}; + +module.exports = Sketch; diff --git a/src/components/slider/SliderSwatches.jsx b/src/components/slider/SliderSwatches.jsx index ca45a169..1e7a2055 100644 --- a/src/components/slider/SliderSwatches.jsx +++ b/src/components/slider/SliderSwatches.jsx @@ -37,7 +37,6 @@ class SliderSwatches extends ReactCSS.Component { } render() { - console.log(this.props.l, this.props.s); return (
From 5621ca00280947b460b60d75621c1e5dcd2e1275 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 04:58:32 -0400 Subject: [PATCH 036/119] Tweaks and unifying color! --- docs/components/home/Home.jsx | 7 ++++ docs/components/home/HomeFeature.jsx | 47 +++++++++-------------- src/components/Color.js | 6 +-- src/components/compact/Compact.jsx | 4 +- src/components/compact/CompactColor.jsx | 3 ++ src/components/material/Material.jsx | 32 ++++++++++++++- src/components/swatches/Swatches.jsx | 4 +- src/components/swatches/SwatchesGroup.jsx | 2 +- 8 files changed, 67 insertions(+), 38 deletions(-) diff --git a/docs/components/home/Home.jsx b/docs/components/home/Home.jsx index 189b0703..067786d0 100644 --- a/docs/components/home/Home.jsx +++ b/docs/components/home/Home.jsx @@ -21,6 +21,13 @@ module.exports = class Home extends ReactCSS.Component { render() { return (
+ + +
diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index 002d0db1..c1eb4640 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -68,12 +68,8 @@ class HomeFeature extends ReactCSS.Component { paddingTop: '100px', }, - tempPadding: { - height: '100px', - }, - slider: { - paddingBottom: '40px', + paddingTop: '20px', }, split: { @@ -115,28 +111,6 @@ class HomeFeature extends ReactCSS.Component {
- - -
-
- -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
@@ -150,7 +124,24 @@ class HomeFeature extends ReactCSS.Component {
- Other Color Pickers + +
+
+ +
+
+
+ +
+
+ +
+
+
+
+ +
+
diff --git a/src/components/Color.js b/src/components/Color.js index fdb9f8ca..036f31ca 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -21,9 +21,9 @@ class ColorPicker extends ReactCSS.Component { // s: props.s, // l: props.l, // a: props.a, - h: 174, - s: 100, - l: 29, + h: 150, + s: 50, + l: 20, a: 100, }; diff --git a/src/components/compact/Compact.jsx b/src/components/compact/Compact.jsx index 995625f9..8af9d420 100644 --- a/src/components/compact/Compact.jsx +++ b/src/components/compact/Compact.jsx @@ -20,7 +20,7 @@ class Compact extends ReactCSS.Component { return { 'default': { Compact: { - background: '#EBEBEB', + background: '#f6f6f6', radius: '4px', }, compact: { @@ -72,7 +72,7 @@ Compact.defaultProps = { '#333333', '#808080', '#cccccc', '#D33115', '#E27300', '#FCC400', '#B0BC00', '#68BC00', '#16A5A5', '#009CE0', '#7B64FF', '#FA28FF', '#000000', '#666666', '#B3B3B3', '#9F0500', '#C45100', '#FB9E00', - '#808900', '#167D00', '#0C797D', '#0062B1', '#653294', '#AB149E',], + '#808900', '#194D33', '#0C797D', '#0062B1', '#653294', '#AB149E',], }; module.exports = Compact; diff --git a/src/components/compact/CompactColor.jsx b/src/components/compact/CompactColor.jsx index ae195f2d..12ac717a 100644 --- a/src/components/compact/CompactColor.jsx +++ b/src/components/compact/CompactColor.jsx @@ -36,6 +36,9 @@ class CompactColor extends ReactCSS.Component { }, }, 'color-#FFFFFF': { + color: { + boxShadow: 'inset 0 0 0 1px #ddd', + }, dot: { background: '#000', }, diff --git a/src/components/material/Material.jsx b/src/components/material/Material.jsx index 7bdfe8ce..d163884d 100644 --- a/src/components/material/Material.jsx +++ b/src/components/material/Material.jsx @@ -16,6 +16,8 @@ class Material extends ReactCSS.Component { } classes() { + var hex = tinycolor(this.props).toHex(); + return { 'default': { material: { @@ -24,6 +26,32 @@ class Material extends ReactCSS.Component { padding: '16px', fontFamily: 'Roboto', }, + Hex: { + style: { + wrap: { + position: 'relative', + }, + input: { + width: '100%', + marginTop: '12px', + fontSize: '15px', + color: '#333', + padding: '0', + border: '0', + borderBottom: '2px solid #' + hex, + outline: 'none', + height: '30px', + }, + label: { + position: 'absolute', + top: '0', + left: '0', + fontSize: '11px', + color: '#999999', + textTransform: 'capitalize', + }, + }, + }, Input: { style: { wrap: { @@ -53,7 +81,7 @@ class Material extends ReactCSS.Component { split: { display: 'flex', marginRight: '-10px', - paddingTop: '12px', + paddingTop: '11px', }, third: { flex: '1', @@ -88,7 +116,7 @@ class Material extends ReactCSS.Component { return (
- +
diff --git a/src/components/swatches/Swatches.jsx b/src/components/swatches/Swatches.jsx index f72bbe2b..da05f45f 100644 --- a/src/components/swatches/Swatches.jsx +++ b/src/components/swatches/Swatches.jsx @@ -76,8 +76,8 @@ Swatches.defaultProps = { [material.blue['900'], material.blue['700'], material.blue['500'], material.blue['300'], material.blue['100']], [material.lightBlue['900'], material.lightBlue['700'], material.lightBlue['500'], material.lightBlue['300'], material.lightBlue['100']], [material.cyan['900'], material.cyan['700'], material.cyan['500'], material.cyan['300'], material.cyan['100']], - [material.teal['900'], material.teal['700'], material.teal['500'], material.teal['300'], material.teal['100']], - [material.green['900'], material.green['700'], material.green['500'], material.green['300'], material.green['100']], + [material.teal['900'], material.teal['700'], material.teal['500'], material.teal['300'], material.teal['100']], + ['#194D33', material.green['700'], material.green['500'], material.green['300'], material.green['100']], [material.lightGreen['900'], material.lightGreen['700'], material.lightGreen['500'], material.lightGreen['300'], material.lightGreen['100']], [material.lime['900'], material.lime['700'], material.lime['500'], material.lime['300'], material.lime['100']], [material.yellow['900'], material.yellow['700'], material.yellow['500'], material.yellow['300'], material.yellow['100']], diff --git a/src/components/swatches/SwatchesGroup.jsx b/src/components/swatches/SwatchesGroup.jsx index d99623e2..3b837f13 100644 --- a/src/components/swatches/SwatchesGroup.jsx +++ b/src/components/swatches/SwatchesGroup.jsx @@ -35,7 +35,7 @@ class SwatchesGroup extends ReactCSS.Component { for (var i = 0; i < this.props.group.length; i++) { var color = this.props.group[i]; - colors.push(); + colors.push(); } return ( From ae6f2433f4a7514dc5d54a4101bfb4e9b4eedd25 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 05:08:24 -0400 Subject: [PATCH 037/119] Labels --- docs/components/home/HomeFeature.jsx | 39 +++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index c1eb4640..3592f6cc 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -58,6 +58,22 @@ class HomeFeature extends ReactCSS.Component { chrome: { paddingTop: '40px', + position: 'relative', + }, + sketch: { + position: 'relative', + }, + photoshop: { + position: 'relative', + }, + compact: { + position: 'relative', + }, + material: { + position: 'relative', + }, + swatches: { + position: 'relative', }, over: { position: 'absolute', @@ -65,11 +81,12 @@ class HomeFeature extends ReactCSS.Component { }, under: { - paddingTop: '100px', + paddingTop: '110px', }, slider: { paddingTop: '20px', + position: 'relative', }, split: { @@ -80,6 +97,19 @@ class HomeFeature extends ReactCSS.Component { bottom: '0', width: '100%', }, + + label: { + textAlign: 'center', + position: 'absolute', + width: '100%', + color: 'rgba(0,0,0,.4)', + fontSize: '12px', + marginTop: '10px', + }, + whiteLabel: { + Extend: 'label', + color: 'rgba(255,255,255,.7)', + }, }, }; } @@ -108,15 +138,18 @@ class HomeFeature extends ReactCSS.Component {
+
Chrome
+
Sketch
+
Photoshop
@@ -128,18 +161,22 @@ class HomeFeature extends ReactCSS.Component {
+
Slider
+
Compact
+
Material
+
Swatches
From 32693893b55f0c57de345bffe714ae8ee8fa6b26 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 05:10:56 -0400 Subject: [PATCH 038/119] Sizing Tweaks --- docs/components/home/HomeFeature.jsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index 3592f6cc..44372b3c 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -40,7 +40,7 @@ class HomeFeature extends ReactCSS.Component { background: 'rgba(8, 30, 6, .87)', }, title: { - paddingTop: '40px', + paddingTop: '30px', fontSize: '52px', color: '#253727', }, @@ -53,7 +53,8 @@ class HomeFeature extends ReactCSS.Component { width: '320px', }, star: { - paddingTop: '20px', + paddingTop: '25px', + paddingBottom: '10px', }, chrome: { @@ -81,11 +82,11 @@ class HomeFeature extends ReactCSS.Component { }, under: { - paddingTop: '110px', + paddingTop: '125px', }, slider: { - paddingTop: '20px', + paddingTop: '10px', position: 'relative', }, From 5c22988bc908e130e3e2b6dbbbc36f777f6039d9 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 05:14:43 -0400 Subject: [PATCH 039/119] Sketch Slider Pointer Fix --- src/components/common/Alpha.jsx | 2 +- src/components/common/Hue.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index b1cb2956..d41f57da 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -49,7 +49,7 @@ class Alpha extends ReactCSS.Component { height: '8px', boxShadow: '0 0 2px rgba(0, 0, 0, .6)', background: '#fff', - top: '1px', + marginTop: '1px', transform: 'translateX(-2px)', }, }, diff --git a/src/components/common/Hue.jsx b/src/components/common/Hue.jsx index 577e91a7..884991de 100644 --- a/src/components/common/Hue.jsx +++ b/src/components/common/Hue.jsx @@ -31,7 +31,7 @@ class Hue extends ReactCSS.Component { left: (this.props.value * 100) / 360 + '%', }, slider: { - top: '1px', + marginTop: '1px', width: '4px', borderRadius: '1px', height: '8px', From b8f1cbd72c8e18f04bbf8077c62a1abbeabd8bf8 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 05:40:06 -0400 Subject: [PATCH 040/119] Throttle!!!!!!!!!!!! --- src/components/common/Saturation.jsx | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index 7e896cc0..b7da49db 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -3,12 +3,17 @@ var React = require('react'); var ReactCSS = require('reactcss'); var tinycolor = require('tinycolor2'); +var _ = require('lodash'); class Saturation extends ReactCSS.Component { constructor() { super(); + this.throttle = _.throttle(function(fn, data) { + fn(data); + }, 50); + this.handleChange = this.handleChange.bind(this); } @@ -48,42 +53,23 @@ class Saturation extends ReactCSS.Component { }; } - // componentDidMount() { - // var circle = React.findDOMNode(this.refs.circle); - // var hsv = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }).toHsv(); - // circle.style.top = -(hsv.v * 100) + 100 + '%'; - // circle.style.left = hsv.s * 100 + '%'; - // } - // - // componentWillReceiveProps(nextProps) { - // var circle = React.findDOMNode(this.refs.circle); - // var hsv = tinycolor({ h: nextProps.h, s: nextProps.s, l: nextProps.l }).toHsv(); - // circle.style.top = -(hsv.v * 100) + 100 + '%'; - // circle.style.left = hsv.s * 100 + '%'; - // } - handleChange(e) { var container = React.findDOMNode(this.refs.container); - - // var circle = React.findDOMNode(this.refs.circle); var containerWidth = container.clientWidth; var containerHeight = container.clientHeight; var left = e.pageX - container.getBoundingClientRect().left; var top = e.pageY - container.getBoundingClientRect().top; if (left > 0 && top > 0 && left < containerWidth && top < containerHeight) { - // circle.style.top = top + 'px'; - // circle.style.left = left + 'px'; var saturation = left * 100 / containerWidth; var bright = -(top * 100 / containerHeight) + 100; var computed = tinycolor({ h: this.props.h, s: saturation, v: bright }).toHsl(); if (this.props.h !== computed.h || this.props.s !== computed.s) { - this.props.onChange({ l: computed.l * 100, s: computed.s * 100 }); + this.throttle(this.props.onChange, { l: computed.l * 100, s: computed.s * 100 }); } } } render() { - var pointer =
; if (this.props.pointer) { @@ -101,7 +87,6 @@ class Saturation extends ReactCSS.Component {
); } - } module.exports = Saturation; From 43686c1b52211a0dce7eb131399b8e085db5fa21 Mon Sep 17 00:00:00 2001 From: case Date: Wed, 12 Aug 2015 06:08:51 -0400 Subject: [PATCH 041/119] `Saturation` client side stays visually up to date with the data backfill when done dragging --- src/components/common/Saturation.jsx | 61 ++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index b7da49db..36c4461a 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -7,25 +7,29 @@ var _ = require('lodash'); class Saturation extends ReactCSS.Component { - constructor() { + constructor(props) { super(); + this.state = props; + this.throttle = _.throttle(function(fn, data) { fn(data); }, 50); this.handleChange = this.handleChange.bind(this); + this.handleStart = this.handleStart.bind(this); + this.handleEnd = this.handleEnd.bind(this); } classes() { - var hsv = tinycolor({ h: this.props.h, s: this.props.s, l: this.props.l }).toHsv(); + var hsv = tinycolor({ h: this.state.h, s: this.state.s, l: this.state.l }).toHsv(); return { 'default': { color: { Absolute: '0 0 0 0', - background: 'hsl(' + this.props.h + ',100%, 50%)', - borderRadius: this.props.radius, + background: 'hsl(' + this.state.h + ',100%, 50%)', + borderRadius: this.state.radius, }, white: { Absolute: '0 0 0 0', @@ -34,7 +38,7 @@ class Saturation extends ReactCSS.Component { black: { Absolute: '0 0 0 0', background: 'linear-gradient(to top, #000, rgba(0,0,0,0))', - boxShadow: this.props.shadow, + boxShadow: this.state.shadow, }, pointer: { position: 'absolute', @@ -53,6 +57,27 @@ class Saturation extends ReactCSS.Component { }; } + componentWillReceiveProps(nextProps) { + var pointer = React.findDOMNode(this.refs.pointer); + + if (this.state.dragging) { + var pointer = React.findDOMNode(this.refs.pointer); + var hsv = tinycolor({ h: nextProps.h, s: nextProps.s, l: nextProps.l }).toHsv(); + pointer.style.top = -(hsv.v * 100) + 100 + '%'; + pointer.style.left = hsv.s * 100 + '%'; + + var next = {}; + for (var propName in nextProps) { + next[propName] = nextProps[propName]; + } + next.altState = false; + next.dragging = false; + this.setState({ altState: next }); + } else { + this.setState(nextProps); + } + } + handleChange(e) { var container = React.findDOMNode(this.refs.container); var containerWidth = container.clientWidth; @@ -62,25 +87,37 @@ class Saturation extends ReactCSS.Component { if (left > 0 && top > 0 && left < containerWidth && top < containerHeight) { var saturation = left * 100 / containerWidth; var bright = -(top * 100 / containerHeight) + 100; - var computed = tinycolor({ h: this.props.h, s: saturation, v: bright }).toHsl(); - if (this.props.h !== computed.h || this.props.s !== computed.s) { - this.throttle(this.props.onChange, { l: computed.l * 100, s: computed.s * 100 }); + var computed = tinycolor({ h: this.state.h, s: saturation, v: bright }).toHsl(); + if (this.state.h !== computed.h || this.state.s !== computed.s) { + this.throttle(this.state.onChange, { l: computed.l * 100, s: computed.s * 100 }); } } } + handleStart() { + this.setState({ dragging: true }); + } + + handleEnd() { + if (this.state.altState) { + this.setState(this.state.altState); + } else { + this.setState({ dragging: false }); + } + } + render() { - var pointer =
; + var pointer =
; - if (this.props.pointer) { - pointer = ; + if (this.state.pointer) { + pointer = ; } return (
-
+
{ pointer }
From 75f6356d0546d55f553a1564c04adf5cb5202d57 Mon Sep 17 00:00:00 2001 From: case Date: Thu, 13 Aug 2015 17:46:50 -0400 Subject: [PATCH 042/119] Basic documentation in! --- docs/components/home/HomeDocumentation.jsx | 8 +- docs/documentation/02-usage.md | 7 ++ docs/documentation/index.js | 1 + modules/react-docs/components/Code.jsx | 2 +- modules/react-docs/components/Docs.jsx | 107 +++++++++++++++++- modules/react-docs/components/Markdown.jsx | 2 +- modules/react-docs/components/Sidebar.jsx | 80 +++++++++++++ modules/react-docs/components/SidebarItem.jsx | 55 +++++++++ package.json | 3 + 9 files changed, 260 insertions(+), 5 deletions(-) create mode 100644 docs/documentation/02-usage.md create mode 100644 modules/react-docs/components/Sidebar.jsx create mode 100644 modules/react-docs/components/SidebarItem.jsx diff --git a/docs/components/home/HomeDocumentation.jsx b/docs/components/home/HomeDocumentation.jsx index 8e5652ec..1b49581a 100644 --- a/docs/components/home/HomeDocumentation.jsx +++ b/docs/components/home/HomeDocumentation.jsx @@ -14,6 +14,10 @@ class HomeDocumentation extends ReactCSS.Component { classes() { return { 'default': { + body: { + paddingTop: '50px', + paddingBottom: '50px', + }, }, }; } @@ -21,8 +25,8 @@ class HomeDocumentation extends ReactCSS.Component { render() { return (
- - Body + +
); diff --git a/docs/documentation/02-usage.md b/docs/documentation/02-usage.md new file mode 100644 index 00000000..b60b0339 --- /dev/null +++ b/docs/documentation/02-usage.md @@ -0,0 +1,7 @@ +--- +id: usage +title: Usage +--- +``` +npm install react-color +``` diff --git a/docs/documentation/index.js b/docs/documentation/index.js index 64ffa69c..c3730a9f 100644 --- a/docs/documentation/index.js +++ b/docs/documentation/index.js @@ -1,4 +1,5 @@ module.exports = { '01-about': require('./01-about.md'), + '02-usage': require('./02-usage.md'), }; diff --git a/modules/react-docs/components/Code.jsx b/modules/react-docs/components/Code.jsx index 9455fe0a..dcb9bbce 100644 --- a/modules/react-docs/components/Code.jsx +++ b/modules/react-docs/components/Code.jsx @@ -2,7 +2,7 @@ var React = require('react'); var ReactCSS = require('reactcss'); -var markdown = require('../../helpers/markdown'); +var markdown = require('../helpers/markdown'); var context = require('react-context'); var { Tile } = require('react-material-design'); diff --git a/modules/react-docs/components/Docs.jsx b/modules/react-docs/components/Docs.jsx index e82ac9ae..f1a9cbee 100644 --- a/modules/react-docs/components/Docs.jsx +++ b/modules/react-docs/components/Docs.jsx @@ -2,9 +2,28 @@ var React = require('react'); var ReactCSS = require('reactcss'); +var markdown = require('../helpers/markdown'); + +var { Grid } = require('react-basic-layout'); +var MarkdownTitle = require('./MarkdownTitle'); +var Markdown = require('./Markdown'); +var Code = require('./Code'); +var Sidebar = require('./Sidebar'); class Docs extends ReactCSS.Component { + constructor() { + super(); + this.state = { + sidebarFixed: false, + visible: false, + files: {}, + }; + this.changeSelection = this.changeSelection.bind(this); + this.attachSidebar = this.attachSidebar.bind(this); + this.handleScroll = this.handleScroll.bind(this); + } + classes() { return { 'default': { @@ -12,8 +31,94 @@ class Docs extends ReactCSS.Component { }; } + componentDidMount() { + window.addEventListener('scroll', this.handleScroll, false); + + var domFiles = React.findDOMNode(this.refs.files) && React.findDOMNode(this.refs.files).children; + + if (domFiles) { + var files = {}; + for (var i = 0; i < domFiles.length; i++) { + var file = domFiles[i]; + files[file.offsetTop] = file.id; + } + + this.setState({ files: files }); + } + } + + componentWillUnmount() { + window.removeEventListener('scroll', this.handleScroll, false); + } + + handleScroll(e) { + this.changeSelection(); + this.attachSidebar(); + } + + attachSidebar() { + var sidebarTop = React.findDOMNode(this.refs.sidebar).getBoundingClientRect().top; + + if (sidebarTop <= 0 && this.state.sidebarFixed === false) { + this.setState({ sidebarFixed: true }); + } + + if (sidebarTop > 0 && this.state.sidebarFixed === true) { + this.setState({ sidebarFixed: false }); + } + } + + changeSelection() { + var top = document.body.scrollTop - 300; + var mostVisible = ''; + + for (var offset in this.state.files) { + if (this.state.files.hasOwnProperty(offset)) { + var id = this.state.files[offset]; + if (offset < top) { + mostVisible = id; + } + } + } + + if (mostVisible !== this.state.visible) { + this.setState({ visible: mostVisible }); + } + } + render() { - return
docs
; + var markdownFiles = []; + + for (var fileName in this.props.markdown) { + if (this.props.markdown.hasOwnProperty(fileName)) { + var file = this.props.markdown[fileName]; + var args = markdown.getArgs(file); + var body = markdown.getBody(file); + + markdownFiles.push( +
+ + + + { body } +
+ ); + } + } + + return ( + +
+ +
+
+ { markdownFiles } +
+
+ ); } } diff --git a/modules/react-docs/components/Markdown.jsx b/modules/react-docs/components/Markdown.jsx index 1905e345..e8e04c81 100644 --- a/modules/react-docs/components/Markdown.jsx +++ b/modules/react-docs/components/Markdown.jsx @@ -2,7 +2,7 @@ var React = require('react'); var ReactCSS = require('reactcss'); -var markdown = require('../../helpers/markdown'); +var markdown = require('../helpers/markdown'); var Code = require('./Code'); diff --git a/modules/react-docs/components/Sidebar.jsx b/modules/react-docs/components/Sidebar.jsx new file mode 100644 index 00000000..1e050f6c --- /dev/null +++ b/modules/react-docs/components/Sidebar.jsx @@ -0,0 +1,80 @@ +/* jshint node: true, esnext: true */ +"use strict"; + +var React = require('react'); +var ReactCSS = require('reactcss'); +var markdown = require('../helpers/markdown'); + +var { Tile } = require('react-material-design'); +var SidebarItem = require('./SidebarItem'); + +module.exports = class Sidebar extends ReactCSS.Component { + + classes() { + return { + 'default': { + sidebar: { + paddingTop: '20px', + position: 'relative', + width: '100%', + maxWidth: '130px', + }, + star: { + display: 'none', + position: 'absolute', + }, + }, + 'fixed': { + sidebar: { + top: '0', + bottom: '0', + position: 'fixed', + }, + star: { + bottom: '30px', + top: 'auto', + display: 'block', + }, + }, + }; + } + + render() { + + var sidebarItems = []; + + for (var fileName in this.props.files) { + if (this.props.files.hasOwnProperty(fileName)) { + var file = this.props.files[fileName]; + var args = markdown.getArgs(file); + var sectionNumber; + if (markdown.isSubSection(fileName)) { + sectionNumber = fileName.split('-')[0]; + } else { + sectionNumber = false; + } + + sidebarItems.push( + + ); + } + } + + return ( +
+ +
+ +
+ + { sidebarItems } + +
+ ); + } +}; diff --git a/modules/react-docs/components/SidebarItem.jsx b/modules/react-docs/components/SidebarItem.jsx new file mode 100644 index 00000000..2f19fbc8 --- /dev/null +++ b/modules/react-docs/components/SidebarItem.jsx @@ -0,0 +1,55 @@ +/* jshint node: true, esnext: true */ +"use strict"; + +var React = require('react'); +var ReactCSS = require('reactcss'); + +var { Tile } = require('react-material-design'); + +module.exports = class SidebarItem extends ReactCSS.Component { + + classes() { + return { + 'default': { + sidebarItem: { + fontSize: '14px', + textDecoration: 'none', + color: 'rgba(0, 0, 0, .57)', + transition: 'all 200ms linear', + }, + number: { + fontSize: '14px', + color: 'rgba(0, 0, 0, .27)', + fontWeight: 'bold', + paddingTop: '14px', + }, + li: { + paddingBottom: '8px', + }, + }, + 'bold': { + sidebarItem: { + fontWeight: 'bold', + paddingTop: '14px', + display: 'block', + }, + }, + 'active': { + sidebarItem: { + color: 'rgba(255,255,255,.87)', + }, + }, + }; + } + + render() { + return ( +
+ +
{ this.props.sidebarNumber }
+ { this.props.label } +
+
+ ); + } +}; diff --git a/package.json b/package.json index 2ec50b30..dc4ee1c2 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "dependencies": { "install": "^0.1.8", "lodash": "^3.10.1", + "material-colors": "^1.0.0", "npm": "^2.13.4", "react": "^0.13.3", "reactcss": "^0.3.2", @@ -30,12 +31,14 @@ "css-loader": "^0.15.6", "gulp": "^3.9.0", "gulp-util": "^3.0.6", + "highlight.js": "^8.7.0", "html-loader": "^0.3.0", "jsx-loader": "^0.13.2", "normalize.css": "^3.0.3", "react-context": "0.0.1", "react-hot-loader": "^1.2.8", "react-map-styles": "^0.2.0", + "remarkable": "^1.6.0", "style-loader": "^0.12.3", "webpack": "^1.11.0", "webpack-dev-server": "^1.10.1" From fa9212955a1dec73ab203739e4fab22d6c8a5fc2 Mon Sep 17 00:00:00 2001 From: case Date: Thu, 13 Aug 2015 21:18:15 -0400 Subject: [PATCH 043/119] Central color + component data cleanup --- docs/components/home/HomeFeature.jsx | 58 ++++++++++-------- package.json | 1 + src/components/Color.js | 71 ++++++++++++++--------- src/components/Sketch/SketchFields.jsx | 5 +- src/components/chrome/Chrome.jsx | 2 +- src/components/chrome/ChromeFields.jsx | 10 ++-- src/components/common/Alpha.jsx | 4 +- src/components/common/Saturation.jsx | 3 +- src/components/sketch/Sketch.jsx | 2 +- src/components/slider/SliderSwatch.jsx | 4 +- src/components/slider/SliderSwatches.jsx | 10 ++-- src/components/swatches/SwatchesColor.jsx | 4 +- 12 files changed, 100 insertions(+), 74 deletions(-) diff --git a/docs/components/home/HomeFeature.jsx b/docs/components/home/HomeFeature.jsx index 44372b3c..1f8c41e3 100644 --- a/docs/components/home/HomeFeature.jsx +++ b/docs/components/home/HomeFeature.jsx @@ -12,14 +12,14 @@ class HomeFeature extends ReactCSS.Component { constructor() { super(); - // this.state = { - // h: 174, - // s: 100, - // l: 29, - // a: 100, - // }; - - // this.handleChange = this.handleChange.bind(this); + this.state = { + h: 150, + s: .50, + l: .20, + a: 1, + }; + + this.handleChange = this.handleChange.bind(this); } classes() { @@ -82,7 +82,7 @@ class HomeFeature extends ReactCSS.Component { }, under: { - paddingTop: '125px', + // paddingTop: '125px', }, slider: { @@ -115,16 +115,26 @@ class HomeFeature extends ReactCSS.Component { }; } - // handleChange(data) { - // if (data !== this.state) { - // this.setState(data); - // } - // } + handleChange(data) { + if (data.hsl !== this.state) { + this.setState(data.hsl); + } + } + + componentDidMount() { + var container = React.findDOMNode(this.refs.container); + var over = React.findDOMNode(this.refs.over); + var under = React.findDOMNode(this.refs.under); + var containerHeight = container.getBoundingClientRect().top + container.clientHeight; + var overHeight = over.getBoundingClientRect().top + over.clientHeight; + + under.style.paddingTop = overHeight - containerHeight + 50 + 'px'; + } render() { return (
-
+
@@ -138,45 +148,45 @@ class HomeFeature extends ReactCSS.Component {
- +
Chrome
-
+
- +
Sketch
- +
Photoshop
-
+
- +
Slider
- +
Compact
- +
Material
- +
Swatches
diff --git a/package.json b/package.json index dc4ee1c2..d5603e22 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "install": "^0.1.8", "lodash": "^3.10.1", "material-colors": "^1.0.0", + "merge": "^1.2.0", "npm": "^2.13.4", "react": "^0.13.3", "reactcss": "^0.3.2", diff --git a/src/components/Color.js b/src/components/Color.js index 036f31ca..9bda5d9d 100644 --- a/src/components/Color.js +++ b/src/components/Color.js @@ -2,6 +2,8 @@ var React = require('react'); var ReactCSS = require('reactcss'); +var tinycolor = require('tinycolor2'); +var merge = require('merge'); var Photoshop = require('./photoshop/Photoshop'); var Sketch = require('./sketch/Sketch'); @@ -11,21 +13,23 @@ var Slider = require('./slider/Slider'); var Material = require('./material/Material'); var Compact = require('./compact/Compact'); +var toHsl = function(data) { + if (data.h) { + return { + h: data.h, + s: data.s, + l: data.l, + a: data.a, + }; + } +}; + class ColorPicker extends ReactCSS.Component { constructor(props) { super(); - this.state = { - // h: props.h, - // s: props.s, - // l: props.l, - // a: props.a, - h: 150, - s: 50, - l: 20, - a: 100, - }; + this.state = toHsl(props.color); this.handleChange = this.handleChange.bind(this); } @@ -39,23 +43,30 @@ class ColorPicker extends ReactCSS.Component { } handleChange(data) { + this.setState(data); + if (this.props.onChange) { - this.props.onChange(this.state); - } else { - this.setState(data); + var color = tinycolor(merge(this.state, data)); + + var newData = { + hsl: color.toHsl(), + rgb: color.toRgb(), + hex: color.toHex(), + }; + + newData.hsl.h = Math.round(newData.hsl.h * 100) / 100; + newData.hsl.s = Math.round(newData.hsl.s * 100) / 100; + newData.hsl.l = Math.round(newData.hsl.l * 100) / 100; + + this.props.onChange(newData); } } - // componentWillReceiveProps(nextProps) { - // if (nextProps.h) { - // this.setState({ - // h: nextProps.h, - // s: nextProps.s, - // l: nextProps.l, - // a: nextProps.a, - // }); - // } - // } + componentWillReceiveProps(nextProps) { + if (this.state !== nextProps.color) { + this.setState(toHsl(nextProps.color)); + } + } render() { var Picker = Sketch; @@ -81,11 +92,13 @@ class ColorPicker extends ReactCSS.Component { } -// ColorPicker.defaultProps = { -// h: 174, -// s: 100, -// l: 29, -// a: 100, -// }; +ColorPicker.defaultProps = { + color: { + h: 250, + s: .50, + l: .20, + a: 1, + }, +}; module.exports = ColorPicker; diff --git a/src/components/Sketch/SketchFields.jsx b/src/components/Sketch/SketchFields.jsx index c3ac4c6f..a5e27a7f 100644 --- a/src/components/Sketch/SketchFields.jsx +++ b/src/components/Sketch/SketchFields.jsx @@ -73,7 +73,8 @@ class ShetchFields extends ReactCSS.Component { } else if (data.a > 100) { data.a = 100; } - + + data.a = data.a / 100; this.props.onChange(data); } } @@ -96,7 +97,7 @@ class ShetchFields extends ReactCSS.Component {
- +
); diff --git a/src/components/chrome/Chrome.jsx b/src/components/chrome/Chrome.jsx index 873817ca..680f0216 100644 --- a/src/components/chrome/Chrome.jsx +++ b/src/components/chrome/Chrome.jsx @@ -64,7 +64,7 @@ class Chrome extends ReactCSS.Component { zIndex: 2, borderRadius: '8px', boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.1)', - background: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + (this.props.a / 100) + ')', + background: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + this.props.a + ')', }, toggles: { flex: '1', diff --git a/src/components/chrome/ChromeFields.jsx b/src/components/chrome/ChromeFields.jsx index c05093fb..2e01ccde 100644 --- a/src/components/chrome/ChromeFields.jsx +++ b/src/components/chrome/ChromeFields.jsx @@ -177,22 +177,22 @@ class ChromeFields extends ReactCSS.Component {
- +
; } else if (this.state.view === 'hsl') { fields =
- +
- +
- +
- +
; } diff --git a/src/components/common/Alpha.jsx b/src/components/common/Alpha.jsx index d41f57da..c60ac84d 100644 --- a/src/components/common/Alpha.jsx +++ b/src/components/common/Alpha.jsx @@ -41,7 +41,7 @@ class Alpha extends ReactCSS.Component { pointer: { zIndex: '2', position: 'absolute', - left: this.props.a + '%', + left: this.props.a * 100 + '%', }, slider: { width: '4px', @@ -61,7 +61,7 @@ class Alpha extends ReactCSS.Component { var containerWidth = container.clientWidth; var left = e.pageX - container.getBoundingClientRect().left; if (left >= 0 && left <= containerWidth) { - var percent = Math.round(left * 100 / containerWidth); + var percent = Math.round(left * 100 / containerWidth) / 100; if (this.props.a !== percent) { this.props.onChange({ a: percent }); } diff --git a/src/components/common/Saturation.jsx b/src/components/common/Saturation.jsx index 36c4461a..418799cd 100644 --- a/src/components/common/Saturation.jsx +++ b/src/components/common/Saturation.jsx @@ -70,6 +70,7 @@ class Saturation extends ReactCSS.Component { for (var propName in nextProps) { next[propName] = nextProps[propName]; } + next.altState = false; next.dragging = false; this.setState({ altState: next }); @@ -89,7 +90,7 @@ class Saturation extends ReactCSS.Component { var bright = -(top * 100 / containerHeight) + 100; var computed = tinycolor({ h: this.state.h, s: saturation, v: bright }).toHsl(); if (this.state.h !== computed.h || this.state.s !== computed.s) { - this.throttle(this.state.onChange, { l: computed.l * 100, s: computed.s * 100 }); + this.throttle(this.state.onChange, { l: Math.round(computed.l * 100), s: Math.round(computed.s * 100) }); } } } diff --git a/src/components/sketch/Sketch.jsx b/src/components/sketch/Sketch.jsx index f32cd292..5cb478a5 100644 --- a/src/components/sketch/Sketch.jsx +++ b/src/components/sketch/Sketch.jsx @@ -58,7 +58,7 @@ class Sketch extends ReactCSS.Component { activeColor: { Absolute: '0 0 0 0', borderRadius: '2px', - background: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + (this.props.a / 100) + ')', + background: 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + this.props.a + ')', boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)', zIndex: '2', }, diff --git a/src/components/slider/SliderSwatch.jsx b/src/components/slider/SliderSwatch.jsx index d24b414a..a63b2b62 100644 --- a/src/components/slider/SliderSwatch.jsx +++ b/src/components/slider/SliderSwatch.jsx @@ -16,7 +16,7 @@ class SliderSwatch extends ReactCSS.Component { 'default': { swatch: { height: '12px', - background: 'hsl(' + this.props.h + ', 50%, ' + this.props.offset + '%)', + background: 'hsl(' + this.props.h + ', 50%, ' + (this.props.offset * 100) + '%)', }, }, 'first': { @@ -39,7 +39,7 @@ class SliderSwatch extends ReactCSS.Component { } handleClick() { - this.props.onClick({ h: this.props.h, s: 50, l: this.props.offset }); + this.props.onClick({ h: this.props.h, s: .5, l: this.props.offset }); } render() { diff --git a/src/components/slider/SliderSwatches.jsx b/src/components/slider/SliderSwatches.jsx index 1e7a2055..885364dc 100644 --- a/src/components/slider/SliderSwatches.jsx +++ b/src/components/slider/SliderSwatches.jsx @@ -40,19 +40,19 @@ class SliderSwatches extends ReactCSS.Component { return (
- +
- +
- +
- +
- +
diff --git a/src/components/swatches/SwatchesColor.jsx b/src/components/swatches/SwatchesColor.jsx index 78206cf8..aa2b9434 100644 --- a/src/components/swatches/SwatchesColor.jsx +++ b/src/components/swatches/SwatchesColor.jsx @@ -24,7 +24,7 @@ class SwatchesColor extends ReactCSS.Component { check: { fill: '#fff', marginLeft: '8px', - opacity: '0', + display: 'none', }, }, 'first': { @@ -41,7 +41,7 @@ class SwatchesColor extends ReactCSS.Component { }, active: { check: { - opacity: '1', + display: 'block', }, }, }; From 134f22c78560be2f95b69c14233c017f2dd851fe Mon Sep 17 00:00:00 2001 From: case Date: Fri, 14 Aug 2015 03:20:53 -0400 Subject: [PATCH 044/119] Tweaks --- src/components/chrome/ChromeFields.jsx | 6 +++--- src/components/slider/SliderSwatch.jsx | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/chrome/ChromeFields.jsx b/src/components/chrome/ChromeFields.jsx index 2e01ccde..1b52ac43 100644 --- a/src/components/chrome/ChromeFields.jsx +++ b/src/components/chrome/ChromeFields.jsx @@ -12,7 +12,7 @@ class ChromeFields extends ReactCSS.Component { super(); this.state = { - view: 'hex', + view: '', }; this.handleChange = this.handleChange.bind(this); @@ -92,7 +92,7 @@ class ChromeFields extends ReactCSS.Component { } componentDidMount() { - if (this.props.a === 100 && this.state.view !== 'hex') { + if (this.props.a === 1 && this.state.view !== 'hex') { this.setState({ view: 'hex' }); } else if (this.state.view !== 'rgb' && this.state.view !== 'hsl') { this.setState({ view: 'rgb' }); @@ -105,7 +105,7 @@ class ChromeFields extends ReactCSS.Component { } else if (this.state.view === 'rgb') { this.setState({ view: 'hsl' }); } else if (this.state.view === 'hsl') { - if (this.props.a === 100) { + if (this.props.a === 1) { this.setState({ view: 'hex' }); } else { this.setState({ view: 'rgb' }); diff --git a/src/components/slider/SliderSwatch.jsx b/src/components/slider/SliderSwatch.jsx index a63b2b62..f7398cc5 100644 --- a/src/components/slider/SliderSwatch.jsx +++ b/src/components/slider/SliderSwatch.jsx @@ -17,6 +17,7 @@ class SliderSwatch extends ReactCSS.Component { swatch: { height: '12px', background: 'hsl(' + this.props.h + ', 50%, ' + (this.props.offset * 100) + '%)', + cursor: 'pointer', }, }, 'first': { From 0c28d4af2d557b295484b819b2d7cf7e20f84dfe Mon Sep 17 00:00:00 2001 From: case Date: Fri, 14 Aug 2015 03:29:28 -0400 Subject: [PATCH 045/119] Web pack Build --- gulpfile.js | 25 +++++++++++++++++++++++++ webpack.config.js | 4 ++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 077f6dd6..9865dec8 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,6 +10,9 @@ gulp.task('docs', function(callback) { docs.entry = ['webpack-dev-server/client?http://localhost:' + port, 'webpack/hot/dev-server', docs.entry[0]]; + docs.module.loaders[0].loaders.unshift('react-hot-loader'); + docs.module.loaders[1].loaders.unshift('react-hot-loader'); + docs.devtool = 'eval'; docs.debug = true; @@ -27,3 +30,25 @@ gulp.task('docs', function(callback) { gutil.log('[webpack-dev-server]', 'http://localhost:' + port + '/'); }); }); + +gulp.task('build', function(done) { + + var build = Object.create(webpackConfig); + + build.plugins = [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('production'), + }, + }), + new webpack.optimize.DedupePlugin(), + ]; + + webpack(build, function(err, stats) { + if (err) { + throw new Error(err); + } + + done(); + }); +}); diff --git a/webpack.config.js b/webpack.config.js index d81ef893..554faae7 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -13,11 +13,11 @@ module.exports = { { test: /\.js$/, exclude: /node_modules/, - loaders: ['react-hot-loader', 'babel-loader'], + loaders: ['babel-loader'], }, { test: /\.jsx$/, exclude: /node_modules/, - loaders: ['react-hot-loader', 'jsx-loader', 'babel-loader', 'react-map-styles'], + loaders: ['jsx-loader', 'babel-loader', 'react-map-styles'], }, { test: /\.css$/, loaders: ['style-loader', 'css-loader'], From d414f866995ab37471260d277dc5682396cf62e4 Mon Sep 17 00:00:00 2001 From: case Date: Fri, 14 Aug 2015 03:30:10 -0400 Subject: [PATCH 046/119] Build --- build/bundle.js | 63692 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63692 insertions(+) create mode 100644 build/bundle.js diff --git a/build/bundle.js b/build/bundle.js new file mode 100644 index 00000000..b53a36ef --- /dev/null +++ b/build/bundle.js @@ -0,0 +1,63692 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = "build/"; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ((function(modules) { + // Check all modules for deduplicated modules + for(var i in modules) { + if(Object.prototype.hasOwnProperty.call(modules, i)) { + switch(typeof modules[i]) { + case "function": break; + case "object": + // Module can be created from a template + modules[i] = (function(_m) { + var args = _m.slice(1), fn = modules[_m[0]]; + return function (a,b,c) { + fn.apply(this, [a,b,c].concat(args)); + }; + }(modules[i])); + break; + default: + // Module is a copy of another module + modules[i] = modules[modules[i]]; + break; + } + } + } + return modules; +}([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__(1); + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var React = __webpack_require__(2); + __webpack_require__(153); + + var Home = __webpack_require__(157); + + React.render(React.createElement(Home), document.getElementById('root')); + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__(3); + + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule React + */ + + /* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ + + 'use strict'; + + var EventPluginUtils = __webpack_require__(4); + var ReactChildren = __webpack_require__(8); + var ReactComponent = __webpack_require__(22); + var ReactClass = __webpack_require__(37); + var ReactContext = __webpack_require__(12); + var ReactCurrentOwner = __webpack_require__(17); + var ReactElement = __webpack_require__(11); + var ReactElementValidator = __webpack_require__(32); + var ReactDOM = __webpack_require__(40); + var ReactDOMTextComponent = __webpack_require__(42); + var ReactDefaultInjection = __webpack_require__(91); + var ReactInstanceHandles = __webpack_require__(19); + var ReactMount = __webpack_require__(67); + var ReactPerf = __webpack_require__(28); + var ReactPropTypes = __webpack_require__(122); + var ReactReconciler = __webpack_require__(29); + var ReactServerRendering = __webpack_require__(150); + + var assign = __webpack_require__(13); + var findDOMNode = __webpack_require__(111); + var onlyChild = __webpack_require__(152); + + ReactDefaultInjection.inject(); + + var createElement = ReactElement.createElement; + var createFactory = ReactElement.createFactory; + var cloneElement = ReactElement.cloneElement; + + if (false) { + createElement = ReactElementValidator.createElement; + createFactory = ReactElementValidator.createFactory; + cloneElement = ReactElementValidator.cloneElement; + } + + var render = ReactPerf.measure('React', 'render', ReactMount.render); + + var React = { + Children: { + map: ReactChildren.map, + forEach: ReactChildren.forEach, + count: ReactChildren.count, + only: onlyChild + }, + Component: ReactComponent, + DOM: ReactDOM, + PropTypes: ReactPropTypes, + initializeTouchEvents: function(shouldUseTouch) { + EventPluginUtils.useTouchEvents = shouldUseTouch; + }, + createClass: ReactClass.createClass, + createElement: createElement, + cloneElement: cloneElement, + createFactory: createFactory, + createMixin: function(mixin) { + // Currently a noop. Will be used to validate and trace mixins. + return mixin; + }, + constructAndRenderComponent: ReactMount.constructAndRenderComponent, + constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID, + findDOMNode: findDOMNode, + render: render, + renderToString: ReactServerRendering.renderToString, + renderToStaticMarkup: ReactServerRendering.renderToStaticMarkup, + unmountComponentAtNode: ReactMount.unmountComponentAtNode, + isValidElement: ReactElement.isValidElement, + withContext: ReactContext.withContext, + + // Hook for JSX spread, don't use this for anything else. + __spread: assign + }; + + // Inject the runtime into a devtools global hook regardless of browser. + // Allows for debugging when the hook is injected on the page. + if ( + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { + __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ + CurrentOwner: ReactCurrentOwner, + InstanceHandles: ReactInstanceHandles, + Mount: ReactMount, + Reconciler: ReactReconciler, + TextComponent: ReactDOMTextComponent + }); + } + + if (false) { + var ExecutionEnvironment = require("./ExecutionEnvironment"); + if (ExecutionEnvironment.canUseDOM && window.top === window.self) { + + // If we're in Chrome, look for the devtools marker and provide a download + // link if not installed. + if (navigator.userAgent.indexOf('Chrome') > -1) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { + console.debug( + 'Download the React DevTools for a better development experience: ' + + 'https://fb.me/react-devtools' + ); + } + } + + var expectedFeatures = [ + // shims + Array.isArray, + Array.prototype.every, + Array.prototype.forEach, + Array.prototype.indexOf, + Array.prototype.map, + Date.now, + Function.prototype.bind, + Object.keys, + String.prototype.split, + String.prototype.trim, + + // shams + Object.create, + Object.freeze + ]; + + for (var i = 0; i < expectedFeatures.length; i++) { + if (!expectedFeatures[i]) { + console.error( + 'One or more ES5 shim/shams expected by React are not available: ' + + 'https://fb.me/react-warning-polyfills' + ); + break; + } + } + } + } + + React.version = '0.13.3'; + + module.exports = React; + + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule EventPluginUtils + */ + + 'use strict'; + + var EventConstants = __webpack_require__(5); + + var invariant = __webpack_require__(7); + + /** + * Injected dependencies: + */ + + /** + * - `Mount`: [required] Module that can convert between React dom IDs and + * actual node references. + */ + var injection = { + Mount: null, + injectMount: function(InjectedMount) { + injection.Mount = InjectedMount; + if (false) { + ("production" !== process.env.NODE_ENV ? invariant( + InjectedMount && InjectedMount.getNode, + 'EventPluginUtils.injection.injectMount(...): Injected Mount module ' + + 'is missing getNode.' + ) : invariant(InjectedMount && InjectedMount.getNode)); + } + } + }; + + var topLevelTypes = EventConstants.topLevelTypes; + + function isEndish(topLevelType) { + return topLevelType === topLevelTypes.topMouseUp || + topLevelType === topLevelTypes.topTouchEnd || + topLevelType === topLevelTypes.topTouchCancel; + } + + function isMoveish(topLevelType) { + return topLevelType === topLevelTypes.topMouseMove || + topLevelType === topLevelTypes.topTouchMove; + } + function isStartish(topLevelType) { + return topLevelType === topLevelTypes.topMouseDown || + topLevelType === topLevelTypes.topTouchStart; + } + + + var validateEventDispatches; + if (false) { + validateEventDispatches = function(event) { + var dispatchListeners = event._dispatchListeners; + var dispatchIDs = event._dispatchIDs; + + var listenersIsArr = Array.isArray(dispatchListeners); + var idsIsArr = Array.isArray(dispatchIDs); + var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0; + var listenersLen = listenersIsArr ? + dispatchListeners.length : + dispatchListeners ? 1 : 0; + + ("production" !== process.env.NODE_ENV ? invariant( + idsIsArr === listenersIsArr && IDsLen === listenersLen, + 'EventPluginUtils: Invalid `event`.' + ) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen)); + }; + } + + /** + * Invokes `cb(event, listener, id)`. Avoids using call if no scope is + * provided. The `(listener,id)` pair effectively forms the "dispatch" but are + * kept separate to conserve memory. + */ + function forEachEventDispatch(event, cb) { + var dispatchListeners = event._dispatchListeners; + var dispatchIDs = event._dispatchIDs; + if (false) { + validateEventDispatches(event); + } + if (Array.isArray(dispatchListeners)) { + for (var i = 0; i < dispatchListeners.length; i++) { + if (event.isPropagationStopped()) { + break; + } + // Listeners and IDs are two parallel arrays that are always in sync. + cb(event, dispatchListeners[i], dispatchIDs[i]); + } + } else if (dispatchListeners) { + cb(event, dispatchListeners, dispatchIDs); + } + } + + /** + * Default implementation of PluginModule.executeDispatch(). + * @param {SyntheticEvent} SyntheticEvent to handle + * @param {function} Application-level callback + * @param {string} domID DOM id to pass to the callback. + */ + function executeDispatch(event, listener, domID) { + event.currentTarget = injection.Mount.getNode(domID); + var returnValue = listener(event, domID); + event.currentTarget = null; + return returnValue; + } + + /** + * Standard/simple iteration through an event's collected dispatches. + */ + function executeDispatchesInOrder(event, cb) { + forEachEventDispatch(event, cb); + event._dispatchListeners = null; + event._dispatchIDs = null; + } + + /** + * Standard/simple iteration through an event's collected dispatches, but stops + * at the first dispatch execution returning true, and returns that id. + * + * @return id of the first dispatch execution who's listener returns true, or + * null if no listener returned true. + */ + function executeDispatchesInOrderStopAtTrueImpl(event) { + var dispatchListeners = event._dispatchListeners; + var dispatchIDs = event._dispatchIDs; + if (false) { + validateEventDispatches(event); + } + if (Array.isArray(dispatchListeners)) { + for (var i = 0; i < dispatchListeners.length; i++) { + if (event.isPropagationStopped()) { + break; + } + // Listeners and IDs are two parallel arrays that are always in sync. + if (dispatchListeners[i](event, dispatchIDs[i])) { + return dispatchIDs[i]; + } + } + } else if (dispatchListeners) { + if (dispatchListeners(event, dispatchIDs)) { + return dispatchIDs; + } + } + return null; + } + + /** + * @see executeDispatchesInOrderStopAtTrueImpl + */ + function executeDispatchesInOrderStopAtTrue(event) { + var ret = executeDispatchesInOrderStopAtTrueImpl(event); + event._dispatchIDs = null; + event._dispatchListeners = null; + return ret; + } + + /** + * Execution of a "direct" dispatch - there must be at most one dispatch + * accumulated on the event or it is considered an error. It doesn't really make + * sense for an event with multiple dispatches (bubbled) to keep track of the + * return values at each dispatch execution, but it does tend to make sense when + * dealing with "direct" dispatches. + * + * @return The return value of executing the single dispatch. + */ + function executeDirectDispatch(event) { + if (false) { + validateEventDispatches(event); + } + var dispatchListener = event._dispatchListeners; + var dispatchID = event._dispatchIDs; + ( false ? invariant( + !Array.isArray(dispatchListener), + 'executeDirectDispatch(...): Invalid `event`.' + ) : invariant(!Array.isArray(dispatchListener))); + var res = dispatchListener ? + dispatchListener(event, dispatchID) : + null; + event._dispatchListeners = null; + event._dispatchIDs = null; + return res; + } + + /** + * @param {SyntheticEvent} event + * @return {bool} True iff number of dispatches accumulated is greater than 0. + */ + function hasDispatches(event) { + return !!event._dispatchListeners; + } + + /** + * General utilities that are useful in creating custom Event Plugins. + */ + var EventPluginUtils = { + isEndish: isEndish, + isMoveish: isMoveish, + isStartish: isStartish, + + executeDirectDispatch: executeDirectDispatch, + executeDispatch: executeDispatch, + executeDispatchesInOrder: executeDispatchesInOrder, + executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, + hasDispatches: hasDispatches, + injection: injection, + useTouchEvents: false + }; + + module.exports = EventPluginUtils; + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule EventConstants + */ + + 'use strict'; + + var keyMirror = __webpack_require__(6); + + var PropagationPhases = keyMirror({bubbled: null, captured: null}); + + /** + * Types of raw signals from the browser caught at the top level. + */ + var topLevelTypes = keyMirror({ + topBlur: null, + topChange: null, + topClick: null, + topCompositionEnd: null, + topCompositionStart: null, + topCompositionUpdate: null, + topContextMenu: null, + topCopy: null, + topCut: null, + topDoubleClick: null, + topDrag: null, + topDragEnd: null, + topDragEnter: null, + topDragExit: null, + topDragLeave: null, + topDragOver: null, + topDragStart: null, + topDrop: null, + topError: null, + topFocus: null, + topInput: null, + topKeyDown: null, + topKeyPress: null, + topKeyUp: null, + topLoad: null, + topMouseDown: null, + topMouseMove: null, + topMouseOut: null, + topMouseOver: null, + topMouseUp: null, + topPaste: null, + topReset: null, + topScroll: null, + topSelectionChange: null, + topSubmit: null, + topTextInput: null, + topTouchCancel: null, + topTouchEnd: null, + topTouchMove: null, + topTouchStart: null, + topWheel: null + }); + + var EventConstants = { + topLevelTypes: topLevelTypes, + PropagationPhases: PropagationPhases + }; + + module.exports = EventConstants; + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule keyMirror + * @typechecks static-only + */ + + 'use strict'; + + var invariant = __webpack_require__(7); + + /** + * Constructs an enumeration with keys equal to their value. + * + * For example: + * + * var COLORS = keyMirror({blue: null, red: null}); + * var myColor = COLORS.blue; + * var isColorValid = !!COLORS[myColor]; + * + * The last line could not be performed if the values of the generated enum were + * not equal to their keys. + * + * Input: {key1: val1, key2: val2} + * Output: {key1: key1, key2: key2} + * + * @param {object} obj + * @return {object} + */ + var keyMirror = function(obj) { + var ret = {}; + var key; + ( false ? invariant( + obj instanceof Object && !Array.isArray(obj), + 'keyMirror(...): Argument must be an object.' + ) : invariant(obj instanceof Object && !Array.isArray(obj))); + for (key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + ret[key] = key; + } + return ret; + }; + + module.exports = keyMirror; + + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule invariant + */ + + "use strict"; + + /** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + + var invariant = function(condition, format, a, b, c, d, e, f) { + if (false) { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + } + + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + 'Invariant Violation: ' + + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } + }; + + module.exports = invariant; + + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactChildren + */ + + 'use strict'; + + var PooledClass = __webpack_require__(9); + var ReactFragment = __webpack_require__(10); + + var traverseAllChildren = __webpack_require__(18); + var warning = __webpack_require__(15); + + var twoArgumentPooler = PooledClass.twoArgumentPooler; + var threeArgumentPooler = PooledClass.threeArgumentPooler; + + /** + * PooledClass representing the bookkeeping associated with performing a child + * traversal. Allows avoiding binding callbacks. + * + * @constructor ForEachBookKeeping + * @param {!function} forEachFunction Function to perform traversal with. + * @param {?*} forEachContext Context to perform context with. + */ + function ForEachBookKeeping(forEachFunction, forEachContext) { + this.forEachFunction = forEachFunction; + this.forEachContext = forEachContext; + } + PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); + + function forEachSingleChild(traverseContext, child, name, i) { + var forEachBookKeeping = traverseContext; + forEachBookKeeping.forEachFunction.call( + forEachBookKeeping.forEachContext, child, i); + } + + /** + * Iterates through children that are typically specified as `props.children`. + * + * The provided forEachFunc(child, index) will be called for each + * leaf child. + * + * @param {?*} children Children tree container. + * @param {function(*, int)} forEachFunc. + * @param {*} forEachContext Context for forEachContext. + */ + function forEachChildren(children, forEachFunc, forEachContext) { + if (children == null) { + return children; + } + + var traverseContext = + ForEachBookKeeping.getPooled(forEachFunc, forEachContext); + traverseAllChildren(children, forEachSingleChild, traverseContext); + ForEachBookKeeping.release(traverseContext); + } + + /** + * PooledClass representing the bookkeeping associated with performing a child + * mapping. Allows avoiding binding callbacks. + * + * @constructor MapBookKeeping + * @param {!*} mapResult Object containing the ordered map of results. + * @param {!function} mapFunction Function to perform mapping with. + * @param {?*} mapContext Context to perform mapping with. + */ + function MapBookKeeping(mapResult, mapFunction, mapContext) { + this.mapResult = mapResult; + this.mapFunction = mapFunction; + this.mapContext = mapContext; + } + PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler); + + function mapSingleChildIntoContext(traverseContext, child, name, i) { + var mapBookKeeping = traverseContext; + var mapResult = mapBookKeeping.mapResult; + + var keyUnique = !mapResult.hasOwnProperty(name); + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + keyUnique, + 'ReactChildren.map(...): Encountered two children with the same key, ' + + '`%s`. Child keys must be unique; when two children share a key, only ' + + 'the first child will be used.', + name + ) : null); + } + + if (keyUnique) { + var mappedChild = + mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i); + mapResult[name] = mappedChild; + } + } + + /** + * Maps children that are typically specified as `props.children`. + * + * The provided mapFunction(child, key, index) will be called for each + * leaf child. + * + * TODO: This may likely break any calls to `ReactChildren.map` that were + * previously relying on the fact that we guarded against null children. + * + * @param {?*} children Children tree container. + * @param {function(*, int)} mapFunction. + * @param {*} mapContext Context for mapFunction. + * @return {object} Object containing the ordered map of results. + */ + function mapChildren(children, func, context) { + if (children == null) { + return children; + } + + var mapResult = {}; + var traverseContext = MapBookKeeping.getPooled(mapResult, func, context); + traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); + MapBookKeeping.release(traverseContext); + return ReactFragment.create(mapResult); + } + + function forEachSingleChildDummy(traverseContext, child, name, i) { + return null; + } + + /** + * Count the number of children that are typically specified as + * `props.children`. + * + * @param {?*} children Children tree container. + * @return {number} The number of children. + */ + function countChildren(children, context) { + return traverseAllChildren(children, forEachSingleChildDummy, null); + } + + var ReactChildren = { + forEach: forEachChildren, + map: mapChildren, + count: countChildren + }; + + module.exports = ReactChildren; + + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule PooledClass + */ + + 'use strict'; + + var invariant = __webpack_require__(7); + + /** + * Static poolers. Several custom versions for each potential number of + * arguments. A completely generic pooler is easy to implement, but would + * require accessing the `arguments` object. In each of these, `this` refers to + * the Class itself, not an instance. If any others are needed, simply add them + * here, or in their own files. + */ + var oneArgumentPooler = function(copyFieldsFrom) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, copyFieldsFrom); + return instance; + } else { + return new Klass(copyFieldsFrom); + } + }; + + var twoArgumentPooler = function(a1, a2) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2); + return instance; + } else { + return new Klass(a1, a2); + } + }; + + var threeArgumentPooler = function(a1, a2, a3) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2, a3); + return instance; + } else { + return new Klass(a1, a2, a3); + } + }; + + var fiveArgumentPooler = function(a1, a2, a3, a4, a5) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2, a3, a4, a5); + return instance; + } else { + return new Klass(a1, a2, a3, a4, a5); + } + }; + + var standardReleaser = function(instance) { + var Klass = this; + ( false ? invariant( + instance instanceof Klass, + 'Trying to release an instance into a pool of a different type.' + ) : invariant(instance instanceof Klass)); + if (instance.destructor) { + instance.destructor(); + } + if (Klass.instancePool.length < Klass.poolSize) { + Klass.instancePool.push(instance); + } + }; + + var DEFAULT_POOL_SIZE = 10; + var DEFAULT_POOLER = oneArgumentPooler; + + /** + * Augments `CopyConstructor` to be a poolable class, augmenting only the class + * itself (statically) not adding any prototypical fields. Any CopyConstructor + * you give this may have a `poolSize` property, and will look for a + * prototypical `destructor` on instances (optional). + * + * @param {Function} CopyConstructor Constructor that can be used to reset. + * @param {Function} pooler Customizable pooler. + */ + var addPoolingTo = function(CopyConstructor, pooler) { + var NewKlass = CopyConstructor; + NewKlass.instancePool = []; + NewKlass.getPooled = pooler || DEFAULT_POOLER; + if (!NewKlass.poolSize) { + NewKlass.poolSize = DEFAULT_POOL_SIZE; + } + NewKlass.release = standardReleaser; + return NewKlass; + }; + + var PooledClass = { + addPoolingTo: addPoolingTo, + oneArgumentPooler: oneArgumentPooler, + twoArgumentPooler: twoArgumentPooler, + threeArgumentPooler: threeArgumentPooler, + fiveArgumentPooler: fiveArgumentPooler + }; + + module.exports = PooledClass; + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactFragment + */ + + 'use strict'; + + var ReactElement = __webpack_require__(11); + + var warning = __webpack_require__(15); + + /** + * We used to allow keyed objects to serve as a collection of ReactElements, + * or nested sets. This allowed us a way to explicitly key a set a fragment of + * components. This is now being replaced with an opaque data structure. + * The upgrade path is to call React.addons.createFragment({ key: value }) to + * create a keyed fragment. The resulting data structure is opaque, for now. + */ + + if (false) { + var fragmentKey = '_reactFragment'; + var didWarnKey = '_reactDidWarn'; + var canWarnForReactFragment = false; + + try { + // Feature test. Don't even try to issue this warning if we can't use + // enumerable: false. + + var dummy = function() { + return 1; + }; + + Object.defineProperty( + {}, + fragmentKey, + {enumerable: false, value: true} + ); + + Object.defineProperty( + {}, + 'key', + {enumerable: true, get: dummy} + ); + + canWarnForReactFragment = true; + } catch (x) { } + + var proxyPropertyAccessWithWarning = function(obj, key) { + Object.defineProperty(obj, key, { + enumerable: true, + get: function() { + ("production" !== process.env.NODE_ENV ? warning( + this[didWarnKey], + 'A ReactFragment is an opaque type. Accessing any of its ' + + 'properties is deprecated. Pass it to one of the React.Children ' + + 'helpers.' + ) : null); + this[didWarnKey] = true; + return this[fragmentKey][key]; + }, + set: function(value) { + ("production" !== process.env.NODE_ENV ? warning( + this[didWarnKey], + 'A ReactFragment is an immutable opaque type. Mutating its ' + + 'properties is deprecated.' + ) : null); + this[didWarnKey] = true; + this[fragmentKey][key] = value; + } + }); + }; + + var issuedWarnings = {}; + + var didWarnForFragment = function(fragment) { + // We use the keys and the type of the value as a heuristic to dedupe the + // warning to avoid spamming too much. + var fragmentCacheKey = ''; + for (var key in fragment) { + fragmentCacheKey += key + ':' + (typeof fragment[key]) + ','; + } + var alreadyWarnedOnce = !!issuedWarnings[fragmentCacheKey]; + issuedWarnings[fragmentCacheKey] = true; + return alreadyWarnedOnce; + }; + } + + var ReactFragment = { + // Wrap a keyed object in an opaque proxy that warns you if you access any + // of its properties. + create: function(object) { + if (false) { + if (typeof object !== 'object' || !object || Array.isArray(object)) { + ("production" !== process.env.NODE_ENV ? warning( + false, + 'React.addons.createFragment only accepts a single object.', + object + ) : null); + return object; + } + if (ReactElement.isValidElement(object)) { + ("production" !== process.env.NODE_ENV ? warning( + false, + 'React.addons.createFragment does not accept a ReactElement ' + + 'without a wrapper object.' + ) : null); + return object; + } + if (canWarnForReactFragment) { + var proxy = {}; + Object.defineProperty(proxy, fragmentKey, { + enumerable: false, + value: object + }); + Object.defineProperty(proxy, didWarnKey, { + writable: true, + enumerable: false, + value: false + }); + for (var key in object) { + proxyPropertyAccessWithWarning(proxy, key); + } + Object.preventExtensions(proxy); + return proxy; + } + } + return object; + }, + // Extract the original keyed object from the fragment opaque type. Warn if + // a plain object is passed here. + extract: function(fragment) { + if (false) { + if (canWarnForReactFragment) { + if (!fragment[fragmentKey]) { + ("production" !== process.env.NODE_ENV ? warning( + didWarnForFragment(fragment), + 'Any use of a keyed object should be wrapped in ' + + 'React.addons.createFragment(object) before being passed as a ' + + 'child.' + ) : null); + return fragment; + } + return fragment[fragmentKey]; + } + } + return fragment; + }, + // Check if this is a fragment and if so, extract the keyed object. If it + // is a fragment-like object, warn that it should be wrapped. Ignore if we + // can't determine what kind of object this is. + extractIfFragment: function(fragment) { + if (false) { + if (canWarnForReactFragment) { + // If it is the opaque type, return the keyed object. + if (fragment[fragmentKey]) { + return fragment[fragmentKey]; + } + // Otherwise, check each property if it has an element, if it does + // it is probably meant as a fragment, so we can warn early. Defer, + // the warning to extract. + for (var key in fragment) { + if (fragment.hasOwnProperty(key) && + ReactElement.isValidElement(fragment[key])) { + // This looks like a fragment object, we should provide an + // early warning. + return ReactFragment.extract(fragment); + } + } + } + } + return fragment; + } + }; + + module.exports = ReactFragment; + + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactElement + */ + + 'use strict'; + + var ReactContext = __webpack_require__(12); + var ReactCurrentOwner = __webpack_require__(17); + + var assign = __webpack_require__(13); + var warning = __webpack_require__(15); + + var RESERVED_PROPS = { + key: true, + ref: true + }; + + /** + * Warn for mutations. + * + * @internal + * @param {object} object + * @param {string} key + */ + function defineWarningProperty(object, key) { + Object.defineProperty(object, key, { + + configurable: false, + enumerable: true, + + get: function() { + if (!this._store) { + return null; + } + return this._store[key]; + }, + + set: function(value) { + ( false ? warning( + false, + 'Don\'t set the %s property of the React element. Instead, ' + + 'specify the correct value when initially creating the element.', + key + ) : null); + this._store[key] = value; + } + + }); + } + + /** + * This is updated to true if the membrane is successfully created. + */ + var useMutationMembrane = false; + + /** + * Warn for mutations. + * + * @internal + * @param {object} element + */ + function defineMutationMembrane(prototype) { + try { + var pseudoFrozenProperties = { + props: true + }; + for (var key in pseudoFrozenProperties) { + defineWarningProperty(prototype, key); + } + useMutationMembrane = true; + } catch (x) { + // IE will fail on defineProperty + } + } + + /** + * Base constructor for all React elements. This is only used to make this + * work with a dynamic instanceof check. Nothing should live on this prototype. + * + * @param {*} type + * @param {string|object} ref + * @param {*} key + * @param {*} props + * @internal + */ + var ReactElement = function(type, key, ref, owner, context, props) { + // Built-in properties that belong on the element + this.type = type; + this.key = key; + this.ref = ref; + + // Record the component responsible for creating this element. + this._owner = owner; + + // TODO: Deprecate withContext, and then the context becomes accessible + // through the owner. + this._context = context; + + if (false) { + // The validation flag and props are currently mutative. We put them on + // an external backing store so that we can freeze the whole object. + // This can be replaced with a WeakMap once they are implemented in + // commonly used development environments. + this._store = {props: props, originalProps: assign({}, props)}; + + // To make comparing ReactElements easier for testing purposes, we make + // the validation flag non-enumerable (where possible, which should + // include every environment we run tests in), so the test framework + // ignores it. + try { + Object.defineProperty(this._store, 'validated', { + configurable: false, + enumerable: false, + writable: true + }); + } catch (x) { + } + this._store.validated = false; + + // We're not allowed to set props directly on the object so we early + // return and rely on the prototype membrane to forward to the backing + // store. + if (useMutationMembrane) { + Object.freeze(this); + return; + } + } + + this.props = props; + }; + + // We intentionally don't expose the function on the constructor property. + // ReactElement should be indistinguishable from a plain object. + ReactElement.prototype = { + _isReactElement: true + }; + + if (false) { + defineMutationMembrane(ReactElement.prototype); + } + + ReactElement.createElement = function(type, config, children) { + var propName; + + // Reserved names are extracted + var props = {}; + + var key = null; + var ref = null; + + if (config != null) { + ref = config.ref === undefined ? null : config.ref; + key = config.key === undefined ? null : '' + config.key; + // Remaining properties are added to a new props object + for (propName in config) { + if (config.hasOwnProperty(propName) && + !RESERVED_PROPS.hasOwnProperty(propName)) { + props[propName] = config[propName]; + } + } + } + + // Children can be more than one argument, and those are transferred onto + // the newly allocated props object. + var childrenLength = arguments.length - 2; + if (childrenLength === 1) { + props.children = children; + } else if (childrenLength > 1) { + var childArray = Array(childrenLength); + for (var i = 0; i < childrenLength; i++) { + childArray[i] = arguments[i + 2]; + } + props.children = childArray; + } + + // Resolve default props + if (type && type.defaultProps) { + var defaultProps = type.defaultProps; + for (propName in defaultProps) { + if (typeof props[propName] === 'undefined') { + props[propName] = defaultProps[propName]; + } + } + } + + return new ReactElement( + type, + key, + ref, + ReactCurrentOwner.current, + ReactContext.current, + props + ); + }; + + ReactElement.createFactory = function(type) { + var factory = ReactElement.createElement.bind(null, type); + // Expose the type on the factory and the prototype so that it can be + // easily accessed on elements. E.g. .type === Foo.type. + // This should not be named `constructor` since this may not be the function + // that created the element, and it may not even be a constructor. + // Legacy hook TODO: Warn if this is accessed + factory.type = type; + return factory; + }; + + ReactElement.cloneAndReplaceProps = function(oldElement, newProps) { + var newElement = new ReactElement( + oldElement.type, + oldElement.key, + oldElement.ref, + oldElement._owner, + oldElement._context, + newProps + ); + + if (false) { + // If the key on the original is valid, then the clone is valid + newElement._store.validated = oldElement._store.validated; + } + return newElement; + }; + + ReactElement.cloneElement = function(element, config, children) { + var propName; + + // Original props are copied + var props = assign({}, element.props); + + // Reserved names are extracted + var key = element.key; + var ref = element.ref; + + // Owner will be preserved, unless ref is overridden + var owner = element._owner; + + if (config != null) { + if (config.ref !== undefined) { + // Silently steal the ref from the parent. + ref = config.ref; + owner = ReactCurrentOwner.current; + } + if (config.key !== undefined) { + key = '' + config.key; + } + // Remaining properties override existing props + for (propName in config) { + if (config.hasOwnProperty(propName) && + !RESERVED_PROPS.hasOwnProperty(propName)) { + props[propName] = config[propName]; + } + } + } + + // Children can be more than one argument, and those are transferred onto + // the newly allocated props object. + var childrenLength = arguments.length - 2; + if (childrenLength === 1) { + props.children = children; + } else if (childrenLength > 1) { + var childArray = Array(childrenLength); + for (var i = 0; i < childrenLength; i++) { + childArray[i] = arguments[i + 2]; + } + props.children = childArray; + } + + return new ReactElement( + element.type, + key, + ref, + owner, + element._context, + props + ); + }; + + /** + * @param {?object} object + * @return {boolean} True if `object` is a valid component. + * @final + */ + ReactElement.isValidElement = function(object) { + // ReactTestUtils is often used outside of beforeEach where as React is + // within it. This leads to two different instances of React on the same + // page. To identify a element from a different React instance we use + // a flag instead of an instanceof check. + var isElement = !!(object && object._isReactElement); + // if (isElement && !(object instanceof ReactElement)) { + // This is an indicator that you're using multiple versions of React at the + // same time. This will screw with ownership and stuff. Fix it, please. + // TODO: We could possibly warn here. + // } + return isElement; + }; + + module.exports = ReactElement; + + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactContext + */ + + 'use strict'; + + var assign = __webpack_require__(13); + var emptyObject = __webpack_require__(14); + var warning = __webpack_require__(15); + + var didWarn = false; + + /** + * Keeps track of the current context. + * + * The context is automatically passed down the component ownership hierarchy + * and is accessible via `this.context` on ReactCompositeComponents. + */ + var ReactContext = { + + /** + * @internal + * @type {object} + */ + current: emptyObject, + + /** + * Temporarily extends the current context while executing scopedCallback. + * + * A typical use case might look like + * + * render: function() { + * var children = ReactContext.withContext({foo: 'foo'}, () => ( + * + * )); + * return
{children}
; + * } + * + * @param {object} newContext New context to merge into the existing context + * @param {function} scopedCallback Callback to run with the new context + * @return {ReactComponent|array} + */ + withContext: function(newContext, scopedCallback) { + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + didWarn, + 'withContext is deprecated and will be removed in a future version. ' + + 'Use a wrapper component with getChildContext instead.' + ) : null); + + didWarn = true; + } + + var result; + var previousContext = ReactContext.current; + ReactContext.current = assign({}, previousContext, newContext); + try { + result = scopedCallback(); + } finally { + ReactContext.current = previousContext; + } + return result; + } + + }; + + module.exports = ReactContext; + + +/***/ }, +/* 13 */ +/***/ function(module, exports) { + + /** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule Object.assign + */ + + // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign + + 'use strict'; + + function assign(target, sources) { + if (target == null) { + throw new TypeError('Object.assign target cannot be null or undefined'); + } + + var to = Object(target); + var hasOwnProperty = Object.prototype.hasOwnProperty; + + for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { + var nextSource = arguments[nextIndex]; + if (nextSource == null) { + continue; + } + + var from = Object(nextSource); + + // We don't currently support accessors nor proxies. Therefore this + // copy cannot throw. If we ever supported this then we must handle + // exceptions and side-effects. We don't support symbols so they won't + // be transferred. + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + } + + return to; + } + + module.exports = assign; + + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule emptyObject + */ + + "use strict"; + + var emptyObject = {}; + + if (false) { + Object.freeze(emptyObject); + } + + module.exports = emptyObject; + + +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule warning + */ + + "use strict"; + + var emptyFunction = __webpack_require__(16); + + /** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + + var warning = emptyFunction; + + if (false) { + warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + if (format === undefined) { + throw new Error( + '`warning(condition, format, ...args)` requires a warning ' + + 'message argument' + ); + } + + if (format.length < 10 || /^[s\W]*$/.test(format)) { + throw new Error( + 'The warning format should be able to uniquely identify this ' + + 'warning. Please, use a more descriptive format than: ' + format + ); + } + + if (format.indexOf('Failed Composite propType: ') === 0) { + return; // Ignore CompositeComponent proptype check. + } + + if (!condition) { + var argIndex = 0; + var message = 'Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];}); + console.warn(message); + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch(x) {} + } + }; + } + + module.exports = warning; + + +/***/ }, +/* 16 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule emptyFunction + */ + + function makeEmptyFunction(arg) { + return function() { + return arg; + }; + } + + /** + * This function accepts and discards inputs; it has no side effects. This is + * primarily useful idiomatically for overridable function endpoints which + * always need to be callable, since JS lacks a null-call idiom ala Cocoa. + */ + function emptyFunction() {} + + emptyFunction.thatReturns = makeEmptyFunction; + emptyFunction.thatReturnsFalse = makeEmptyFunction(false); + emptyFunction.thatReturnsTrue = makeEmptyFunction(true); + emptyFunction.thatReturnsNull = makeEmptyFunction(null); + emptyFunction.thatReturnsThis = function() { return this; }; + emptyFunction.thatReturnsArgument = function(arg) { return arg; }; + + module.exports = emptyFunction; + + +/***/ }, +/* 17 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactCurrentOwner + */ + + 'use strict'; + + /** + * Keeps track of the current owner. + * + * The current owner is the component who should own any components that are + * currently being constructed. + * + * The depth indicate how many composite components are above this render level. + */ + var ReactCurrentOwner = { + + /** + * @internal + * @type {ReactComponent} + */ + current: null + + }; + + module.exports = ReactCurrentOwner; + + +/***/ }, +/* 18 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule traverseAllChildren + */ + + 'use strict'; + + var ReactElement = __webpack_require__(11); + var ReactFragment = __webpack_require__(10); + var ReactInstanceHandles = __webpack_require__(19); + + var getIteratorFn = __webpack_require__(21); + var invariant = __webpack_require__(7); + var warning = __webpack_require__(15); + + var SEPARATOR = ReactInstanceHandles.SEPARATOR; + var SUBSEPARATOR = ':'; + + /** + * TODO: Test that a single child and an array with one item have the same key + * pattern. + */ + + var userProvidedKeyEscaperLookup = { + '=': '=0', + '.': '=1', + ':': '=2' + }; + + var userProvidedKeyEscapeRegex = /[=.:]/g; + + var didWarnAboutMaps = false; + + function userProvidedKeyEscaper(match) { + return userProvidedKeyEscaperLookup[match]; + } + + /** + * Generate a key string that identifies a component within a set. + * + * @param {*} component A component that could contain a manual key. + * @param {number} index Index that is used if a manual key is not provided. + * @return {string} + */ + function getComponentKey(component, index) { + if (component && component.key != null) { + // Explicit key + return wrapUserProvidedKey(component.key); + } + // Implicit key determined by the index in the set + return index.toString(36); + } + + /** + * Escape a component key so that it is safe to use in a reactid. + * + * @param {*} key Component key to be escaped. + * @return {string} An escaped string. + */ + function escapeUserProvidedKey(text) { + return ('' + text).replace( + userProvidedKeyEscapeRegex, + userProvidedKeyEscaper + ); + } + + /** + * Wrap a `key` value explicitly provided by the user to distinguish it from + * implicitly-generated keys generated by a component's index in its parent. + * + * @param {string} key Value of a user-provided `key` attribute + * @return {string} + */ + function wrapUserProvidedKey(key) { + return '$' + escapeUserProvidedKey(key); + } + + /** + * @param {?*} children Children tree container. + * @param {!string} nameSoFar Name of the key path so far. + * @param {!number} indexSoFar Number of children encountered until this point. + * @param {!function} callback Callback to invoke with each child found. + * @param {?*} traverseContext Used to pass information throughout the traversal + * process. + * @return {!number} The number of children in this subtree. + */ + function traverseAllChildrenImpl( + children, + nameSoFar, + indexSoFar, + callback, + traverseContext + ) { + var type = typeof children; + + if (type === 'undefined' || type === 'boolean') { + // All of the above are perceived as null. + children = null; + } + + if (children === null || + type === 'string' || + type === 'number' || + ReactElement.isValidElement(children)) { + callback( + traverseContext, + children, + // If it's the only child, treat the name as if it was wrapped in an array + // so that it's consistent if the number of children grows. + nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar, + indexSoFar + ); + return 1; + } + + var child, nextName, nextIndex; + var subtreeCount = 0; // Count of children found in the current subtree. + + if (Array.isArray(children)) { + for (var i = 0; i < children.length; i++) { + child = children[i]; + nextName = ( + (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + + getComponentKey(child, i) + ); + nextIndex = indexSoFar + subtreeCount; + subtreeCount += traverseAllChildrenImpl( + child, + nextName, + nextIndex, + callback, + traverseContext + ); + } + } else { + var iteratorFn = getIteratorFn(children); + if (iteratorFn) { + var iterator = iteratorFn.call(children); + var step; + if (iteratorFn !== children.entries) { + var ii = 0; + while (!(step = iterator.next()).done) { + child = step.value; + nextName = ( + (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + + getComponentKey(child, ii++) + ); + nextIndex = indexSoFar + subtreeCount; + subtreeCount += traverseAllChildrenImpl( + child, + nextName, + nextIndex, + callback, + traverseContext + ); + } + } else { + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + didWarnAboutMaps, + 'Using Maps as children is not yet fully supported. It is an ' + + 'experimental feature that might be removed. Convert it to a ' + + 'sequence / iterable of keyed ReactElements instead.' + ) : null); + didWarnAboutMaps = true; + } + // Iterator will provide entry [k,v] tuples rather than values. + while (!(step = iterator.next()).done) { + var entry = step.value; + if (entry) { + child = entry[1]; + nextName = ( + (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + + wrapUserProvidedKey(entry[0]) + SUBSEPARATOR + + getComponentKey(child, 0) + ); + nextIndex = indexSoFar + subtreeCount; + subtreeCount += traverseAllChildrenImpl( + child, + nextName, + nextIndex, + callback, + traverseContext + ); + } + } + } + } else if (type === 'object') { + ( false ? invariant( + children.nodeType !== 1, + 'traverseAllChildren(...): Encountered an invalid child; DOM ' + + 'elements are not valid children of React components.' + ) : invariant(children.nodeType !== 1)); + var fragment = ReactFragment.extract(children); + for (var key in fragment) { + if (fragment.hasOwnProperty(key)) { + child = fragment[key]; + nextName = ( + (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + + wrapUserProvidedKey(key) + SUBSEPARATOR + + getComponentKey(child, 0) + ); + nextIndex = indexSoFar + subtreeCount; + subtreeCount += traverseAllChildrenImpl( + child, + nextName, + nextIndex, + callback, + traverseContext + ); + } + } + } + } + + return subtreeCount; + } + + /** + * Traverses children that are typically specified as `props.children`, but + * might also be specified through attributes: + * + * - `traverseAllChildren(this.props.children, ...)` + * - `traverseAllChildren(this.props.leftPanelChildren, ...)` + * + * The `traverseContext` is an optional argument that is passed through the + * entire traversal. It can be used to store accumulations or anything else that + * the callback might find relevant. + * + * @param {?*} children Children tree object. + * @param {!function} callback To invoke upon traversing each child. + * @param {?*} traverseContext Context for traversal. + * @return {!number} The number of children in this subtree. + */ + function traverseAllChildren(children, callback, traverseContext) { + if (children == null) { + return 0; + } + + return traverseAllChildrenImpl(children, '', 0, callback, traverseContext); + } + + module.exports = traverseAllChildren; + + +/***/ }, +/* 19 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactInstanceHandles + * @typechecks static-only + */ + + 'use strict'; + + var ReactRootIndex = __webpack_require__(20); + + var invariant = __webpack_require__(7); + + var SEPARATOR = '.'; + var SEPARATOR_LENGTH = SEPARATOR.length; + + /** + * Maximum depth of traversals before we consider the possibility of a bad ID. + */ + var MAX_TREE_DEPTH = 100; + + /** + * Creates a DOM ID prefix to use when mounting React components. + * + * @param {number} index A unique integer + * @return {string} React root ID. + * @internal + */ + function getReactRootIDString(index) { + return SEPARATOR + index.toString(36); + } + + /** + * Checks if a character in the supplied ID is a separator or the end. + * + * @param {string} id A React DOM ID. + * @param {number} index Index of the character to check. + * @return {boolean} True if the character is a separator or end of the ID. + * @private + */ + function isBoundary(id, index) { + return id.charAt(index) === SEPARATOR || index === id.length; + } + + /** + * Checks if the supplied string is a valid React DOM ID. + * + * @param {string} id A React DOM ID, maybe. + * @return {boolean} True if the string is a valid React DOM ID. + * @private + */ + function isValidID(id) { + return id === '' || ( + id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR + ); + } + + /** + * Checks if the first ID is an ancestor of or equal to the second ID. + * + * @param {string} ancestorID + * @param {string} descendantID + * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`. + * @internal + */ + function isAncestorIDOf(ancestorID, descendantID) { + return ( + descendantID.indexOf(ancestorID) === 0 && + isBoundary(descendantID, ancestorID.length) + ); + } + + /** + * Gets the parent ID of the supplied React DOM ID, `id`. + * + * @param {string} id ID of a component. + * @return {string} ID of the parent, or an empty string. + * @private + */ + function getParentID(id) { + return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : ''; + } + + /** + * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the + * supplied `destinationID`. If they are equal, the ID is returned. + * + * @param {string} ancestorID ID of an ancestor node of `destinationID`. + * @param {string} destinationID ID of the destination node. + * @return {string} Next ID on the path from `ancestorID` to `destinationID`. + * @private + */ + function getNextDescendantID(ancestorID, destinationID) { + ( false ? invariant( + isValidID(ancestorID) && isValidID(destinationID), + 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', + ancestorID, + destinationID + ) : invariant(isValidID(ancestorID) && isValidID(destinationID))); + ( false ? invariant( + isAncestorIDOf(ancestorID, destinationID), + 'getNextDescendantID(...): React has made an invalid assumption about ' + + 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', + ancestorID, + destinationID + ) : invariant(isAncestorIDOf(ancestorID, destinationID))); + if (ancestorID === destinationID) { + return ancestorID; + } + // Skip over the ancestor and the immediate separator. Traverse until we hit + // another separator or we reach the end of `destinationID`. + var start = ancestorID.length + SEPARATOR_LENGTH; + var i; + for (i = start; i < destinationID.length; i++) { + if (isBoundary(destinationID, i)) { + break; + } + } + return destinationID.substr(0, i); + } + + /** + * Gets the nearest common ancestor ID of two IDs. + * + * Using this ID scheme, the nearest common ancestor ID is the longest common + * prefix of the two IDs that immediately preceded a "marker" in both strings. + * + * @param {string} oneID + * @param {string} twoID + * @return {string} Nearest common ancestor ID, or the empty string if none. + * @private + */ + function getFirstCommonAncestorID(oneID, twoID) { + var minLength = Math.min(oneID.length, twoID.length); + if (minLength === 0) { + return ''; + } + var lastCommonMarkerIndex = 0; + // Use `<=` to traverse until the "EOL" of the shorter string. + for (var i = 0; i <= minLength; i++) { + if (isBoundary(oneID, i) && isBoundary(twoID, i)) { + lastCommonMarkerIndex = i; + } else if (oneID.charAt(i) !== twoID.charAt(i)) { + break; + } + } + var longestCommonID = oneID.substr(0, lastCommonMarkerIndex); + ( false ? invariant( + isValidID(longestCommonID), + 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', + oneID, + twoID, + longestCommonID + ) : invariant(isValidID(longestCommonID))); + return longestCommonID; + } + + /** + * Traverses the parent path between two IDs (either up or down). The IDs must + * not be the same, and there must exist a parent path between them. If the + * callback returns `false`, traversal is stopped. + * + * @param {?string} start ID at which to start traversal. + * @param {?string} stop ID at which to end traversal. + * @param {function} cb Callback to invoke each ID with. + * @param {?boolean} skipFirst Whether or not to skip the first node. + * @param {?boolean} skipLast Whether or not to skip the last node. + * @private + */ + function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) { + start = start || ''; + stop = stop || ''; + ( false ? invariant( + start !== stop, + 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', + start + ) : invariant(start !== stop)); + var traverseUp = isAncestorIDOf(stop, start); + ( false ? invariant( + traverseUp || isAncestorIDOf(start, stop), + 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + + 'not have a parent path.', + start, + stop + ) : invariant(traverseUp || isAncestorIDOf(start, stop))); + // Traverse from `start` to `stop` one depth at a time. + var depth = 0; + var traverse = traverseUp ? getParentID : getNextDescendantID; + for (var id = start; /* until break */; id = traverse(id, stop)) { + var ret; + if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) { + ret = cb(id, traverseUp, arg); + } + if (ret === false || id === stop) { + // Only break //after// visiting `stop`. + break; + } + ( false ? invariant( + depth++ < MAX_TREE_DEPTH, + 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + + 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', + start, stop + ) : invariant(depth++ < MAX_TREE_DEPTH)); + } + } + + /** + * Manages the IDs assigned to DOM representations of React components. This + * uses a specific scheme in order to traverse the DOM efficiently (e.g. in + * order to simulate events). + * + * @internal + */ + var ReactInstanceHandles = { + + /** + * Constructs a React root ID + * @return {string} A React root ID. + */ + createReactRootID: function() { + return getReactRootIDString(ReactRootIndex.createReactRootIndex()); + }, + + /** + * Constructs a React ID by joining a root ID with a name. + * + * @param {string} rootID Root ID of a parent component. + * @param {string} name A component's name (as flattened children). + * @return {string} A React ID. + * @internal + */ + createReactID: function(rootID, name) { + return rootID + name; + }, + + /** + * Gets the DOM ID of the React component that is the root of the tree that + * contains the React component with the supplied DOM ID. + * + * @param {string} id DOM ID of a React component. + * @return {?string} DOM ID of the React component that is the root. + * @internal + */ + getReactRootIDFromNodeID: function(id) { + if (id && id.charAt(0) === SEPARATOR && id.length > 1) { + var index = id.indexOf(SEPARATOR, 1); + return index > -1 ? id.substr(0, index) : id; + } + return null; + }, + + /** + * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that + * should would receive a `mouseEnter` or `mouseLeave` event. + * + * NOTE: Does not invoke the callback on the nearest common ancestor because + * nothing "entered" or "left" that element. + * + * @param {string} leaveID ID being left. + * @param {string} enterID ID being entered. + * @param {function} cb Callback to invoke on each entered/left ID. + * @param {*} upArg Argument to invoke the callback with on left IDs. + * @param {*} downArg Argument to invoke the callback with on entered IDs. + * @internal + */ + traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) { + var ancestorID = getFirstCommonAncestorID(leaveID, enterID); + if (ancestorID !== leaveID) { + traverseParentPath(leaveID, ancestorID, cb, upArg, false, true); + } + if (ancestorID !== enterID) { + traverseParentPath(ancestorID, enterID, cb, downArg, true, false); + } + }, + + /** + * Simulates the traversal of a two-phase, capture/bubble event dispatch. + * + * NOTE: This traversal happens on IDs without touching the DOM. + * + * @param {string} targetID ID of the target node. + * @param {function} cb Callback to invoke. + * @param {*} arg Argument to invoke the callback with. + * @internal + */ + traverseTwoPhase: function(targetID, cb, arg) { + if (targetID) { + traverseParentPath('', targetID, cb, arg, true, false); + traverseParentPath(targetID, '', cb, arg, false, true); + } + }, + + /** + * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For + * example, passing `.0.$row-0.1` would result in `cb` getting called + * with `.0`, `.0.$row-0`, and `.0.$row-0.1`. + * + * NOTE: This traversal happens on IDs without touching the DOM. + * + * @param {string} targetID ID of the target node. + * @param {function} cb Callback to invoke. + * @param {*} arg Argument to invoke the callback with. + * @internal + */ + traverseAncestors: function(targetID, cb, arg) { + traverseParentPath('', targetID, cb, arg, true, false); + }, + + /** + * Exposed for unit testing. + * @private + */ + _getFirstCommonAncestorID: getFirstCommonAncestorID, + + /** + * Exposed for unit testing. + * @private + */ + _getNextDescendantID: getNextDescendantID, + + isAncestorIDOf: isAncestorIDOf, + + SEPARATOR: SEPARATOR + + }; + + module.exports = ReactInstanceHandles; + + +/***/ }, +/* 20 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactRootIndex + * @typechecks + */ + + 'use strict'; + + var ReactRootIndexInjection = { + /** + * @param {function} _createReactRootIndex + */ + injectCreateReactRootIndex: function(_createReactRootIndex) { + ReactRootIndex.createReactRootIndex = _createReactRootIndex; + } + }; + + var ReactRootIndex = { + createReactRootIndex: null, + injection: ReactRootIndexInjection + }; + + module.exports = ReactRootIndex; + + +/***/ }, +/* 21 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule getIteratorFn + * @typechecks static-only + */ + + 'use strict'; + + /* global Symbol */ + var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. + + /** + * Returns the iterator method function contained on the iterable object. + * + * Be sure to invoke the function with the iterable as context: + * + * var iteratorFn = getIteratorFn(myIterable); + * if (iteratorFn) { + * var iterator = iteratorFn.call(myIterable); + * ... + * } + * + * @param {?object} maybeIterable + * @return {?function} + */ + function getIteratorFn(maybeIterable) { + var iteratorFn = maybeIterable && ( + (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]) + ); + if (typeof iteratorFn === 'function') { + return iteratorFn; + } + } + + module.exports = getIteratorFn; + + +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactComponent + */ + + 'use strict'; + + var ReactUpdateQueue = __webpack_require__(23); + + var invariant = __webpack_require__(7); + var warning = __webpack_require__(15); + + /** + * Base class helpers for the updating state of a component. + */ + function ReactComponent(props, context) { + this.props = props; + this.context = context; + } + + /** + * Sets a subset of the state. Always use this to mutate + * state. You should treat `this.state` as immutable. + * + * There is no guarantee that `this.state` will be immediately updated, so + * accessing `this.state` after calling this method may return the old value. + * + * There is no guarantee that calls to `setState` will run synchronously, + * as they may eventually be batched together. You can provide an optional + * callback that will be executed when the call to setState is actually + * completed. + * + * When a function is provided to setState, it will be called at some point in + * the future (not synchronously). It will be called with the up to date + * component arguments (state, props, context). These values can be different + * from this.* because your function may be called after receiveProps but before + * shouldComponentUpdate, and this new state, props, and context will not yet be + * assigned to this. + * + * @param {object|function} partialState Next partial state or function to + * produce next partial state to be merged with current state. + * @param {?function} callback Called after state is updated. + * @final + * @protected + */ + ReactComponent.prototype.setState = function(partialState, callback) { + ( false ? invariant( + typeof partialState === 'object' || + typeof partialState === 'function' || + partialState == null, + 'setState(...): takes an object of state variables to update or a ' + + 'function which returns an object of state variables.' + ) : invariant(typeof partialState === 'object' || + typeof partialState === 'function' || + partialState == null)); + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + partialState != null, + 'setState(...): You passed an undefined or null state object; ' + + 'instead, use forceUpdate().' + ) : null); + } + ReactUpdateQueue.enqueueSetState(this, partialState); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + }; + + /** + * Forces an update. This should only be invoked when it is known with + * certainty that we are **not** in a DOM transaction. + * + * You may want to call this when you know that some deeper aspect of the + * component's state has changed but `setState` was not called. + * + * This will not invoke `shouldComponentUpdate`, but it will invoke + * `componentWillUpdate` and `componentDidUpdate`. + * + * @param {?function} callback Called after update is complete. + * @final + * @protected + */ + ReactComponent.prototype.forceUpdate = function(callback) { + ReactUpdateQueue.enqueueForceUpdate(this); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + }; + + /** + * Deprecated APIs. These APIs used to exist on classic React classes but since + * we would like to deprecate them, we're not going to move them over to this + * modern base class. Instead, we define a getter that warns if it's accessed. + */ + if (false) { + var deprecatedAPIs = { + getDOMNode: [ + 'getDOMNode', + 'Use React.findDOMNode(component) instead.' + ], + isMounted: [ + 'isMounted', + 'Instead, make sure to clean up subscriptions and pending requests in ' + + 'componentWillUnmount to prevent memory leaks.' + ], + replaceProps: [ + 'replaceProps', + 'Instead, call React.render again at the top level.' + ], + replaceState: [ + 'replaceState', + 'Refactor your code to use setState instead (see ' + + 'https://github.com/facebook/react/issues/3236).' + ], + setProps: [ + 'setProps', + 'Instead, call React.render again at the top level.' + ] + }; + var defineDeprecationWarning = function(methodName, info) { + try { + Object.defineProperty(ReactComponent.prototype, methodName, { + get: function() { + ("production" !== process.env.NODE_ENV ? warning( + false, + '%s(...) is deprecated in plain JavaScript React classes. %s', + info[0], + info[1] + ) : null); + return undefined; + } + }); + } catch (x) { + // IE will fail on defineProperty (es5-shim/sham too) + } + }; + for (var fnName in deprecatedAPIs) { + if (deprecatedAPIs.hasOwnProperty(fnName)) { + defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); + } + } + } + + module.exports = ReactComponent; + + +/***/ }, +/* 23 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactUpdateQueue + */ + + 'use strict'; + + var ReactLifeCycle = __webpack_require__(24); + var ReactCurrentOwner = __webpack_require__(17); + var ReactElement = __webpack_require__(11); + var ReactInstanceMap = __webpack_require__(25); + var ReactUpdates = __webpack_require__(26); + + var assign = __webpack_require__(13); + var invariant = __webpack_require__(7); + var warning = __webpack_require__(15); + + function enqueueUpdate(internalInstance) { + if (internalInstance !== ReactLifeCycle.currentlyMountingInstance) { + // If we're in a componentWillMount handler, don't enqueue a rerender + // because ReactUpdates assumes we're in a browser context (which is + // wrong for server rendering) and we're about to do a render anyway. + // See bug in #1740. + ReactUpdates.enqueueUpdate(internalInstance); + } + } + + function getInternalInstanceReadyForUpdate(publicInstance, callerName) { + ( false ? invariant( + ReactCurrentOwner.current == null, + '%s(...): Cannot update during an existing state transition ' + + '(such as within `render`). Render methods should be a pure function ' + + 'of props and state.', + callerName + ) : invariant(ReactCurrentOwner.current == null)); + + var internalInstance = ReactInstanceMap.get(publicInstance); + if (!internalInstance) { + if (false) { + // Only warn when we have a callerName. Otherwise we should be silent. + // We're probably calling from enqueueCallback. We don't want to warn + // there because we already warned for the corresponding lifecycle method. + ("production" !== process.env.NODE_ENV ? warning( + !callerName, + '%s(...): Can only update a mounted or mounting component. ' + + 'This usually means you called %s() on an unmounted ' + + 'component. This is a no-op.', + callerName, + callerName + ) : null); + } + return null; + } + + if (internalInstance === ReactLifeCycle.currentlyUnmountingInstance) { + return null; + } + + return internalInstance; + } + + /** + * ReactUpdateQueue allows for state updates to be scheduled into a later + * reconciliation step. + */ + var ReactUpdateQueue = { + + /** + * Enqueue a callback that will be executed after all the pending updates + * have processed. + * + * @param {ReactClass} publicInstance The instance to use as `this` context. + * @param {?function} callback Called after state is updated. + * @internal + */ + enqueueCallback: function(publicInstance, callback) { + ( false ? invariant( + typeof callback === 'function', + 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + + 'isn\'t callable.' + ) : invariant(typeof callback === 'function')); + var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); + + // Previously we would throw an error if we didn't have an internal + // instance. Since we want to make it a no-op instead, we mirror the same + // behavior we have in other enqueue* methods. + // We also need to ignore callbacks in componentWillMount. See + // enqueueUpdates. + if (!internalInstance || + internalInstance === ReactLifeCycle.currentlyMountingInstance) { + return null; + } + + if (internalInstance._pendingCallbacks) { + internalInstance._pendingCallbacks.push(callback); + } else { + internalInstance._pendingCallbacks = [callback]; + } + // TODO: The callback here is ignored when setState is called from + // componentWillMount. Either fix it or disallow doing so completely in + // favor of getInitialState. Alternatively, we can disallow + // componentWillMount during server-side rendering. + enqueueUpdate(internalInstance); + }, + + enqueueCallbackInternal: function(internalInstance, callback) { + ( false ? invariant( + typeof callback === 'function', + 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + + 'isn\'t callable.' + ) : invariant(typeof callback === 'function')); + if (internalInstance._pendingCallbacks) { + internalInstance._pendingCallbacks.push(callback); + } else { + internalInstance._pendingCallbacks = [callback]; + } + enqueueUpdate(internalInstance); + }, + + /** + * Forces an update. This should only be invoked when it is known with + * certainty that we are **not** in a DOM transaction. + * + * You may want to call this when you know that some deeper aspect of the + * component's state has changed but `setState` was not called. + * + * This will not invoke `shouldUpdateComponent`, but it will invoke + * `componentWillUpdate` and `componentDidUpdate`. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @internal + */ + enqueueForceUpdate: function(publicInstance) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'forceUpdate' + ); + + if (!internalInstance) { + return; + } + + internalInstance._pendingForceUpdate = true; + + enqueueUpdate(internalInstance); + }, + + /** + * Replaces all of the state. Always use this or `setState` to mutate state. + * You should treat `this.state` as immutable. + * + * There is no guarantee that `this.state` will be immediately updated, so + * accessing `this.state` after calling this method may return the old value. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} completeState Next state. + * @internal + */ + enqueueReplaceState: function(publicInstance, completeState) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'replaceState' + ); + + if (!internalInstance) { + return; + } + + internalInstance._pendingStateQueue = [completeState]; + internalInstance._pendingReplaceState = true; + + enqueueUpdate(internalInstance); + }, + + /** + * Sets a subset of the state. This only exists because _pendingState is + * internal. This provides a merging strategy that is not available to deep + * properties which is confusing. TODO: Expose pendingState or don't use it + * during the merge. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} partialState Next partial state to be merged with state. + * @internal + */ + enqueueSetState: function(publicInstance, partialState) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'setState' + ); + + if (!internalInstance) { + return; + } + + var queue = + internalInstance._pendingStateQueue || + (internalInstance._pendingStateQueue = []); + queue.push(partialState); + + enqueueUpdate(internalInstance); + }, + + /** + * Sets a subset of the props. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} partialProps Subset of the next props. + * @internal + */ + enqueueSetProps: function(publicInstance, partialProps) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'setProps' + ); + + if (!internalInstance) { + return; + } + + ( false ? invariant( + internalInstance._isTopLevel, + 'setProps(...): You called `setProps` on a ' + + 'component with a parent. This is an anti-pattern since props will ' + + 'get reactively updated when rendered. Instead, change the owner\'s ' + + '`render` method to pass the correct value as props to the component ' + + 'where it is created.' + ) : invariant(internalInstance._isTopLevel)); + + // Merge with the pending element if it exists, otherwise with existing + // element props. + var element = internalInstance._pendingElement || + internalInstance._currentElement; + var props = assign({}, element.props, partialProps); + internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( + element, + props + ); + + enqueueUpdate(internalInstance); + }, + + /** + * Replaces all of the props. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} props New props. + * @internal + */ + enqueueReplaceProps: function(publicInstance, props) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'replaceProps' + ); + + if (!internalInstance) { + return; + } + + ( false ? invariant( + internalInstance._isTopLevel, + 'replaceProps(...): You called `replaceProps` on a ' + + 'component with a parent. This is an anti-pattern since props will ' + + 'get reactively updated when rendered. Instead, change the owner\'s ' + + '`render` method to pass the correct value as props to the component ' + + 'where it is created.' + ) : invariant(internalInstance._isTopLevel)); + + // Merge with the pending element if it exists, otherwise with existing + // element props. + var element = internalInstance._pendingElement || + internalInstance._currentElement; + internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( + element, + props + ); + + enqueueUpdate(internalInstance); + }, + + enqueueElementInternal: function(internalInstance, newElement) { + internalInstance._pendingElement = newElement; + enqueueUpdate(internalInstance); + } + + }; + + module.exports = ReactUpdateQueue; + + +/***/ }, +/* 24 */ +/***/ function(module, exports) { + + /** + * Copyright 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactLifeCycle + */ + + 'use strict'; + + /** + * This module manages the bookkeeping when a component is in the process + * of being mounted or being unmounted. This is used as a way to enforce + * invariants (or warnings) when it is not recommended to call + * setState/forceUpdate. + * + * currentlyMountingInstance: During the construction phase, it is not possible + * to trigger an update since the instance is not fully mounted yet. However, we + * currently allow this as a convenience for mutating the initial state. + * + * currentlyUnmountingInstance: During the unmounting phase, the instance is + * still mounted and can therefore schedule an update. However, this is not + * recommended and probably an error since it's about to be unmounted. + * Therefore we still want to trigger in an error for that case. + */ + + var ReactLifeCycle = { + currentlyMountingInstance: null, + currentlyUnmountingInstance: null + }; + + module.exports = ReactLifeCycle; + + +/***/ }, +/* 25 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactInstanceMap + */ + + 'use strict'; + + /** + * `ReactInstanceMap` maintains a mapping from a public facing stateful + * instance (key) and the internal representation (value). This allows public + * methods to accept the user facing instance as an argument and map them back + * to internal methods. + */ + + // TODO: Replace this with ES6: var ReactInstanceMap = new Map(); + var ReactInstanceMap = { + + /** + * This API should be called `delete` but we'd have to make sure to always + * transform these to strings for IE support. When this transform is fully + * supported we can rename it. + */ + remove: function(key) { + key._reactInternalInstance = undefined; + }, + + get: function(key) { + return key._reactInternalInstance; + }, + + has: function(key) { + return key._reactInternalInstance !== undefined; + }, + + set: function(key, value) { + key._reactInternalInstance = value; + } + + }; + + module.exports = ReactInstanceMap; + + +/***/ }, +/* 26 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactUpdates + */ + + 'use strict'; + + var CallbackQueue = __webpack_require__(27); + var PooledClass = __webpack_require__(9); + var ReactCurrentOwner = __webpack_require__(17); + var ReactPerf = __webpack_require__(28); + var ReactReconciler = __webpack_require__(29); + var Transaction = __webpack_require__(36); + + var assign = __webpack_require__(13); + var invariant = __webpack_require__(7); + var warning = __webpack_require__(15); + + var dirtyComponents = []; + var asapCallbackQueue = CallbackQueue.getPooled(); + var asapEnqueued = false; + + var batchingStrategy = null; + + function ensureInjected() { + ( false ? invariant( + ReactUpdates.ReactReconcileTransaction && batchingStrategy, + 'ReactUpdates: must inject a reconcile transaction class and batching ' + + 'strategy' + ) : invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy)); + } + + var NESTED_UPDATES = { + initialize: function() { + this.dirtyComponentsLength = dirtyComponents.length; + }, + close: function() { + if (this.dirtyComponentsLength !== dirtyComponents.length) { + // Additional updates were enqueued by componentDidUpdate handlers or + // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run + // these new updates so that if A's componentDidUpdate calls setState on + // B, B will update before the callback A's updater provided when calling + // setState. + dirtyComponents.splice(0, this.dirtyComponentsLength); + flushBatchedUpdates(); + } else { + dirtyComponents.length = 0; + } + } + }; + + var UPDATE_QUEUEING = { + initialize: function() { + this.callbackQueue.reset(); + }, + close: function() { + this.callbackQueue.notifyAll(); + } + }; + + var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; + + function ReactUpdatesFlushTransaction() { + this.reinitializeTransaction(); + this.dirtyComponentsLength = null; + this.callbackQueue = CallbackQueue.getPooled(); + this.reconcileTransaction = + ReactUpdates.ReactReconcileTransaction.getPooled(); + } + + assign( + ReactUpdatesFlushTransaction.prototype, + Transaction.Mixin, { + getTransactionWrappers: function() { + return TRANSACTION_WRAPPERS; + }, + + destructor: function() { + this.dirtyComponentsLength = null; + CallbackQueue.release(this.callbackQueue); + this.callbackQueue = null; + ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); + this.reconcileTransaction = null; + }, + + perform: function(method, scope, a) { + // Essentially calls `this.reconcileTransaction.perform(method, scope, a)` + // with this transaction's wrappers around it. + return Transaction.Mixin.perform.call( + this, + this.reconcileTransaction.perform, + this.reconcileTransaction, + method, + scope, + a + ); + } + }); + + PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); + + function batchedUpdates(callback, a, b, c, d) { + ensureInjected(); + batchingStrategy.batchedUpdates(callback, a, b, c, d); + } + + /** + * Array comparator for ReactComponents by mount ordering. + * + * @param {ReactComponent} c1 first component you're comparing + * @param {ReactComponent} c2 second component you're comparing + * @return {number} Return value usable by Array.prototype.sort(). + */ + function mountOrderComparator(c1, c2) { + return c1._mountOrder - c2._mountOrder; + } + + function runBatchedUpdates(transaction) { + var len = transaction.dirtyComponentsLength; + ( false ? invariant( + len === dirtyComponents.length, + 'Expected flush transaction\'s stored dirty-components length (%s) to ' + + 'match dirty-components array length (%s).', + len, + dirtyComponents.length + ) : invariant(len === dirtyComponents.length)); + + // Since reconciling a component higher in the owner hierarchy usually (not + // always -- see shouldComponentUpdate()) will reconcile children, reconcile + // them before their children by sorting the array. + dirtyComponents.sort(mountOrderComparator); + + for (var i = 0; i < len; i++) { + // If a component is unmounted before pending changes apply, it will still + // be here, but we assume that it has cleared its _pendingCallbacks and + // that performUpdateIfNecessary is a noop. + var component = dirtyComponents[i]; + + // If performUpdateIfNecessary happens to enqueue any new updates, we + // shouldn't execute the callbacks until the next render happens, so + // stash the callbacks first + var callbacks = component._pendingCallbacks; + component._pendingCallbacks = null; + + ReactReconciler.performUpdateIfNecessary( + component, + transaction.reconcileTransaction + ); + + if (callbacks) { + for (var j = 0; j < callbacks.length; j++) { + transaction.callbackQueue.enqueue( + callbacks[j], + component.getPublicInstance() + ); + } + } + } + } + + var flushBatchedUpdates = function() { + // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents + // array and perform any updates enqueued by mount-ready handlers (i.e., + // componentDidUpdate) but we need to check here too in order to catch + // updates enqueued by setState callbacks and asap calls. + while (dirtyComponents.length || asapEnqueued) { + if (dirtyComponents.length) { + var transaction = ReactUpdatesFlushTransaction.getPooled(); + transaction.perform(runBatchedUpdates, null, transaction); + ReactUpdatesFlushTransaction.release(transaction); + } + + if (asapEnqueued) { + asapEnqueued = false; + var queue = asapCallbackQueue; + asapCallbackQueue = CallbackQueue.getPooled(); + queue.notifyAll(); + CallbackQueue.release(queue); + } + } + }; + flushBatchedUpdates = ReactPerf.measure( + 'ReactUpdates', + 'flushBatchedUpdates', + flushBatchedUpdates + ); + + /** + * Mark a component as needing a rerender, adding an optional callback to a + * list of functions which will be executed once the rerender occurs. + */ + function enqueueUpdate(component) { + ensureInjected(); + + // Various parts of our code (such as ReactCompositeComponent's + // _renderValidatedComponent) assume that calls to render aren't nested; + // verify that that's the case. (This is called by each top-level update + // function, like setProps, setState, forceUpdate, etc.; creation and + // destruction of top-level components is guarded in ReactMount.) + ( false ? warning( + ReactCurrentOwner.current == null, + 'enqueueUpdate(): Render methods should be a pure function of props ' + + 'and state; triggering nested component updates from render is not ' + + 'allowed. If necessary, trigger nested updates in ' + + 'componentDidUpdate.' + ) : null); + + if (!batchingStrategy.isBatchingUpdates) { + batchingStrategy.batchedUpdates(enqueueUpdate, component); + return; + } + + dirtyComponents.push(component); + } + + /** + * Enqueue a callback to be run at the end of the current batching cycle. Throws + * if no updates are currently being performed. + */ + function asap(callback, context) { + ( false ? invariant( + batchingStrategy.isBatchingUpdates, + 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' + + 'updates are not being batched.' + ) : invariant(batchingStrategy.isBatchingUpdates)); + asapCallbackQueue.enqueue(callback, context); + asapEnqueued = true; + } + + var ReactUpdatesInjection = { + injectReconcileTransaction: function(ReconcileTransaction) { + ( false ? invariant( + ReconcileTransaction, + 'ReactUpdates: must provide a reconcile transaction class' + ) : invariant(ReconcileTransaction)); + ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; + }, + + injectBatchingStrategy: function(_batchingStrategy) { + ( false ? invariant( + _batchingStrategy, + 'ReactUpdates: must provide a batching strategy' + ) : invariant(_batchingStrategy)); + ( false ? invariant( + typeof _batchingStrategy.batchedUpdates === 'function', + 'ReactUpdates: must provide a batchedUpdates() function' + ) : invariant(typeof _batchingStrategy.batchedUpdates === 'function')); + ( false ? invariant( + typeof _batchingStrategy.isBatchingUpdates === 'boolean', + 'ReactUpdates: must provide an isBatchingUpdates boolean attribute' + ) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean')); + batchingStrategy = _batchingStrategy; + } + }; + + var ReactUpdates = { + /** + * React references `ReactReconcileTransaction` using this property in order + * to allow dependency injection. + * + * @internal + */ + ReactReconcileTransaction: null, + + batchedUpdates: batchedUpdates, + enqueueUpdate: enqueueUpdate, + flushBatchedUpdates: flushBatchedUpdates, + injection: ReactUpdatesInjection, + asap: asap + }; + + module.exports = ReactUpdates; + + +/***/ }, +/* 27 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CallbackQueue + */ + + 'use strict'; + + var PooledClass = __webpack_require__(9); + + var assign = __webpack_require__(13); + var invariant = __webpack_require__(7); + + /** + * A specialized pseudo-event module to help keep track of components waiting to + * be notified when their DOM representations are available for use. + * + * This implements `PooledClass`, so you should never need to instantiate this. + * Instead, use `CallbackQueue.getPooled()`. + * + * @class ReactMountReady + * @implements PooledClass + * @internal + */ + function CallbackQueue() { + this._callbacks = null; + this._contexts = null; + } + + assign(CallbackQueue.prototype, { + + /** + * Enqueues a callback to be invoked when `notifyAll` is invoked. + * + * @param {function} callback Invoked when `notifyAll` is invoked. + * @param {?object} context Context to call `callback` with. + * @internal + */ + enqueue: function(callback, context) { + this._callbacks = this._callbacks || []; + this._contexts = this._contexts || []; + this._callbacks.push(callback); + this._contexts.push(context); + }, + + /** + * Invokes all enqueued callbacks and clears the queue. This is invoked after + * the DOM representation of a component has been created or updated. + * + * @internal + */ + notifyAll: function() { + var callbacks = this._callbacks; + var contexts = this._contexts; + if (callbacks) { + ( false ? invariant( + callbacks.length === contexts.length, + 'Mismatched list of contexts in callback queue' + ) : invariant(callbacks.length === contexts.length)); + this._callbacks = null; + this._contexts = null; + for (var i = 0, l = callbacks.length; i < l; i++) { + callbacks[i].call(contexts[i]); + } + callbacks.length = 0; + contexts.length = 0; + } + }, + + /** + * Resets the internal queue. + * + * @internal + */ + reset: function() { + this._callbacks = null; + this._contexts = null; + }, + + /** + * `PooledClass` looks for this. + */ + destructor: function() { + this.reset(); + } + + }); + + PooledClass.addPoolingTo(CallbackQueue); + + module.exports = CallbackQueue; + + +/***/ }, +/* 28 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactPerf + * @typechecks static-only + */ + + 'use strict'; + + /** + * ReactPerf is a general AOP system designed to measure performance. This + * module only has the hooks: see ReactDefaultPerf for the analysis tool. + */ + var ReactPerf = { + /** + * Boolean to enable/disable measurement. Set to false by default to prevent + * accidental logging and perf loss. + */ + enableMeasure: false, + + /** + * Holds onto the measure function in use. By default, don't measure + * anything, but we'll override this if we inject a measure function. + */ + storedMeasure: _noMeasure, + + /** + * @param {object} object + * @param {string} objectName + * @param {object} methodNames + */ + measureMethods: function(object, objectName, methodNames) { + if (false) { + for (var key in methodNames) { + if (!methodNames.hasOwnProperty(key)) { + continue; + } + object[key] = ReactPerf.measure( + objectName, + methodNames[key], + object[key] + ); + } + } + }, + + /** + * Use this to wrap methods you want to measure. Zero overhead in production. + * + * @param {string} objName + * @param {string} fnName + * @param {function} func + * @return {function} + */ + measure: function(objName, fnName, func) { + if (false) { + var measuredFunc = null; + var wrapper = function() { + if (ReactPerf.enableMeasure) { + if (!measuredFunc) { + measuredFunc = ReactPerf.storedMeasure(objName, fnName, func); + } + return measuredFunc.apply(this, arguments); + } + return func.apply(this, arguments); + }; + wrapper.displayName = objName + '_' + fnName; + return wrapper; + } + return func; + }, + + injection: { + /** + * @param {function} measure + */ + injectMeasure: function(measure) { + ReactPerf.storedMeasure = measure; + } + } + }; + + /** + * Simply passes through the measured function, without measuring it. + * + * @param {string} objName + * @param {string} fnName + * @param {function} func + * @return {function} + */ + function _noMeasure(objName, fnName, func) { + return func; + } + + module.exports = ReactPerf; + + +/***/ }, +/* 29 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactReconciler + */ + + 'use strict'; + + var ReactRef = __webpack_require__(30); + var ReactElementValidator = __webpack_require__(32); + + /** + * Helper to call ReactRef.attachRefs with this composite component, split out + * to avoid allocations in the transaction mount-ready queue. + */ + function attachRefs() { + ReactRef.attachRefs(this, this._currentElement); + } + + var ReactReconciler = { + + /** + * Initializes the component, renders markup, and registers event listeners. + * + * @param {ReactComponent} internalInstance + * @param {string} rootID DOM ID of the root node. + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @return {?string} Rendered markup to be inserted into the DOM. + * @final + * @internal + */ + mountComponent: function(internalInstance, rootID, transaction, context) { + var markup = internalInstance.mountComponent(rootID, transaction, context); + if (false) { + ReactElementValidator.checkAndWarnForMutatedProps( + internalInstance._currentElement + ); + } + transaction.getReactMountReady().enqueue(attachRefs, internalInstance); + return markup; + }, + + /** + * Releases any resources allocated by `mountComponent`. + * + * @final + * @internal + */ + unmountComponent: function(internalInstance) { + ReactRef.detachRefs(internalInstance, internalInstance._currentElement); + internalInstance.unmountComponent(); + }, + + /** + * Update a component using a new element. + * + * @param {ReactComponent} internalInstance + * @param {ReactElement} nextElement + * @param {ReactReconcileTransaction} transaction + * @param {object} context + * @internal + */ + receiveComponent: function( + internalInstance, nextElement, transaction, context + ) { + var prevElement = internalInstance._currentElement; + + if (nextElement === prevElement && nextElement._owner != null) { + // Since elements are immutable after the owner is rendered, + // we can do a cheap identity compare here to determine if this is a + // superfluous reconcile. It's possible for state to be mutable but such + // change should trigger an update of the owner which would recreate + // the element. We explicitly check for the existence of an owner since + // it's possible for an element created outside a composite to be + // deeply mutated and reused. + return; + } + + if (false) { + ReactElementValidator.checkAndWarnForMutatedProps(nextElement); + } + + var refsChanged = ReactRef.shouldUpdateRefs( + prevElement, + nextElement + ); + + if (refsChanged) { + ReactRef.detachRefs(internalInstance, prevElement); + } + + internalInstance.receiveComponent(nextElement, transaction, context); + + if (refsChanged) { + transaction.getReactMountReady().enqueue(attachRefs, internalInstance); + } + }, + + /** + * Flush any dirty changes in a component. + * + * @param {ReactComponent} internalInstance + * @param {ReactReconcileTransaction} transaction + * @internal + */ + performUpdateIfNecessary: function( + internalInstance, + transaction + ) { + internalInstance.performUpdateIfNecessary(transaction); + } + + }; + + module.exports = ReactReconciler; + + +/***/ }, +/* 30 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactRef + */ + + 'use strict'; + + var ReactOwner = __webpack_require__(31); + + var ReactRef = {}; + + function attachRef(ref, component, owner) { + if (typeof ref === 'function') { + ref(component.getPublicInstance()); + } else { + // Legacy ref + ReactOwner.addComponentAsRefTo(component, ref, owner); + } + } + + function detachRef(ref, component, owner) { + if (typeof ref === 'function') { + ref(null); + } else { + // Legacy ref + ReactOwner.removeComponentAsRefFrom(component, ref, owner); + } + } + + ReactRef.attachRefs = function(instance, element) { + var ref = element.ref; + if (ref != null) { + attachRef(ref, instance, element._owner); + } + }; + + ReactRef.shouldUpdateRefs = function(prevElement, nextElement) { + // If either the owner or a `ref` has changed, make sure the newest owner + // has stored a reference to `this`, and the previous owner (if different) + // has forgotten the reference to `this`. We use the element instead + // of the public this.props because the post processing cannot determine + // a ref. The ref conceptually lives on the element. + + // TODO: Should this even be possible? The owner cannot change because + // it's forbidden by shouldUpdateReactComponent. The ref can change + // if you swap the keys of but not the refs. Reconsider where this check + // is made. It probably belongs where the key checking and + // instantiateReactComponent is done. + + return ( + nextElement._owner !== prevElement._owner || + nextElement.ref !== prevElement.ref + ); + }; + + ReactRef.detachRefs = function(instance, element) { + var ref = element.ref; + if (ref != null) { + detachRef(ref, instance, element._owner); + } + }; + + module.exports = ReactRef; + + +/***/ }, +/* 31 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactOwner + */ + + 'use strict'; + + var invariant = __webpack_require__(7); + + /** + * ReactOwners are capable of storing references to owned components. + * + * All components are capable of //being// referenced by owner components, but + * only ReactOwner components are capable of //referencing// owned components. + * The named reference is known as a "ref". + * + * Refs are available when mounted and updated during reconciliation. + * + * var MyComponent = React.createClass({ + * render: function() { + * return ( + *
+ * + *
+ * ); + * }, + * handleClick: function() { + * this.refs.custom.handleClick(); + * }, + * componentDidMount: function() { + * this.refs.custom.initialize(); + * } + * }); + * + * Refs should rarely be used. When refs are used, they should only be done to + * control data that is not handled by React's data flow. + * + * @class ReactOwner + */ + var ReactOwner = { + + /** + * @param {?object} object + * @return {boolean} True if `object` is a valid owner. + * @final + */ + isValidOwner: function(object) { + return !!( + (object && + typeof object.attachRef === 'function' && typeof object.detachRef === 'function') + ); + }, + + /** + * Adds a component by ref to an owner component. + * + * @param {ReactComponent} component Component to reference. + * @param {string} ref Name by which to refer to the component. + * @param {ReactOwner} owner Component on which to record the ref. + * @final + * @internal + */ + addComponentAsRefTo: function(component, ref, owner) { + ( false ? invariant( + ReactOwner.isValidOwner(owner), + 'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' + + 'usually means that you\'re trying to add a ref to a component that ' + + 'doesn\'t have an owner (that is, was not created inside of another ' + + 'component\'s `render` method). Try rendering this component inside of ' + + 'a new top-level component which will hold the ref.' + ) : invariant(ReactOwner.isValidOwner(owner))); + owner.attachRef(ref, component); + }, + + /** + * Removes a component by ref from an owner component. + * + * @param {ReactComponent} component Component to dereference. + * @param {string} ref Name of the ref to remove. + * @param {ReactOwner} owner Component on which the ref is recorded. + * @final + * @internal + */ + removeComponentAsRefFrom: function(component, ref, owner) { + ( false ? invariant( + ReactOwner.isValidOwner(owner), + 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' + + 'usually means that you\'re trying to remove a ref to a component that ' + + 'doesn\'t have an owner (that is, was not created inside of another ' + + 'component\'s `render` method). Try rendering this component inside of ' + + 'a new top-level component which will hold the ref.' + ) : invariant(ReactOwner.isValidOwner(owner))); + // Check that `component` is still the current ref because we do not want to + // detach the ref if another component stole it. + if (owner.getPublicInstance().refs[ref] === component.getPublicInstance()) { + owner.detachRef(ref); + } + } + + }; + + module.exports = ReactOwner; + + +/***/ }, +/* 32 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactElementValidator + */ + + /** + * ReactElementValidator provides a wrapper around a element factory + * which validates the props passed to the element. This is intended to be + * used only in DEV and could be replaced by a static type checker for languages + * that support it. + */ + + 'use strict'; + + var ReactElement = __webpack_require__(11); + var ReactFragment = __webpack_require__(10); + var ReactPropTypeLocations = __webpack_require__(33); + var ReactPropTypeLocationNames = __webpack_require__(34); + var ReactCurrentOwner = __webpack_require__(17); + var ReactNativeComponent = __webpack_require__(35); + + var getIteratorFn = __webpack_require__(21); + var invariant = __webpack_require__(7); + var warning = __webpack_require__(15); + + function getDeclarationErrorAddendum() { + if (ReactCurrentOwner.current) { + var name = ReactCurrentOwner.current.getName(); + if (name) { + return ' Check the render method of `' + name + '`.'; + } + } + return ''; + } + + /** + * Warn if there's no key explicitly set on dynamic arrays of children or + * object keys are not valid. This allows us to keep track of children between + * updates. + */ + var ownerHasKeyUseWarning = {}; + + var loggedTypeFailures = {}; + + var NUMERIC_PROPERTY_REGEX = /^\d+$/; + + /** + * Gets the instance's name for use in warnings. + * + * @internal + * @return {?string} Display name or undefined + */ + function getName(instance) { + var publicInstance = instance && instance.getPublicInstance(); + if (!publicInstance) { + return undefined; + } + var constructor = publicInstance.constructor; + if (!constructor) { + return undefined; + } + return constructor.displayName || constructor.name || undefined; + } + + /** + * Gets the current owner's displayName for use in warnings. + * + * @internal + * @return {?string} Display name or undefined + */ + function getCurrentOwnerDisplayName() { + var current = ReactCurrentOwner.current; + return ( + current && getName(current) || undefined + ); + } + + /** + * Warn if the element doesn't have an explicit key assigned to it. + * This element is in an array. The array could grow and shrink or be + * reordered. All children that haven't already been validated are required to + * have a "key" property assigned to it. + * + * @internal + * @param {ReactElement} element Element that requires a key. + * @param {*} parentType element's parent's type. + */ + function validateExplicitKey(element, parentType) { + if (element._store.validated || element.key != null) { + return; + } + element._store.validated = true; + + warnAndMonitorForKeyUse( + 'Each child in an array or iterator should have a unique "key" prop.', + element, + parentType + ); + } + + /** + * Warn if the key is being defined as an object property but has an incorrect + * value. + * + * @internal + * @param {string} name Property name of the key. + * @param {ReactElement} element Component that requires a key. + * @param {*} parentType element's parent's type. + */ + function validatePropertyKey(name, element, parentType) { + if (!NUMERIC_PROPERTY_REGEX.test(name)) { + return; + } + warnAndMonitorForKeyUse( + 'Child objects should have non-numeric keys so ordering is preserved.', + element, + parentType + ); + } + + /** + * Shared warning and monitoring code for the key warnings. + * + * @internal + * @param {string} message The base warning that gets output. + * @param {ReactElement} element Component that requires a key. + * @param {*} parentType element's parent's type. + */ + function warnAndMonitorForKeyUse(message, element, parentType) { + var ownerName = getCurrentOwnerDisplayName(); + var parentName = typeof parentType === 'string' ? + parentType : parentType.displayName || parentType.name; + + var useName = ownerName || parentName; + var memoizer = ownerHasKeyUseWarning[message] || ( + (ownerHasKeyUseWarning[message] = {}) + ); + if (memoizer.hasOwnProperty(useName)) { + return; + } + memoizer[useName] = true; + + var parentOrOwnerAddendum = + ownerName ? (" Check the render method of " + ownerName + ".") : + parentName ? (" Check the React.render call using <" + parentName + ">.") : + ''; + + // Usually the current owner is the offender, but if it accepts children as a + // property, it may be the creator of the child that's responsible for + // assigning it a key. + var childOwnerAddendum = ''; + if (element && + element._owner && + element._owner !== ReactCurrentOwner.current) { + // Name of the component that originally created this child. + var childOwnerName = getName(element._owner); + + childOwnerAddendum = (" It was passed a child from " + childOwnerName + "."); + } + + ( false ? warning( + false, + message + '%s%s See https://fb.me/react-warning-keys for more information.', + parentOrOwnerAddendum, + childOwnerAddendum + ) : null); + } + + /** + * Ensure that every element either is passed in a static location, in an + * array with an explicit keys property defined, or in an object literal + * with valid key property. + * + * @internal + * @param {ReactNode} node Statically passed child of any type. + * @param {*} parentType node's parent's type. + */ + function validateChildKeys(node, parentType) { + if (Array.isArray(node)) { + for (var i = 0; i < node.length; i++) { + var child = node[i]; + if (ReactElement.isValidElement(child)) { + validateExplicitKey(child, parentType); + } + } + } else if (ReactElement.isValidElement(node)) { + // This element was passed in a valid location. + node._store.validated = true; + } else if (node) { + var iteratorFn = getIteratorFn(node); + // Entry iterators provide implicit keys. + if (iteratorFn) { + if (iteratorFn !== node.entries) { + var iterator = iteratorFn.call(node); + var step; + while (!(step = iterator.next()).done) { + if (ReactElement.isValidElement(step.value)) { + validateExplicitKey(step.value, parentType); + } + } + } + } else if (typeof node === 'object') { + var fragment = ReactFragment.extractIfFragment(node); + for (var key in fragment) { + if (fragment.hasOwnProperty(key)) { + validatePropertyKey(key, fragment[key], parentType); + } + } + } + } + } + + /** + * Assert that the props are valid + * + * @param {string} componentName Name of the component for error messages. + * @param {object} propTypes Map of prop name to a ReactPropType + * @param {object} props + * @param {string} location e.g. "prop", "context", "child context" + * @private + */ + function checkPropTypes(componentName, propTypes, props, location) { + for (var propName in propTypes) { + if (propTypes.hasOwnProperty(propName)) { + var error; + // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + ( false ? invariant( + typeof propTypes[propName] === 'function', + '%s: %s type `%s` is invalid; it must be a function, usually from ' + + 'React.PropTypes.', + componentName || 'React class', + ReactPropTypeLocationNames[location], + propName + ) : invariant(typeof propTypes[propName] === 'function')); + error = propTypes[propName](props, propName, componentName, location); + } catch (ex) { + error = ex; + } + if (error instanceof Error && !(error.message in loggedTypeFailures)) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error.message] = true; + + var addendum = getDeclarationErrorAddendum(this); + ( false ? warning(false, 'Failed propType: %s%s', error.message, addendum) : null); + } + } + } + } + + var warnedPropsMutations = {}; + + /** + * Warn about mutating props when setting `propName` on `element`. + * + * @param {string} propName The string key within props that was set + * @param {ReactElement} element + */ + function warnForPropsMutation(propName, element) { + var type = element.type; + var elementName = typeof type === 'string' ? type : type.displayName; + var ownerName = element._owner ? + element._owner.getPublicInstance().constructor.displayName : null; + + var warningKey = propName + '|' + elementName + '|' + ownerName; + if (warnedPropsMutations.hasOwnProperty(warningKey)) { + return; + } + warnedPropsMutations[warningKey] = true; + + var elementInfo = ''; + if (elementName) { + elementInfo = ' <' + elementName + ' />'; + } + var ownerInfo = ''; + if (ownerName) { + ownerInfo = ' The element was created by ' + ownerName + '.'; + } + + ( false ? warning( + false, + 'Don\'t set .props.%s of the React component%s. Instead, specify the ' + + 'correct value when initially creating the element or use ' + + 'React.cloneElement to make a new element with updated props.%s', + propName, + elementInfo, + ownerInfo + ) : null); + } + + // Inline Object.is polyfill + function is(a, b) { + if (a !== a) { + // NaN + return b !== b; + } + if (a === 0 && b === 0) { + // +-0 + return 1 / a === 1 / b; + } + return a === b; + } + + /** + * Given an element, check if its props have been mutated since element + * creation (or the last call to this function). In particular, check if any + * new props have been added, which we can't directly catch by defining warning + * properties on the props object. + * + * @param {ReactElement} element + */ + function checkAndWarnForMutatedProps(element) { + if (!element._store) { + // Element was created using `new ReactElement` directly or with + // `ReactElement.createElement`; skip mutation checking + return; + } + + var originalProps = element._store.originalProps; + var props = element.props; + + for (var propName in props) { + if (props.hasOwnProperty(propName)) { + if (!originalProps.hasOwnProperty(propName) || + !is(originalProps[propName], props[propName])) { + warnForPropsMutation(propName, element); + + // Copy over the new value so that the two props objects match again + originalProps[propName] = props[propName]; + } + } + } + } + + /** + * Given an element, validate that its props follow the propTypes definition, + * provided by the type. + * + * @param {ReactElement} element + */ + function validatePropTypes(element) { + if (element.type == null) { + // This has already warned. Don't throw. + return; + } + // Extract the component class from the element. Converts string types + // to a composite class which may have propTypes. + // TODO: Validating a string's propTypes is not decoupled from the + // rendering target which is problematic. + var componentClass = ReactNativeComponent.getComponentClassForElement( + element + ); + var name = componentClass.displayName || componentClass.name; + if (componentClass.propTypes) { + checkPropTypes( + name, + componentClass.propTypes, + element.props, + ReactPropTypeLocations.prop + ); + } + if (typeof componentClass.getDefaultProps === 'function') { + ( false ? warning( + componentClass.getDefaultProps.isReactClassApproved, + 'getDefaultProps is only used on classic React.createClass ' + + 'definitions. Use a static property named `defaultProps` instead.' + ) : null); + } + } + + var ReactElementValidator = { + + checkAndWarnForMutatedProps: checkAndWarnForMutatedProps, + + createElement: function(type, props, children) { + // We warn in this case but don't throw. We expect the element creation to + // succeed and there will likely be errors in render. + ( false ? warning( + type != null, + 'React.createElement: type should not be null or undefined. It should ' + + 'be a string (for DOM elements) or a ReactClass (for composite ' + + 'components).' + ) : null); + + var element = ReactElement.createElement.apply(this, arguments); + + // The result can be nullish if a mock or a custom function is used. + // TODO: Drop this when these are no longer allowed as the type argument. + if (element == null) { + return element; + } + + for (var i = 2; i < arguments.length; i++) { + validateChildKeys(arguments[i], type); + } + + validatePropTypes(element); + + return element; + }, + + createFactory: function(type) { + var validatedFactory = ReactElementValidator.createElement.bind( + null, + type + ); + // Legacy hook TODO: Warn if this is accessed + validatedFactory.type = type; + + if (false) { + try { + Object.defineProperty( + validatedFactory, + 'type', + { + enumerable: false, + get: function() { + ("production" !== process.env.NODE_ENV ? warning( + false, + 'Factory.type is deprecated. Access the class directly ' + + 'before passing it to createFactory.' + ) : null); + Object.defineProperty(this, 'type', { + value: type + }); + return type; + } + } + ); + } catch (x) { + // IE will fail on defineProperty (es5-shim/sham too) + } + } + + + return validatedFactory; + }, + + cloneElement: function(element, props, children) { + var newElement = ReactElement.cloneElement.apply(this, arguments); + for (var i = 2; i < arguments.length; i++) { + validateChildKeys(arguments[i], newElement.type); + } + validatePropTypes(newElement); + return newElement; + } + + }; + + module.exports = ReactElementValidator; + + +/***/ }, +/* 33 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactPropTypeLocations + */ + + 'use strict'; + + var keyMirror = __webpack_require__(6); + + var ReactPropTypeLocations = keyMirror({ + prop: null, + context: null, + childContext: null + }); + + module.exports = ReactPropTypeLocations; + + +/***/ }, +/* 34 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactPropTypeLocationNames + */ + + 'use strict'; + + var ReactPropTypeLocationNames = {}; + + if (false) { + ReactPropTypeLocationNames = { + prop: 'prop', + context: 'context', + childContext: 'child context' + }; + } + + module.exports = ReactPropTypeLocationNames; + + +/***/ }, +/* 35 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactNativeComponent + */ + + 'use strict'; + + var assign = __webpack_require__(13); + var invariant = __webpack_require__(7); + + var autoGenerateWrapperClass = null; + var genericComponentClass = null; + // This registry keeps track of wrapper classes around native tags + var tagToComponentClass = {}; + var textComponentClass = null; + + var ReactNativeComponentInjection = { + // This accepts a class that receives the tag string. This is a catch all + // that can render any kind of tag. + injectGenericComponentClass: function(componentClass) { + genericComponentClass = componentClass; + }, + // This accepts a text component class that takes the text string to be + // rendered as props. + injectTextComponentClass: function(componentClass) { + textComponentClass = componentClass; + }, + // This accepts a keyed object with classes as values. Each key represents a + // tag. That particular tag will use this class instead of the generic one. + injectComponentClasses: function(componentClasses) { + assign(tagToComponentClass, componentClasses); + }, + // Temporary hack since we expect DOM refs to behave like composites, + // for this release. + injectAutoWrapper: function(wrapperFactory) { + autoGenerateWrapperClass = wrapperFactory; + } + }; + + /** + * Get a composite component wrapper class for a specific tag. + * + * @param {ReactElement} element The tag for which to get the class. + * @return {function} The React class constructor function. + */ + function getComponentClassForElement(element) { + if (typeof element.type === 'function') { + return element.type; + } + var tag = element.type; + var componentClass = tagToComponentClass[tag]; + if (componentClass == null) { + tagToComponentClass[tag] = componentClass = autoGenerateWrapperClass(tag); + } + return componentClass; + } + + /** + * Get a native internal component class for a specific tag. + * + * @param {ReactElement} element The element to create. + * @return {function} The internal class constructor function. + */ + function createInternalComponent(element) { + ( false ? invariant( + genericComponentClass, + 'There is no registered component for the tag %s', + element.type + ) : invariant(genericComponentClass)); + return new genericComponentClass(element.type, element.props); + } + + /** + * @param {ReactText} text + * @return {ReactComponent} + */ + function createInstanceForText(text) { + return new textComponentClass(text); + } + + /** + * @param {ReactComponent} component + * @return {boolean} + */ + function isTextComponent(component) { + return component instanceof textComponentClass; + } + + var ReactNativeComponent = { + getComponentClassForElement: getComponentClassForElement, + createInternalComponent: createInternalComponent, + createInstanceForText: createInstanceForText, + isTextComponent: isTextComponent, + injection: ReactNativeComponentInjection + }; + + module.exports = ReactNativeComponent; + + +/***/ }, +/* 36 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule Transaction + */ + + 'use strict'; + + var invariant = __webpack_require__(7); + + /** + * `Transaction` creates a black box that is able to wrap any method such that + * certain invariants are maintained before and after the method is invoked + * (Even if an exception is thrown while invoking the wrapped method). Whoever + * instantiates a transaction can provide enforcers of the invariants at + * creation time. The `Transaction` class itself will supply one additional + * automatic invariant for you - the invariant that any transaction instance + * should not be run while it is already being run. You would typically create a + * single instance of a `Transaction` for reuse multiple times, that potentially + * is used to wrap several different methods. Wrappers are extremely simple - + * they only require implementing two methods. + * + *
+	 *                       wrappers (injected at creation time)
+	 *                                      +        +
+	 *                                      |        |
+	 *                    +-----------------|--------|--------------+
+	 *                    |                 v        |              |
+	 *                    |      +---------------+   |              |
+	 *                    |   +--|    wrapper1   |---|----+         |
+	 *                    |   |  +---------------+   v    |         |
+	 *                    |   |          +-------------+  |         |
+	 *                    |   |     +----|   wrapper2  |--------+   |
+	 *                    |   |     |    +-------------+  |     |   |
+	 *                    |   |     |                     |     |   |
+	 *                    |   v     v                     v     v   | wrapper
+	 *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
+	 * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
+	 * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
+	 *                    | |   | |   |   |         |   |   | |   | |
+	 *                    | |   | |   |   |         |   |   | |   | |
+	 *                    | |   | |   |   |         |   |   | |   | |
+	 *                    | +---+ +---+   +---------+   +---+ +---+ |
+	 *                    |  initialize                    close    |
+	 *                    +-----------------------------------------+
+	 * 
+ * + * Use cases: + * - Preserving the input selection ranges before/after reconciliation. + * Restoring selection even in the event of an unexpected error. + * - Deactivating events while rearranging the DOM, preventing blurs/focuses, + * while guaranteeing that afterwards, the event system is reactivated. + * - Flushing a queue of collected DOM mutations to the main UI thread after a + * reconciliation takes place in a worker thread. + * - Invoking any collected `componentDidUpdate` callbacks after rendering new + * content. + * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue + * to preserve the `scrollTop` (an automatic scroll aware DOM). + * - (Future use case): Layout calculations before and after DOM updates. + * + * Transactional plugin API: + * - A module that has an `initialize` method that returns any precomputation. + * - and a `close` method that accepts the precomputation. `close` is invoked + * when the wrapped process is completed, or has failed. + * + * @param {Array} transactionWrapper Wrapper modules + * that implement `initialize` and `close`. + * @return {Transaction} Single transaction for reuse in thread. + * + * @class Transaction + */ + var Mixin = { + /** + * Sets up this instance so that it is prepared for collecting metrics. Does + * so such that this setup method may be used on an instance that is already + * initialized, in a way that does not consume additional memory upon reuse. + * That can be useful if you decide to make your subclass of this mixin a + * "PooledClass". + */ + reinitializeTransaction: function() { + this.transactionWrappers = this.getTransactionWrappers(); + if (!this.wrapperInitData) { + this.wrapperInitData = []; + } else { + this.wrapperInitData.length = 0; + } + this._isInTransaction = false; + }, + + _isInTransaction: false, + + /** + * @abstract + * @return {Array} Array of transaction wrappers. + */ + getTransactionWrappers: null, + + isInTransaction: function() { + return !!this._isInTransaction; + }, + + /** + * Executes the function within a safety window. Use this for the top level + * methods that result in large amounts of computation/mutations that would + * need to be safety checked. + * + * @param {function} method Member of scope to call. + * @param {Object} scope Scope to invoke from. + * @param {Object?=} args... Arguments to pass to the method (optional). + * Helps prevent need to bind in many cases. + * @return Return value from `method`. + */ + perform: function(method, scope, a, b, c, d, e, f) { + ( false ? invariant( + !this.isInTransaction(), + 'Transaction.perform(...): Cannot initialize a transaction when there ' + + 'is already an outstanding transaction.' + ) : invariant(!this.isInTransaction())); + var errorThrown; + var ret; + try { + this._isInTransaction = true; + // Catching errors makes debugging more difficult, so we start with + // errorThrown set to true before setting it to false after calling + // close -- if it's still set to true in the finally block, it means + // one of these calls threw. + errorThrown = true; + this.initializeAll(0); + ret = method.call(scope, a, b, c, d, e, f); + errorThrown = false; + } finally { + try { + if (errorThrown) { + // If `method` throws, prefer to show that stack trace over any thrown + // by invoking `closeAll`. + try { + this.closeAll(0); + } catch (err) { + } + } else { + // Since `method` didn't throw, we don't want to silence the exception + // here. + this.closeAll(0); + } + } finally { + this._isInTransaction = false; + } + } + return ret; + }, + + initializeAll: function(startIndex) { + var transactionWrappers = this.transactionWrappers; + for (var i = startIndex; i < transactionWrappers.length; i++) { + var wrapper = transactionWrappers[i]; + try { + // Catching errors makes debugging more difficult, so we start with the + // OBSERVED_ERROR state before overwriting it with the real return value + // of initialize -- if it's still set to OBSERVED_ERROR in the finally + // block, it means wrapper.initialize threw. + this.wrapperInitData[i] = Transaction.OBSERVED_ERROR; + this.wrapperInitData[i] = wrapper.initialize ? + wrapper.initialize.call(this) : + null; + } finally { + if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) { + // The initializer for wrapper i threw an error; initialize the + // remaining wrappers but silence any exceptions from them to ensure + // that the first error is the one to bubble up. + try { + this.initializeAll(i + 1); + } catch (err) { + } + } + } + } + }, + + /** + * Invokes each of `this.transactionWrappers.close[i]` functions, passing into + * them the respective return values of `this.transactionWrappers.init[i]` + * (`close`rs that correspond to initializers that failed will not be + * invoked). + */ + closeAll: function(startIndex) { + ( false ? invariant( + this.isInTransaction(), + 'Transaction.closeAll(): Cannot close transaction when none are open.' + ) : invariant(this.isInTransaction())); + var transactionWrappers = this.transactionWrappers; + for (var i = startIndex; i < transactionWrappers.length; i++) { + var wrapper = transactionWrappers[i]; + var initData = this.wrapperInitData[i]; + var errorThrown; + try { + // Catching errors makes debugging more difficult, so we start with + // errorThrown set to true before setting it to false after calling + // close -- if it's still set to true in the finally block, it means + // wrapper.close threw. + errorThrown = true; + if (initData !== Transaction.OBSERVED_ERROR && wrapper.close) { + wrapper.close.call(this, initData); + } + errorThrown = false; + } finally { + if (errorThrown) { + // The closer for wrapper i threw an error; close the remaining + // wrappers but silence any exceptions from them to ensure that the + // first error is the one to bubble up. + try { + this.closeAll(i + 1); + } catch (e) { + } + } + } + } + this.wrapperInitData.length = 0; + } + }; + + var Transaction = { + + Mixin: Mixin, + + /** + * Token to look for to determine if an error occured. + */ + OBSERVED_ERROR: {} + + }; + + module.exports = Transaction; + + +/***/ }, +/* 37 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactClass + */ + + 'use strict'; + + var ReactComponent = __webpack_require__(22); + var ReactCurrentOwner = __webpack_require__(17); + var ReactElement = __webpack_require__(11); + var ReactErrorUtils = __webpack_require__(38); + var ReactInstanceMap = __webpack_require__(25); + var ReactLifeCycle = __webpack_require__(24); + var ReactPropTypeLocations = __webpack_require__(33); + var ReactPropTypeLocationNames = __webpack_require__(34); + var ReactUpdateQueue = __webpack_require__(23); + + var assign = __webpack_require__(13); + var invariant = __webpack_require__(7); + var keyMirror = __webpack_require__(6); + var keyOf = __webpack_require__(39); + var warning = __webpack_require__(15); + + var MIXINS_KEY = keyOf({mixins: null}); + + /** + * Policies that describe methods in `ReactClassInterface`. + */ + var SpecPolicy = keyMirror({ + /** + * These methods may be defined only once by the class specification or mixin. + */ + DEFINE_ONCE: null, + /** + * These methods may be defined by both the class specification and mixins. + * Subsequent definitions will be chained. These methods must return void. + */ + DEFINE_MANY: null, + /** + * These methods are overriding the base class. + */ + OVERRIDE_BASE: null, + /** + * These methods are similar to DEFINE_MANY, except we assume they return + * objects. We try to merge the keys of the return values of all the mixed in + * functions. If there is a key conflict we throw. + */ + DEFINE_MANY_MERGED: null + }); + + + var injectedMixins = []; + + /** + * Composite components are higher-level components that compose other composite + * or native components. + * + * To create a new type of `ReactClass`, pass a specification of + * your new class to `React.createClass`. The only requirement of your class + * specification is that you implement a `render` method. + * + * var MyComponent = React.createClass({ + * render: function() { + * return
Hello World
; + * } + * }); + * + * The class specification supports a specific protocol of methods that have + * special meaning (e.g. `render`). See `ReactClassInterface` for + * more the comprehensive protocol. Any other properties and methods in the + * class specification will available on the prototype. + * + * @interface ReactClassInterface + * @internal + */ + var ReactClassInterface = { + + /** + * An array of Mixin objects to include when defining your component. + * + * @type {array} + * @optional + */ + mixins: SpecPolicy.DEFINE_MANY, + + /** + * An object containing properties and methods that should be defined on + * the component's constructor instead of its prototype (static methods). + * + * @type {object} + * @optional + */ + statics: SpecPolicy.DEFINE_MANY, + + /** + * Definition of prop types for this component. + * + * @type {object} + * @optional + */ + propTypes: SpecPolicy.DEFINE_MANY, + + /** + * Definition of context types for this component. + * + * @type {object} + * @optional + */ + contextTypes: SpecPolicy.DEFINE_MANY, + + /** + * Definition of context types this component sets for its children. + * + * @type {object} + * @optional + */ + childContextTypes: SpecPolicy.DEFINE_MANY, + + // ==== Definition methods ==== + + /** + * Invoked when the component is mounted. Values in the mapping will be set on + * `this.props` if that prop is not specified (i.e. using an `in` check). + * + * This method is invoked before `getInitialState` and therefore cannot rely + * on `this.state` or use `this.setState`. + * + * @return {object} + * @optional + */ + getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * Invoked once before the component is mounted. The return value will be used + * as the initial value of `this.state`. + * + * getInitialState: function() { + * return { + * isOn: false, + * fooBaz: new BazFoo() + * } + * } + * + * @return {object} + * @optional + */ + getInitialState: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * @return {object} + * @optional + */ + getChildContext: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * Uses props from `this.props` and state from `this.state` to render the + * structure of the component. + * + * No guarantees are made about when or how often this method is invoked, so + * it must not have side effects. + * + * render: function() { + * var name = this.props.name; + * return
Hello, {name}!
; + * } + * + * @return {ReactComponent} + * @nosideeffects + * @required + */ + render: SpecPolicy.DEFINE_ONCE, + + + + // ==== Delegate methods ==== + + /** + * Invoked when the component is initially created and about to be mounted. + * This may have side effects, but any external subscriptions or data created + * by this method must be cleaned up in `componentWillUnmount`. + * + * @optional + */ + componentWillMount: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component has been mounted and has a DOM representation. + * However, there is no guarantee that the DOM node is in the document. + * + * Use this as an opportunity to operate on the DOM when the component has + * been mounted (initialized and rendered) for the first time. + * + * @param {DOMElement} rootNode DOM element representing the component. + * @optional + */ + componentDidMount: SpecPolicy.DEFINE_MANY, + + /** + * Invoked before the component receives new props. + * + * Use this as an opportunity to react to a prop transition by updating the + * state using `this.setState`. Current props are accessed via `this.props`. + * + * componentWillReceiveProps: function(nextProps, nextContext) { + * this.setState({ + * likesIncreasing: nextProps.likeCount > this.props.likeCount + * }); + * } + * + * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop + * transition may cause a state change, but the opposite is not true. If you + * need it, you are probably looking for `componentWillUpdate`. + * + * @param {object} nextProps + * @optional + */ + componentWillReceiveProps: SpecPolicy.DEFINE_MANY, + + /** + * Invoked while deciding if the component should be updated as a result of + * receiving new props, state and/or context. + * + * Use this as an opportunity to `return false` when you're certain that the + * transition to the new props/state/context will not require a component + * update. + * + * shouldComponentUpdate: function(nextProps, nextState, nextContext) { + * return !equal(nextProps, this.props) || + * !equal(nextState, this.state) || + * !equal(nextContext, this.context); + * } + * + * @param {object} nextProps + * @param {?object} nextState + * @param {?object} nextContext + * @return {boolean} True if the component should update. + * @optional + */ + shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, + + /** + * Invoked when the component is about to update due to a transition from + * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` + * and `nextContext`. + * + * Use this as an opportunity to perform preparation before an update occurs. + * + * NOTE: You **cannot** use `this.setState()` in this method. + * + * @param {object} nextProps + * @param {?object} nextState + * @param {?object} nextContext + * @param {ReactReconcileTransaction} transaction + * @optional + */ + componentWillUpdate: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component's DOM representation has been updated. + * + * Use this as an opportunity to operate on the DOM when the component has + * been updated. + * + * @param {object} prevProps + * @param {?object} prevState + * @param {?object} prevContext + * @param {DOMElement} rootNode DOM element representing the component. + * @optional + */ + componentDidUpdate: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component is about to be removed from its parent and have + * its DOM representation destroyed. + * + * Use this as an opportunity to deallocate any external resources. + * + * NOTE: There is no `componentDidUnmount` since your component will have been + * destroyed by that point. + * + * @optional + */ + componentWillUnmount: SpecPolicy.DEFINE_MANY, + + + + // ==== Advanced methods ==== + + /** + * Updates the component's currently mounted DOM representation. + * + * By default, this implements React's rendering and reconciliation algorithm. + * Sophisticated clients may wish to override this. + * + * @param {ReactReconcileTransaction} transaction + * @internal + * @overridable + */ + updateComponent: SpecPolicy.OVERRIDE_BASE + + }; + + /** + * Mapping from class specification keys to special processing functions. + * + * Although these are declared like instance properties in the specification + * when defining classes using `React.createClass`, they are actually static + * and are accessible on the constructor instead of the prototype. Despite + * being static, they must be defined outside of the "statics" key under + * which all other static methods are defined. + */ + var RESERVED_SPEC_KEYS = { + displayName: function(Constructor, displayName) { + Constructor.displayName = displayName; + }, + mixins: function(Constructor, mixins) { + if (mixins) { + for (var i = 0; i < mixins.length; i++) { + mixSpecIntoComponent(Constructor, mixins[i]); + } + } + }, + childContextTypes: function(Constructor, childContextTypes) { + if (false) { + validateTypeDef( + Constructor, + childContextTypes, + ReactPropTypeLocations.childContext + ); + } + Constructor.childContextTypes = assign( + {}, + Constructor.childContextTypes, + childContextTypes + ); + }, + contextTypes: function(Constructor, contextTypes) { + if (false) { + validateTypeDef( + Constructor, + contextTypes, + ReactPropTypeLocations.context + ); + } + Constructor.contextTypes = assign( + {}, + Constructor.contextTypes, + contextTypes + ); + }, + /** + * Special case getDefaultProps which should move into statics but requires + * automatic merging. + */ + getDefaultProps: function(Constructor, getDefaultProps) { + if (Constructor.getDefaultProps) { + Constructor.getDefaultProps = createMergedResultFunction( + Constructor.getDefaultProps, + getDefaultProps + ); + } else { + Constructor.getDefaultProps = getDefaultProps; + } + }, + propTypes: function(Constructor, propTypes) { + if (false) { + validateTypeDef( + Constructor, + propTypes, + ReactPropTypeLocations.prop + ); + } + Constructor.propTypes = assign( + {}, + Constructor.propTypes, + propTypes + ); + }, + statics: function(Constructor, statics) { + mixStaticSpecIntoComponent(Constructor, statics); + } + }; + + function validateTypeDef(Constructor, typeDef, location) { + for (var propName in typeDef) { + if (typeDef.hasOwnProperty(propName)) { + // use a warning instead of an invariant so components + // don't show up in prod but not in __DEV__ + ( false ? warning( + typeof typeDef[propName] === 'function', + '%s: %s type `%s` is invalid; it must be a function, usually from ' + + 'React.PropTypes.', + Constructor.displayName || 'ReactClass', + ReactPropTypeLocationNames[location], + propName + ) : null); + } + } + } + + function validateMethodOverride(proto, name) { + var specPolicy = ReactClassInterface.hasOwnProperty(name) ? + ReactClassInterface[name] : + null; + + // Disallow overriding of base class methods unless explicitly allowed. + if (ReactClassMixin.hasOwnProperty(name)) { + ( false ? invariant( + specPolicy === SpecPolicy.OVERRIDE_BASE, + 'ReactClassInterface: You are attempting to override ' + + '`%s` from your class specification. Ensure that your method names ' + + 'do not overlap with React methods.', + name + ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE)); + } + + // Disallow defining methods more than once unless explicitly allowed. + if (proto.hasOwnProperty(name)) { + ( false ? invariant( + specPolicy === SpecPolicy.DEFINE_MANY || + specPolicy === SpecPolicy.DEFINE_MANY_MERGED, + 'ReactClassInterface: You are attempting to define ' + + '`%s` on your component more than once. This conflict may be due ' + + 'to a mixin.', + name + ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY || + specPolicy === SpecPolicy.DEFINE_MANY_MERGED)); + } + } + + /** + * Mixin helper which handles policy validation and reserved + * specification keys when building React classses. + */ + function mixSpecIntoComponent(Constructor, spec) { + if (!spec) { + return; + } + + ( false ? invariant( + typeof spec !== 'function', + 'ReactClass: You\'re attempting to ' + + 'use a component class as a mixin. Instead, just use a regular object.' + ) : invariant(typeof spec !== 'function')); + ( false ? invariant( + !ReactElement.isValidElement(spec), + 'ReactClass: You\'re attempting to ' + + 'use a component as a mixin. Instead, just use a regular object.' + ) : invariant(!ReactElement.isValidElement(spec))); + + var proto = Constructor.prototype; + + // By handling mixins before any other properties, we ensure the same + // chaining order is applied to methods with DEFINE_MANY policy, whether + // mixins are listed before or after these methods in the spec. + if (spec.hasOwnProperty(MIXINS_KEY)) { + RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); + } + + for (var name in spec) { + if (!spec.hasOwnProperty(name)) { + continue; + } + + if (name === MIXINS_KEY) { + // We have already handled mixins in a special case above + continue; + } + + var property = spec[name]; + validateMethodOverride(proto, name); + + if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { + RESERVED_SPEC_KEYS[name](Constructor, property); + } else { + // Setup methods on prototype: + // The following member methods should not be automatically bound: + // 1. Expected ReactClass methods (in the "interface"). + // 2. Overridden methods (that were mixed in). + var isReactClassMethod = + ReactClassInterface.hasOwnProperty(name); + var isAlreadyDefined = proto.hasOwnProperty(name); + var markedDontBind = property && property.__reactDontBind; + var isFunction = typeof property === 'function'; + var shouldAutoBind = + isFunction && + !isReactClassMethod && + !isAlreadyDefined && + !markedDontBind; + + if (shouldAutoBind) { + if (!proto.__reactAutoBindMap) { + proto.__reactAutoBindMap = {}; + } + proto.__reactAutoBindMap[name] = property; + proto[name] = property; + } else { + if (isAlreadyDefined) { + var specPolicy = ReactClassInterface[name]; + + // These cases should already be caught by validateMethodOverride + ( false ? invariant( + isReactClassMethod && ( + (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) + ), + 'ReactClass: Unexpected spec policy %s for key %s ' + + 'when mixing in component specs.', + specPolicy, + name + ) : invariant(isReactClassMethod && ( + (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY) + ))); + + // For methods which are defined more than once, call the existing + // methods before calling the new property, merging if appropriate. + if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { + proto[name] = createMergedResultFunction(proto[name], property); + } else if (specPolicy === SpecPolicy.DEFINE_MANY) { + proto[name] = createChainedFunction(proto[name], property); + } + } else { + proto[name] = property; + if (false) { + // Add verbose displayName to the function, which helps when looking + // at profiling tools. + if (typeof property === 'function' && spec.displayName) { + proto[name].displayName = spec.displayName + '_' + name; + } + } + } + } + } + } + } + + function mixStaticSpecIntoComponent(Constructor, statics) { + if (!statics) { + return; + } + for (var name in statics) { + var property = statics[name]; + if (!statics.hasOwnProperty(name)) { + continue; + } + + var isReserved = name in RESERVED_SPEC_KEYS; + ( false ? invariant( + !isReserved, + 'ReactClass: You are attempting to define a reserved ' + + 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + + 'as an instance property instead; it will still be accessible on the ' + + 'constructor.', + name + ) : invariant(!isReserved)); + + var isInherited = name in Constructor; + ( false ? invariant( + !isInherited, + 'ReactClass: You are attempting to define ' + + '`%s` on your component more than once. This conflict may be ' + + 'due to a mixin.', + name + ) : invariant(!isInherited)); + Constructor[name] = property; + } + } + + /** + * Merge two objects, but throw if both contain the same key. + * + * @param {object} one The first object, which is mutated. + * @param {object} two The second object + * @return {object} one after it has been mutated to contain everything in two. + */ + function mergeIntoWithNoDuplicateKeys(one, two) { + ( false ? invariant( + one && two && typeof one === 'object' && typeof two === 'object', + 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.' + ) : invariant(one && two && typeof one === 'object' && typeof two === 'object')); + + for (var key in two) { + if (two.hasOwnProperty(key)) { + ( false ? invariant( + one[key] === undefined, + 'mergeIntoWithNoDuplicateKeys(): ' + + 'Tried to merge two objects with the same key: `%s`. This conflict ' + + 'may be due to a mixin; in particular, this may be caused by two ' + + 'getInitialState() or getDefaultProps() methods returning objects ' + + 'with clashing keys.', + key + ) : invariant(one[key] === undefined)); + one[key] = two[key]; + } + } + return one; + } + + /** + * Creates a function that invokes two functions and merges their return values. + * + * @param {function} one Function to invoke first. + * @param {function} two Function to invoke second. + * @return {function} Function that invokes the two argument functions. + * @private + */ + function createMergedResultFunction(one, two) { + return function mergedResult() { + var a = one.apply(this, arguments); + var b = two.apply(this, arguments); + if (a == null) { + return b; + } else if (b == null) { + return a; + } + var c = {}; + mergeIntoWithNoDuplicateKeys(c, a); + mergeIntoWithNoDuplicateKeys(c, b); + return c; + }; + } + + /** + * Creates a function that invokes two functions and ignores their return vales. + * + * @param {function} one Function to invoke first. + * @param {function} two Function to invoke second. + * @return {function} Function that invokes the two argument functions. + * @private + */ + function createChainedFunction(one, two) { + return function chainedFunction() { + one.apply(this, arguments); + two.apply(this, arguments); + }; + } + + /** + * Binds a method to the component. + * + * @param {object} component Component whose method is going to be bound. + * @param {function} method Method to be bound. + * @return {function} The bound method. + */ + function bindAutoBindMethod(component, method) { + var boundMethod = method.bind(component); + if (false) { + boundMethod.__reactBoundContext = component; + boundMethod.__reactBoundMethod = method; + boundMethod.__reactBoundArguments = null; + var componentName = component.constructor.displayName; + var _bind = boundMethod.bind; + /* eslint-disable block-scoped-var, no-undef */ + boundMethod.bind = function(newThis ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + // User is trying to bind() an autobound method; we effectively will + // ignore the value of "this" that the user is trying to use, so + // let's warn. + if (newThis !== component && newThis !== null) { + ("production" !== process.env.NODE_ENV ? warning( + false, + 'bind(): React component methods may only be bound to the ' + + 'component instance. See %s', + componentName + ) : null); + } else if (!args.length) { + ("production" !== process.env.NODE_ENV ? warning( + false, + 'bind(): You are binding a component method to the component. ' + + 'React does this for you automatically in a high-performance ' + + 'way, so you can safely remove this call. See %s', + componentName + ) : null); + return boundMethod; + } + var reboundMethod = _bind.apply(boundMethod, arguments); + reboundMethod.__reactBoundContext = component; + reboundMethod.__reactBoundMethod = method; + reboundMethod.__reactBoundArguments = args; + return reboundMethod; + /* eslint-enable */ + }; + } + return boundMethod; + } + + /** + * Binds all auto-bound methods in a component. + * + * @param {object} component Component whose method is going to be bound. + */ + function bindAutoBindMethods(component) { + for (var autoBindKey in component.__reactAutoBindMap) { + if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { + var method = component.__reactAutoBindMap[autoBindKey]; + component[autoBindKey] = bindAutoBindMethod( + component, + ReactErrorUtils.guard( + method, + component.constructor.displayName + '.' + autoBindKey + ) + ); + } + } + } + + var typeDeprecationDescriptor = { + enumerable: false, + get: function() { + var displayName = this.displayName || this.name || 'Component'; + ( false ? warning( + false, + '%s.type is deprecated. Use %s directly to access the class.', + displayName, + displayName + ) : null); + Object.defineProperty(this, 'type', { + value: this + }); + return this; + } + }; + + /** + * Add more to the ReactClass base class. These are all legacy features and + * therefore not already part of the modern ReactComponent. + */ + var ReactClassMixin = { + + /** + * TODO: This will be deprecated because state should always keep a consistent + * type signature and the only use case for this, is to avoid that. + */ + replaceState: function(newState, callback) { + ReactUpdateQueue.enqueueReplaceState(this, newState); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + }, + + /** + * Checks whether or not this composite component is mounted. + * @return {boolean} True if mounted, false otherwise. + * @protected + * @final + */ + isMounted: function() { + if (false) { + var owner = ReactCurrentOwner.current; + if (owner !== null) { + ("production" !== process.env.NODE_ENV ? warning( + owner._warnedAboutRefsInRender, + '%s is accessing isMounted inside its render() function. ' + + 'render() should be a pure function of props and state. It should ' + + 'never access something that requires stale data from the previous ' + + 'render, such as refs. Move this logic to componentDidMount and ' + + 'componentDidUpdate instead.', + owner.getName() || 'A component' + ) : null); + owner._warnedAboutRefsInRender = true; + } + } + var internalInstance = ReactInstanceMap.get(this); + return ( + internalInstance && + internalInstance !== ReactLifeCycle.currentlyMountingInstance + ); + }, + + /** + * Sets a subset of the props. + * + * @param {object} partialProps Subset of the next props. + * @param {?function} callback Called after props are updated. + * @final + * @public + * @deprecated + */ + setProps: function(partialProps, callback) { + ReactUpdateQueue.enqueueSetProps(this, partialProps); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + }, + + /** + * Replace all the props. + * + * @param {object} newProps Subset of the next props. + * @param {?function} callback Called after props are updated. + * @final + * @public + * @deprecated + */ + replaceProps: function(newProps, callback) { + ReactUpdateQueue.enqueueReplaceProps(this, newProps); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + } + }; + + var ReactClassComponent = function() {}; + assign( + ReactClassComponent.prototype, + ReactComponent.prototype, + ReactClassMixin + ); + + /** + * Module for creating composite components. + * + * @class ReactClass + */ + var ReactClass = { + + /** + * Creates a composite component class given a class specification. + * + * @param {object} spec Class specification (which must define `render`). + * @return {function} Component constructor function. + * @public + */ + createClass: function(spec) { + var Constructor = function(props, context) { + // This constructor is overridden by mocks. The argument is used + // by mocks to assert on what gets mounted. + + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + this instanceof Constructor, + 'Something is calling a React component directly. Use a factory or ' + + 'JSX instead. See: https://fb.me/react-legacyfactory' + ) : null); + } + + // Wire up auto-binding + if (this.__reactAutoBindMap) { + bindAutoBindMethods(this); + } + + this.props = props; + this.context = context; + this.state = null; + + // ReactClasses doesn't have constructors. Instead, they use the + // getInitialState and componentWillMount methods for initialization. + + var initialState = this.getInitialState ? this.getInitialState() : null; + if (false) { + // We allow auto-mocks to proceed as if they're returning null. + if (typeof initialState === 'undefined' && + this.getInitialState._isMockFunction) { + // This is probably bad practice. Consider warning here and + // deprecating this convenience. + initialState = null; + } + } + ( false ? invariant( + typeof initialState === 'object' && !Array.isArray(initialState), + '%s.getInitialState(): must return an object or null', + Constructor.displayName || 'ReactCompositeComponent' + ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); + + this.state = initialState; + }; + Constructor.prototype = new ReactClassComponent(); + Constructor.prototype.constructor = Constructor; + + injectedMixins.forEach( + mixSpecIntoComponent.bind(null, Constructor) + ); + + mixSpecIntoComponent(Constructor, spec); + + // Initialize the defaultProps property after all mixins have been merged + if (Constructor.getDefaultProps) { + Constructor.defaultProps = Constructor.getDefaultProps(); + } + + if (false) { + // This is a tag to indicate that the use of these method names is ok, + // since it's used with createClass. If it's not, then it's likely a + // mistake so we'll warn you to use the static property, property + // initializer or constructor respectively. + if (Constructor.getDefaultProps) { + Constructor.getDefaultProps.isReactClassApproved = {}; + } + if (Constructor.prototype.getInitialState) { + Constructor.prototype.getInitialState.isReactClassApproved = {}; + } + } + + ( false ? invariant( + Constructor.prototype.render, + 'createClass(...): Class specification must implement a `render` method.' + ) : invariant(Constructor.prototype.render)); + + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + !Constructor.prototype.componentShouldUpdate, + '%s has a method called ' + + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + + 'The name is phrased as a question because the function is ' + + 'expected to return a value.', + spec.displayName || 'A component' + ) : null); + } + + // Reduce time spent doing lookups by setting these on the prototype. + for (var methodName in ReactClassInterface) { + if (!Constructor.prototype[methodName]) { + Constructor.prototype[methodName] = null; + } + } + + // Legacy hook + Constructor.type = Constructor; + if (false) { + try { + Object.defineProperty(Constructor, 'type', typeDeprecationDescriptor); + } catch (x) { + // IE will fail on defineProperty (es5-shim/sham too) + } + } + + return Constructor; + }, + + injection: { + injectMixin: function(mixin) { + injectedMixins.push(mixin); + } + } + + }; + + module.exports = ReactClass; + + +/***/ }, +/* 38 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactErrorUtils + * @typechecks + */ + + "use strict"; + + var ReactErrorUtils = { + /** + * Creates a guarded version of a function. This is supposed to make debugging + * of event handlers easier. To aid debugging with the browser's debugger, + * this currently simply returns the original function. + * + * @param {function} func Function to be executed + * @param {string} name The name of the guard + * @return {function} + */ + guard: function(func, name) { + return func; + } + }; + + module.exports = ReactErrorUtils; + + +/***/ }, +/* 39 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule keyOf + */ + + /** + * Allows extraction of a minified key. Let's the build system minify keys + * without loosing the ability to dynamically use key strings as values + * themselves. Pass in an object with a single key/val pair and it will return + * you the string key of that single record. Suppose you want to grab the + * value for a key 'className' inside of an object. Key/val minification may + * have aliased that key to be 'xa12'. keyOf({className: null}) will return + * 'xa12' in that case. Resolve keys you want to use once at startup time, then + * reuse those resolutions. + */ + var keyOf = function(oneKeyObj) { + var key; + for (key in oneKeyObj) { + if (!oneKeyObj.hasOwnProperty(key)) { + continue; + } + return key; + } + return null; + }; + + + module.exports = keyOf; + + +/***/ }, +/* 40 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOM + * @typechecks static-only + */ + + 'use strict'; + + var ReactElement = __webpack_require__(11); + var ReactElementValidator = __webpack_require__(32); + + var mapObject = __webpack_require__(41); + + /** + * Create a factory that creates HTML tag elements. + * + * @param {string} tag Tag name (e.g. `div`). + * @private + */ + function createDOMFactory(tag) { + if (false) { + return ReactElementValidator.createFactory(tag); + } + return ReactElement.createFactory(tag); + } + + /** + * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. + * This is also accessible via `React.DOM`. + * + * @public + */ + var ReactDOM = mapObject({ + a: 'a', + abbr: 'abbr', + address: 'address', + area: 'area', + article: 'article', + aside: 'aside', + audio: 'audio', + b: 'b', + base: 'base', + bdi: 'bdi', + bdo: 'bdo', + big: 'big', + blockquote: 'blockquote', + body: 'body', + br: 'br', + button: 'button', + canvas: 'canvas', + caption: 'caption', + cite: 'cite', + code: 'code', + col: 'col', + colgroup: 'colgroup', + data: 'data', + datalist: 'datalist', + dd: 'dd', + del: 'del', + details: 'details', + dfn: 'dfn', + dialog: 'dialog', + div: 'div', + dl: 'dl', + dt: 'dt', + em: 'em', + embed: 'embed', + fieldset: 'fieldset', + figcaption: 'figcaption', + figure: 'figure', + footer: 'footer', + form: 'form', + h1: 'h1', + h2: 'h2', + h3: 'h3', + h4: 'h4', + h5: 'h5', + h6: 'h6', + head: 'head', + header: 'header', + hr: 'hr', + html: 'html', + i: 'i', + iframe: 'iframe', + img: 'img', + input: 'input', + ins: 'ins', + kbd: 'kbd', + keygen: 'keygen', + label: 'label', + legend: 'legend', + li: 'li', + link: 'link', + main: 'main', + map: 'map', + mark: 'mark', + menu: 'menu', + menuitem: 'menuitem', + meta: 'meta', + meter: 'meter', + nav: 'nav', + noscript: 'noscript', + object: 'object', + ol: 'ol', + optgroup: 'optgroup', + option: 'option', + output: 'output', + p: 'p', + param: 'param', + picture: 'picture', + pre: 'pre', + progress: 'progress', + q: 'q', + rp: 'rp', + rt: 'rt', + ruby: 'ruby', + s: 's', + samp: 'samp', + script: 'script', + section: 'section', + select: 'select', + small: 'small', + source: 'source', + span: 'span', + strong: 'strong', + style: 'style', + sub: 'sub', + summary: 'summary', + sup: 'sup', + table: 'table', + tbody: 'tbody', + td: 'td', + textarea: 'textarea', + tfoot: 'tfoot', + th: 'th', + thead: 'thead', + time: 'time', + title: 'title', + tr: 'tr', + track: 'track', + u: 'u', + ul: 'ul', + 'var': 'var', + video: 'video', + wbr: 'wbr', + + // SVG + circle: 'circle', + clipPath: 'clipPath', + defs: 'defs', + ellipse: 'ellipse', + g: 'g', + line: 'line', + linearGradient: 'linearGradient', + mask: 'mask', + path: 'path', + pattern: 'pattern', + polygon: 'polygon', + polyline: 'polyline', + radialGradient: 'radialGradient', + rect: 'rect', + stop: 'stop', + svg: 'svg', + text: 'text', + tspan: 'tspan' + + }, createDOMFactory); + + module.exports = ReactDOM; + + +/***/ }, +/* 41 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule mapObject + */ + + 'use strict'; + + var hasOwnProperty = Object.prototype.hasOwnProperty; + + /** + * Executes the provided `callback` once for each enumerable own property in the + * object and constructs a new object from the results. The `callback` is + * invoked with three arguments: + * + * - the property value + * - the property name + * - the object being traversed + * + * Properties that are added after the call to `mapObject` will not be visited + * by `callback`. If the values of existing properties are changed, the value + * passed to `callback` will be the value at the time `mapObject` visits them. + * Properties that are deleted before being visited are not visited. + * + * @grep function objectMap() + * @grep function objMap() + * + * @param {?object} object + * @param {function} callback + * @param {*} context + * @return {?object} + */ + function mapObject(object, callback, context) { + if (!object) { + return null; + } + var result = {}; + for (var name in object) { + if (hasOwnProperty.call(object, name)) { + result[name] = callback.call(context, object[name], name, object); + } + } + return result; + } + + module.exports = mapObject; + + +/***/ }, +/* 42 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOMTextComponent + * @typechecks static-only + */ + + 'use strict'; + + var DOMPropertyOperations = __webpack_require__(43); + var ReactComponentBrowserEnvironment = + __webpack_require__(47); + var ReactDOMComponent = __webpack_require__(87); + + var assign = __webpack_require__(13); + var escapeTextContentForBrowser = __webpack_require__(46); + + /** + * Text nodes violate a couple assumptions that React makes about components: + * + * - When mounting text into the DOM, adjacent text nodes are merged. + * - Text nodes cannot be assigned a React root ID. + * + * This component is used to wrap strings in elements so that they can undergo + * the same reconciliation that is applied to elements. + * + * TODO: Investigate representing React components in the DOM with text nodes. + * + * @class ReactDOMTextComponent + * @extends ReactComponent + * @internal + */ + var ReactDOMTextComponent = function(props) { + // This constructor and its argument is currently used by mocks. + }; + + assign(ReactDOMTextComponent.prototype, { + + /** + * @param {ReactText} text + * @internal + */ + construct: function(text) { + // TODO: This is really a ReactText (ReactNode), not a ReactElement + this._currentElement = text; + this._stringText = '' + text; + + // Properties + this._rootNodeID = null; + this._mountIndex = 0; + }, + + /** + * Creates the markup for this text node. This node is not intended to have + * any features besides containing text content. + * + * @param {string} rootID DOM ID of the root node. + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @return {string} Markup for this text node. + * @internal + */ + mountComponent: function(rootID, transaction, context) { + this._rootNodeID = rootID; + var escapedText = escapeTextContentForBrowser(this._stringText); + + if (transaction.renderToStaticMarkup) { + // Normally we'd wrap this in a `span` for the reasons stated above, but + // since this is a situation where React won't take over (static pages), + // we can simply return the text as it is. + return escapedText; + } + + return ( + '' + + escapedText + + '' + ); + }, + + /** + * Updates this component by updating the text content. + * + * @param {ReactText} nextText The next text content + * @param {ReactReconcileTransaction} transaction + * @internal + */ + receiveComponent: function(nextText, transaction) { + if (nextText !== this._currentElement) { + this._currentElement = nextText; + var nextStringText = '' + nextText; + if (nextStringText !== this._stringText) { + // TODO: Save this as pending props and use performUpdateIfNecessary + // and/or updateComponent to do the actual update for consistency with + // other component types? + this._stringText = nextStringText; + ReactDOMComponent.BackendIDOperations.updateTextContentByID( + this._rootNodeID, + nextStringText + ); + } + } + }, + + unmountComponent: function() { + ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID); + } + + }); + + module.exports = ReactDOMTextComponent; + + +/***/ }, +/* 43 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMPropertyOperations + * @typechecks static-only + */ + + 'use strict'; + + var DOMProperty = __webpack_require__(44); + + var quoteAttributeValueForBrowser = __webpack_require__(45); + var warning = __webpack_require__(15); + + function shouldIgnoreValue(name, value) { + return value == null || + (DOMProperty.hasBooleanValue[name] && !value) || + (DOMProperty.hasNumericValue[name] && isNaN(value)) || + (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || + (DOMProperty.hasOverloadedBooleanValue[name] && value === false); + } + + if (false) { + var reactProps = { + children: true, + dangerouslySetInnerHTML: true, + key: true, + ref: true + }; + var warnedProperties = {}; + + var warnUnknownProperty = function(name) { + if (reactProps.hasOwnProperty(name) && reactProps[name] || + warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { + return; + } + + warnedProperties[name] = true; + var lowerCasedName = name.toLowerCase(); + + // data-* attributes should be lowercase; suggest the lowercase version + var standardName = ( + DOMProperty.isCustomAttribute(lowerCasedName) ? + lowerCasedName : + DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? + DOMProperty.getPossibleStandardName[lowerCasedName] : + null + ); + + // For now, only warn when we have a suggested correction. This prevents + // logging too much when using transferPropsTo. + ("production" !== process.env.NODE_ENV ? warning( + standardName == null, + 'Unknown DOM property %s. Did you mean %s?', + name, + standardName + ) : null); + + }; + } + + /** + * Operations for dealing with DOM properties. + */ + var DOMPropertyOperations = { + + /** + * Creates markup for the ID property. + * + * @param {string} id Unescaped ID. + * @return {string} Markup string. + */ + createMarkupForID: function(id) { + return DOMProperty.ID_ATTRIBUTE_NAME + '=' + + quoteAttributeValueForBrowser(id); + }, + + /** + * Creates markup for a property. + * + * @param {string} name + * @param {*} value + * @return {?string} Markup string, or null if the property was invalid. + */ + createMarkupForProperty: function(name, value) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + if (shouldIgnoreValue(name, value)) { + return ''; + } + var attributeName = DOMProperty.getAttributeName[name]; + if (DOMProperty.hasBooleanValue[name] || + (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { + return attributeName; + } + return attributeName + '=' + quoteAttributeValueForBrowser(value); + } else if (DOMProperty.isCustomAttribute(name)) { + if (value == null) { + return ''; + } + return name + '=' + quoteAttributeValueForBrowser(value); + } else if (false) { + warnUnknownProperty(name); + } + return null; + }, + + /** + * Sets the value for a property on a node. + * + * @param {DOMElement} node + * @param {string} name + * @param {*} value + */ + setValueForProperty: function(node, name, value) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + var mutationMethod = DOMProperty.getMutationMethod[name]; + if (mutationMethod) { + mutationMethod(node, value); + } else if (shouldIgnoreValue(name, value)) { + this.deleteValueForProperty(node, name); + } else if (DOMProperty.mustUseAttribute[name]) { + // `setAttribute` with objects becomes only `[object]` in IE8/9, + // ('' + value) makes it output the correct toString()-value. + node.setAttribute(DOMProperty.getAttributeName[name], '' + value); + } else { + var propName = DOMProperty.getPropertyName[name]; + // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the + // property type before comparing; only `value` does and is string. + if (!DOMProperty.hasSideEffects[name] || + ('' + node[propName]) !== ('' + value)) { + // Contrary to `setAttribute`, object properties are properly + // `toString`ed by IE8/9. + node[propName] = value; + } + } + } else if (DOMProperty.isCustomAttribute(name)) { + if (value == null) { + node.removeAttribute(name); + } else { + node.setAttribute(name, '' + value); + } + } else if (false) { + warnUnknownProperty(name); + } + }, + + /** + * Deletes the value for a property on a node. + * + * @param {DOMElement} node + * @param {string} name + */ + deleteValueForProperty: function(node, name) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + var mutationMethod = DOMProperty.getMutationMethod[name]; + if (mutationMethod) { + mutationMethod(node, undefined); + } else if (DOMProperty.mustUseAttribute[name]) { + node.removeAttribute(DOMProperty.getAttributeName[name]); + } else { + var propName = DOMProperty.getPropertyName[name]; + var defaultValue = DOMProperty.getDefaultValueForProperty( + node.nodeName, + propName + ); + if (!DOMProperty.hasSideEffects[name] || + ('' + node[propName]) !== defaultValue) { + node[propName] = defaultValue; + } + } + } else if (DOMProperty.isCustomAttribute(name)) { + node.removeAttribute(name); + } else if (false) { + warnUnknownProperty(name); + } + } + + }; + + module.exports = DOMPropertyOperations; + + +/***/ }, +/* 44 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMProperty + * @typechecks static-only + */ + + /*jslint bitwise: true */ + + 'use strict'; + + var invariant = __webpack_require__(7); + + function checkMask(value, bitmask) { + return (value & bitmask) === bitmask; + } + + var DOMPropertyInjection = { + /** + * Mapping from normalized, camelcased property names to a configuration that + * specifies how the associated DOM property should be accessed or rendered. + */ + MUST_USE_ATTRIBUTE: 0x1, + MUST_USE_PROPERTY: 0x2, + HAS_SIDE_EFFECTS: 0x4, + HAS_BOOLEAN_VALUE: 0x8, + HAS_NUMERIC_VALUE: 0x10, + HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, + HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, + + /** + * Inject some specialized knowledge about the DOM. This takes a config object + * with the following properties: + * + * isCustomAttribute: function that given an attribute name will return true + * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* + * attributes where it's impossible to enumerate all of the possible + * attribute names, + * + * Properties: object mapping DOM property name to one of the + * DOMPropertyInjection constants or null. If your attribute isn't in here, + * it won't get written to the DOM. + * + * DOMAttributeNames: object mapping React attribute name to the DOM + * attribute name. Attribute names not specified use the **lowercase** + * normalized name. + * + * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. + * Property names not specified use the normalized name. + * + * DOMMutationMethods: Properties that require special mutation methods. If + * `value` is undefined, the mutation method should unset the property. + * + * @param {object} domPropertyConfig the config as described above. + */ + injectDOMPropertyConfig: function(domPropertyConfig) { + var Properties = domPropertyConfig.Properties || {}; + var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; + var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; + var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; + + if (domPropertyConfig.isCustomAttribute) { + DOMProperty._isCustomAttributeFunctions.push( + domPropertyConfig.isCustomAttribute + ); + } + + for (var propName in Properties) { + ( false ? invariant( + !DOMProperty.isStandardName.hasOwnProperty(propName), + 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + + '\'%s\' which has already been injected. You may be accidentally ' + + 'injecting the same DOM property config twice, or you may be ' + + 'injecting two configs that have conflicting property names.', + propName + ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); + + DOMProperty.isStandardName[propName] = true; + + var lowerCased = propName.toLowerCase(); + DOMProperty.getPossibleStandardName[lowerCased] = propName; + + if (DOMAttributeNames.hasOwnProperty(propName)) { + var attributeName = DOMAttributeNames[propName]; + DOMProperty.getPossibleStandardName[attributeName] = propName; + DOMProperty.getAttributeName[propName] = attributeName; + } else { + DOMProperty.getAttributeName[propName] = lowerCased; + } + + DOMProperty.getPropertyName[propName] = + DOMPropertyNames.hasOwnProperty(propName) ? + DOMPropertyNames[propName] : + propName; + + if (DOMMutationMethods.hasOwnProperty(propName)) { + DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; + } else { + DOMProperty.getMutationMethod[propName] = null; + } + + var propConfig = Properties[propName]; + DOMProperty.mustUseAttribute[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); + DOMProperty.mustUseProperty[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); + DOMProperty.hasSideEffects[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); + DOMProperty.hasBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); + DOMProperty.hasNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); + DOMProperty.hasPositiveNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); + DOMProperty.hasOverloadedBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); + + ( false ? invariant( + !DOMProperty.mustUseAttribute[propName] || + !DOMProperty.mustUseProperty[propName], + 'DOMProperty: Cannot require using both attribute and property: %s', + propName + ) : invariant(!DOMProperty.mustUseAttribute[propName] || + !DOMProperty.mustUseProperty[propName])); + ( false ? invariant( + DOMProperty.mustUseProperty[propName] || + !DOMProperty.hasSideEffects[propName], + 'DOMProperty: Properties that have side effects must use property: %s', + propName + ) : invariant(DOMProperty.mustUseProperty[propName] || + !DOMProperty.hasSideEffects[propName])); + ( false ? invariant( + !!DOMProperty.hasBooleanValue[propName] + + !!DOMProperty.hasNumericValue[propName] + + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, + 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + + 'numeric value, but not a combination: %s', + propName + ) : invariant(!!DOMProperty.hasBooleanValue[propName] + + !!DOMProperty.hasNumericValue[propName] + + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); + } + } + }; + var defaultValueCache = {}; + + /** + * DOMProperty exports lookup objects that can be used like functions: + * + * > DOMProperty.isValid['id'] + * true + * > DOMProperty.isValid['foobar'] + * undefined + * + * Although this may be confusing, it performs better in general. + * + * @see http://jsperf.com/key-exists + * @see http://jsperf.com/key-missing + */ + var DOMProperty = { + + ID_ATTRIBUTE_NAME: 'data-reactid', + + /** + * Checks whether a property name is a standard property. + * @type {Object} + */ + isStandardName: {}, + + /** + * Mapping from lowercase property names to the properly cased version, used + * to warn in the case of missing properties. + * @type {Object} + */ + getPossibleStandardName: {}, + + /** + * Mapping from normalized names to attribute names that differ. Attribute + * names are used when rendering markup or with `*Attribute()`. + * @type {Object} + */ + getAttributeName: {}, + + /** + * Mapping from normalized names to properties on DOM node instances. + * (This includes properties that mutate due to external factors.) + * @type {Object} + */ + getPropertyName: {}, + + /** + * Mapping from normalized names to mutation methods. This will only exist if + * mutation cannot be set simply by the property or `setAttribute()`. + * @type {Object} + */ + getMutationMethod: {}, + + /** + * Whether the property must be accessed and mutated as an object property. + * @type {Object} + */ + mustUseAttribute: {}, + + /** + * Whether the property must be accessed and mutated using `*Attribute()`. + * (This includes anything that fails ` in `.) + * @type {Object} + */ + mustUseProperty: {}, + + /** + * Whether or not setting a value causes side effects such as triggering + * resources to be loaded or text selection changes. We must ensure that + * the value is only set if it has changed. + * @type {Object} + */ + hasSideEffects: {}, + + /** + * Whether the property should be removed when set to a falsey value. + * @type {Object} + */ + hasBooleanValue: {}, + + /** + * Whether the property must be numeric or parse as a + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasNumericValue: {}, + + /** + * Whether the property must be positive numeric or parse as a positive + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasPositiveNumericValue: {}, + + /** + * Whether the property can be used as a flag as well as with a value. Removed + * when strictly equal to false; present without a value when strictly equal + * to true; present with a value otherwise. + * @type {Object} + */ + hasOverloadedBooleanValue: {}, + + /** + * All of the isCustomAttribute() functions that have been injected. + */ + _isCustomAttributeFunctions: [], + + /** + * Checks whether a property name is a custom attribute. + * @method + */ + isCustomAttribute: function(attributeName) { + for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { + var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; + if (isCustomAttributeFn(attributeName)) { + return true; + } + } + return false; + }, + + /** + * Returns the default property value for a DOM property (i.e., not an + * attribute). Most default values are '' or false, but not all. Worse yet, + * some (in particular, `type`) vary depending on the type of element. + * + * TODO: Is it better to grab all the possible properties when creating an + * element to avoid having to create the same element twice? + */ + getDefaultValueForProperty: function(nodeName, prop) { + var nodeDefaults = defaultValueCache[nodeName]; + var testElement; + if (!nodeDefaults) { + defaultValueCache[nodeName] = nodeDefaults = {}; + } + if (!(prop in nodeDefaults)) { + testElement = document.createElement(nodeName); + nodeDefaults[prop] = testElement[prop]; + } + return nodeDefaults[prop]; + }, + + injection: DOMPropertyInjection + }; + + module.exports = DOMProperty; + + +/***/ }, +/* 45 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule quoteAttributeValueForBrowser + */ + + 'use strict'; + + var escapeTextContentForBrowser = __webpack_require__(46); + + /** + * Escapes attribute value to prevent scripting attacks. + * + * @param {*} value Value to escape. + * @return {string} An escaped string. + */ + function quoteAttributeValueForBrowser(value) { + return '"' + escapeTextContentForBrowser(value) + '"'; + } + + module.exports = quoteAttributeValueForBrowser; + + +/***/ }, +/* 46 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule escapeTextContentForBrowser + */ + + 'use strict'; + + var ESCAPE_LOOKUP = { + '&': '&', + '>': '>', + '<': '<', + '"': '"', + '\'': ''' + }; + + var ESCAPE_REGEX = /[&><"']/g; + + function escaper(match) { + return ESCAPE_LOOKUP[match]; + } + + /** + * Escapes text to prevent scripting attacks. + * + * @param {*} text Text value to escape. + * @return {string} An escaped string. + */ + function escapeTextContentForBrowser(text) { + return ('' + text).replace(ESCAPE_REGEX, escaper); + } + + module.exports = escapeTextContentForBrowser; + + +/***/ }, +/* 47 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactComponentBrowserEnvironment + */ + + /*jslint evil: true */ + + 'use strict'; + + var ReactDOMIDOperations = __webpack_require__(48); + var ReactMount = __webpack_require__(67); + + /** + * Abstracts away all functionality of the reconciler that requires knowledge of + * the browser context. TODO: These callers should be refactored to avoid the + * need for this injection. + */ + var ReactComponentBrowserEnvironment = { + + processChildrenUpdates: + ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, + + replaceNodeWithMarkupByID: + ReactDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID, + + /** + * If a particular environment requires that some resources be cleaned up, + * specify this in the injected Mixin. In the DOM, we would likely want to + * purge any cached node ID lookups. + * + * @private + */ + unmountIDFromEnvironment: function(rootNodeID) { + ReactMount.purgeID(rootNodeID); + } + + }; + + module.exports = ReactComponentBrowserEnvironment; + + +/***/ }, +/* 48 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOMIDOperations + * @typechecks static-only + */ + + /*jslint evil: true */ + + 'use strict'; + + var CSSPropertyOperations = __webpack_require__(49); + var DOMChildrenOperations = __webpack_require__(58); + var DOMPropertyOperations = __webpack_require__(43); + var ReactMount = __webpack_require__(67); + var ReactPerf = __webpack_require__(28); + + var invariant = __webpack_require__(7); + var setInnerHTML = __webpack_require__(66); + + /** + * Errors for properties that should not be updated with `updatePropertyById()`. + * + * @type {object} + * @private + */ + var INVALID_PROPERTY_ERRORS = { + dangerouslySetInnerHTML: + '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.', + style: '`style` must be set using `updateStylesByID()`.' + }; + + /** + * Operations used to process updates to DOM nodes. This is made injectable via + * `ReactDOMComponent.BackendIDOperations`. + */ + var ReactDOMIDOperations = { + + /** + * Updates a DOM node with new property values. This should only be used to + * update DOM properties in `DOMProperty`. + * + * @param {string} id ID of the node to update. + * @param {string} name A valid property name, see `DOMProperty`. + * @param {*} value New value of the property. + * @internal + */ + updatePropertyByID: function(id, name, value) { + var node = ReactMount.getNode(id); + ( false ? invariant( + !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), + 'updatePropertyByID(...): %s', + INVALID_PROPERTY_ERRORS[name] + ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); + + // If we're updating to null or undefined, we should remove the property + // from the DOM node instead of inadvertantly setting to a string. This + // brings us in line with the same behavior we have on initial render. + if (value != null) { + DOMPropertyOperations.setValueForProperty(node, name, value); + } else { + DOMPropertyOperations.deleteValueForProperty(node, name); + } + }, + + /** + * Updates a DOM node to remove a property. This should only be used to remove + * DOM properties in `DOMProperty`. + * + * @param {string} id ID of the node to update. + * @param {string} name A property name to remove, see `DOMProperty`. + * @internal + */ + deletePropertyByID: function(id, name, value) { + var node = ReactMount.getNode(id); + ( false ? invariant( + !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), + 'updatePropertyByID(...): %s', + INVALID_PROPERTY_ERRORS[name] + ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); + DOMPropertyOperations.deleteValueForProperty(node, name, value); + }, + + /** + * Updates a DOM node with new style values. If a value is specified as '', + * the corresponding style property will be unset. + * + * @param {string} id ID of the node to update. + * @param {object} styles Mapping from styles to values. + * @internal + */ + updateStylesByID: function(id, styles) { + var node = ReactMount.getNode(id); + CSSPropertyOperations.setValueForStyles(node, styles); + }, + + /** + * Updates a DOM node's innerHTML. + * + * @param {string} id ID of the node to update. + * @param {string} html An HTML string. + * @internal + */ + updateInnerHTMLByID: function(id, html) { + var node = ReactMount.getNode(id); + setInnerHTML(node, html); + }, + + /** + * Updates a DOM node's text content set by `props.content`. + * + * @param {string} id ID of the node to update. + * @param {string} content Text content. + * @internal + */ + updateTextContentByID: function(id, content) { + var node = ReactMount.getNode(id); + DOMChildrenOperations.updateTextContent(node, content); + }, + + /** + * Replaces a DOM node that exists in the document with markup. + * + * @param {string} id ID of child to be replaced. + * @param {string} markup Dangerous markup to inject in place of child. + * @internal + * @see {Danger.dangerouslyReplaceNodeWithMarkup} + */ + dangerouslyReplaceNodeWithMarkupByID: function(id, markup) { + var node = ReactMount.getNode(id); + DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup); + }, + + /** + * Updates a component's children by processing a series of updates. + * + * @param {array} updates List of update configurations. + * @param {array} markup List of markup strings. + * @internal + */ + dangerouslyProcessChildrenUpdates: function(updates, markup) { + for (var i = 0; i < updates.length; i++) { + updates[i].parentNode = ReactMount.getNode(updates[i].parentID); + } + DOMChildrenOperations.processUpdates(updates, markup); + } + }; + + ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', { + updatePropertyByID: 'updatePropertyByID', + deletePropertyByID: 'deletePropertyByID', + updateStylesByID: 'updateStylesByID', + updateInnerHTMLByID: 'updateInnerHTMLByID', + updateTextContentByID: 'updateTextContentByID', + dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID', + dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates' + }); + + module.exports = ReactDOMIDOperations; + + +/***/ }, +/* 49 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CSSPropertyOperations + * @typechecks static-only + */ + + 'use strict'; + + var CSSProperty = __webpack_require__(50); + var ExecutionEnvironment = __webpack_require__(51); + + var camelizeStyleName = __webpack_require__(52); + var dangerousStyleValue = __webpack_require__(54); + var hyphenateStyleName = __webpack_require__(55); + var memoizeStringOnly = __webpack_require__(57); + var warning = __webpack_require__(15); + + var processStyleName = memoizeStringOnly(function(styleName) { + return hyphenateStyleName(styleName); + }); + + var styleFloatAccessor = 'cssFloat'; + if (ExecutionEnvironment.canUseDOM) { + // IE8 only supports accessing cssFloat (standard) as styleFloat + if (document.documentElement.style.cssFloat === undefined) { + styleFloatAccessor = 'styleFloat'; + } + } + + if (false) { + // 'msTransform' is correct, but the other prefixes should be capitalized + var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; + + // style values shouldn't contain a semicolon + var badStyleValueWithSemicolonPattern = /;\s*$/; + + var warnedStyleNames = {}; + var warnedStyleValues = {}; + + var warnHyphenatedStyleName = function(name) { + if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { + return; + } + + warnedStyleNames[name] = true; + ("production" !== process.env.NODE_ENV ? warning( + false, + 'Unsupported style property %s. Did you mean %s?', + name, + camelizeStyleName(name) + ) : null); + }; + + var warnBadVendoredStyleName = function(name) { + if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { + return; + } + + warnedStyleNames[name] = true; + ("production" !== process.env.NODE_ENV ? warning( + false, + 'Unsupported vendor-prefixed style property %s. Did you mean %s?', + name, + name.charAt(0).toUpperCase() + name.slice(1) + ) : null); + }; + + var warnStyleValueWithSemicolon = function(name, value) { + if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { + return; + } + + warnedStyleValues[value] = true; + ("production" !== process.env.NODE_ENV ? warning( + false, + 'Style property values shouldn\'t contain a semicolon. ' + + 'Try "%s: %s" instead.', + name, + value.replace(badStyleValueWithSemicolonPattern, '') + ) : null); + }; + + /** + * @param {string} name + * @param {*} value + */ + var warnValidStyle = function(name, value) { + if (name.indexOf('-') > -1) { + warnHyphenatedStyleName(name); + } else if (badVendoredStyleNamePattern.test(name)) { + warnBadVendoredStyleName(name); + } else if (badStyleValueWithSemicolonPattern.test(value)) { + warnStyleValueWithSemicolon(name, value); + } + }; + } + + /** + * Operations for dealing with CSS properties. + */ + var CSSPropertyOperations = { + + /** + * Serializes a mapping of style properties for use as inline styles: + * + * > createMarkupForStyles({width: '200px', height: 0}) + * "width:200px;height:0;" + * + * Undefined values are ignored so that declarative programming is easier. + * The result should be HTML-escaped before insertion into the DOM. + * + * @param {object} styles + * @return {?string} + */ + createMarkupForStyles: function(styles) { + var serialized = ''; + for (var styleName in styles) { + if (!styles.hasOwnProperty(styleName)) { + continue; + } + var styleValue = styles[styleName]; + if (false) { + warnValidStyle(styleName, styleValue); + } + if (styleValue != null) { + serialized += processStyleName(styleName) + ':'; + serialized += dangerousStyleValue(styleName, styleValue) + ';'; + } + } + return serialized || null; + }, + + /** + * Sets the value for multiple styles on a node. If a value is specified as + * '' (empty string), the corresponding style property will be unset. + * + * @param {DOMElement} node + * @param {object} styles + */ + setValueForStyles: function(node, styles) { + var style = node.style; + for (var styleName in styles) { + if (!styles.hasOwnProperty(styleName)) { + continue; + } + if (false) { + warnValidStyle(styleName, styles[styleName]); + } + var styleValue = dangerousStyleValue(styleName, styles[styleName]); + if (styleName === 'float') { + styleName = styleFloatAccessor; + } + if (styleValue) { + style[styleName] = styleValue; + } else { + var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; + if (expansion) { + // Shorthand property that IE8 won't like unsetting, so unset each + // component to placate it + for (var individualStyleName in expansion) { + style[individualStyleName] = ''; + } + } else { + style[styleName] = ''; + } + } + } + } + + }; + + module.exports = CSSPropertyOperations; + + +/***/ }, +/* 50 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CSSProperty + */ + + 'use strict'; + + /** + * CSS properties which accept numbers but are not in units of "px". + */ + var isUnitlessNumber = { + boxFlex: true, + boxFlexGroup: true, + columnCount: true, + flex: true, + flexGrow: true, + flexPositive: true, + flexShrink: true, + flexNegative: true, + fontWeight: true, + lineClamp: true, + lineHeight: true, + opacity: true, + order: true, + orphans: true, + widows: true, + zIndex: true, + zoom: true, + + // SVG-related properties + fillOpacity: true, + strokeDashoffset: true, + strokeOpacity: true, + strokeWidth: true + }; + + /** + * @param {string} prefix vendor-specific prefix, eg: Webkit + * @param {string} key style name, eg: transitionDuration + * @return {string} style name prefixed with `prefix`, properly camelCased, eg: + * WebkitTransitionDuration + */ + function prefixKey(prefix, key) { + return prefix + key.charAt(0).toUpperCase() + key.substring(1); + } + + /** + * Support style names that may come passed in prefixed by adding permutations + * of vendor prefixes. + */ + var prefixes = ['Webkit', 'ms', 'Moz', 'O']; + + // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an + // infinite loop, because it iterates over the newly added props too. + Object.keys(isUnitlessNumber).forEach(function(prop) { + prefixes.forEach(function(prefix) { + isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; + }); + }); + + /** + * Most style properties can be unset by doing .style[prop] = '' but IE8 + * doesn't like doing that with shorthand properties so for the properties that + * IE8 breaks on, which are listed here, we instead unset each of the + * individual properties. See http://bugs.jquery.com/ticket/12385. + * The 4-value 'clock' properties like margin, padding, border-width seem to + * behave without any problems. Curiously, list-style works too without any + * special prodding. + */ + var shorthandPropertyExpansions = { + background: { + backgroundImage: true, + backgroundPosition: true, + backgroundRepeat: true, + backgroundColor: true + }, + border: { + borderWidth: true, + borderStyle: true, + borderColor: true + }, + borderBottom: { + borderBottomWidth: true, + borderBottomStyle: true, + borderBottomColor: true + }, + borderLeft: { + borderLeftWidth: true, + borderLeftStyle: true, + borderLeftColor: true + }, + borderRight: { + borderRightWidth: true, + borderRightStyle: true, + borderRightColor: true + }, + borderTop: { + borderTopWidth: true, + borderTopStyle: true, + borderTopColor: true + }, + font: { + fontStyle: true, + fontVariant: true, + fontWeight: true, + fontSize: true, + lineHeight: true, + fontFamily: true + } + }; + + var CSSProperty = { + isUnitlessNumber: isUnitlessNumber, + shorthandPropertyExpansions: shorthandPropertyExpansions + }; + + module.exports = CSSProperty; + + +/***/ }, +/* 51 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ExecutionEnvironment + */ + + /*jslint evil: true */ + + "use strict"; + + var canUseDOM = !!( + (typeof window !== 'undefined' && + window.document && window.document.createElement) + ); + + /** + * Simple, lightweight module assisting with the detection and context of + * Worker. Helps avoid circular dependencies and allows code to reason about + * whether or not they are in a Worker, even if they never include the main + * `ReactWorker` dependency. + */ + var ExecutionEnvironment = { + + canUseDOM: canUseDOM, + + canUseWorkers: typeof Worker !== 'undefined', + + canUseEventListeners: + canUseDOM && !!(window.addEventListener || window.attachEvent), + + canUseViewport: canUseDOM && !!window.screen, + + isInWorker: !canUseDOM // For now, this is true - might change in the future. + + }; + + module.exports = ExecutionEnvironment; + + +/***/ }, +/* 52 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule camelizeStyleName + * @typechecks + */ + + "use strict"; + + var camelize = __webpack_require__(53); + + var msPattern = /^-ms-/; + + /** + * Camelcases a hyphenated CSS property name, for example: + * + * > camelizeStyleName('background-color') + * < "backgroundColor" + * > camelizeStyleName('-moz-transition') + * < "MozTransition" + * > camelizeStyleName('-ms-transition') + * < "msTransition" + * + * As Andi Smith suggests + * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix + * is converted to lowercase `ms`. + * + * @param {string} string + * @return {string} + */ + function camelizeStyleName(string) { + return camelize(string.replace(msPattern, 'ms-')); + } + + module.exports = camelizeStyleName; + + +/***/ }, +/* 53 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule camelize + * @typechecks + */ + + var _hyphenPattern = /-(.)/g; + + /** + * Camelcases a hyphenated string, for example: + * + * > camelize('background-color') + * < "backgroundColor" + * + * @param {string} string + * @return {string} + */ + function camelize(string) { + return string.replace(_hyphenPattern, function(_, character) { + return character.toUpperCase(); + }); + } + + module.exports = camelize; + + +/***/ }, +/* 54 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule dangerousStyleValue + * @typechecks static-only + */ + + 'use strict'; + + var CSSProperty = __webpack_require__(50); + + var isUnitlessNumber = CSSProperty.isUnitlessNumber; + + /** + * Convert a value into the proper css writable value. The style name `name` + * should be logical (no hyphens), as specified + * in `CSSProperty.isUnitlessNumber`. + * + * @param {string} name CSS property name such as `topMargin`. + * @param {*} value CSS property value such as `10px`. + * @return {string} Normalized style value with dimensions applied. + */ + function dangerousStyleValue(name, value) { + // Note that we've removed escapeTextForBrowser() calls here since the + // whole string will be escaped when the attribute is injected into + // the markup. If you provide unsafe user data here they can inject + // arbitrary CSS which may be problematic (I couldn't repro this): + // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet + // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ + // This is not an XSS hole but instead a potential CSS injection issue + // which has lead to a greater discussion about how we're going to + // trust URLs moving forward. See #2115901 + + var isEmpty = value == null || typeof value === 'boolean' || value === ''; + if (isEmpty) { + return ''; + } + + var isNonNumeric = isNaN(value); + if (isNonNumeric || value === 0 || + isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) { + return '' + value; // cast to string + } + + if (typeof value === 'string') { + value = value.trim(); + } + return value + 'px'; + } + + module.exports = dangerousStyleValue; + + +/***/ }, +/* 55 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule hyphenateStyleName + * @typechecks + */ + + "use strict"; + + var hyphenate = __webpack_require__(56); + + var msPattern = /^ms-/; + + /** + * Hyphenates a camelcased CSS property name, for example: + * + * > hyphenateStyleName('backgroundColor') + * < "background-color" + * > hyphenateStyleName('MozTransition') + * < "-moz-transition" + * > hyphenateStyleName('msTransition') + * < "-ms-transition" + * + * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix + * is converted to `-ms-`. + * + * @param {string} string + * @return {string} + */ + function hyphenateStyleName(string) { + return hyphenate(string).replace(msPattern, '-ms-'); + } + + module.exports = hyphenateStyleName; + + +/***/ }, +/* 56 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule hyphenate + * @typechecks + */ + + var _uppercasePattern = /([A-Z])/g; + + /** + * Hyphenates a camelcased string, for example: + * + * > hyphenate('backgroundColor') + * < "background-color" + * + * For CSS style names, use `hyphenateStyleName` instead which works properly + * with all vendor prefixes, including `ms`. + * + * @param {string} string + * @return {string} + */ + function hyphenate(string) { + return string.replace(_uppercasePattern, '-$1').toLowerCase(); + } + + module.exports = hyphenate; + + +/***/ }, +/* 57 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule memoizeStringOnly + * @typechecks static-only + */ + + 'use strict'; + + /** + * Memoizes the return value of a function that accepts one string argument. + * + * @param {function} callback + * @return {function} + */ + function memoizeStringOnly(callback) { + var cache = {}; + return function(string) { + if (!cache.hasOwnProperty(string)) { + cache[string] = callback.call(this, string); + } + return cache[string]; + }; + } + + module.exports = memoizeStringOnly; + + +/***/ }, +/* 58 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMChildrenOperations + * @typechecks static-only + */ + + 'use strict'; + + var Danger = __webpack_require__(59); + var ReactMultiChildUpdateTypes = __webpack_require__(64); + + var setTextContent = __webpack_require__(65); + var invariant = __webpack_require__(7); + + /** + * Inserts `childNode` as a child of `parentNode` at the `index`. + * + * @param {DOMElement} parentNode Parent node in which to insert. + * @param {DOMElement} childNode Child node to insert. + * @param {number} index Index at which to insert the child. + * @internal + */ + function insertChildAt(parentNode, childNode, index) { + // By exploiting arrays returning `undefined` for an undefined index, we can + // rely exclusively on `insertBefore(node, null)` instead of also using + // `appendChild(node)`. However, using `undefined` is not allowed by all + // browsers so we must replace it with `null`. + parentNode.insertBefore( + childNode, + parentNode.childNodes[index] || null + ); + } + + /** + * Operations for updating with DOM children. + */ + var DOMChildrenOperations = { + + dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, + + updateTextContent: setTextContent, + + /** + * Updates a component's children by processing a series of updates. The + * update configurations are each expected to have a `parentNode` property. + * + * @param {array} updates List of update configurations. + * @param {array} markupList List of markup strings. + * @internal + */ + processUpdates: function(updates, markupList) { + var update; + // Mapping from parent IDs to initial child orderings. + var initialChildren = null; + // List of children that will be moved or removed. + var updatedChildren = null; + + for (var i = 0; i < updates.length; i++) { + update = updates[i]; + if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || + update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { + var updatedIndex = update.fromIndex; + var updatedChild = update.parentNode.childNodes[updatedIndex]; + var parentID = update.parentID; + + ( false ? invariant( + updatedChild, + 'processUpdates(): Unable to find child %s of element. This ' + + 'probably means the DOM was unexpectedly mutated (e.g., by the ' + + 'browser), usually due to forgetting a when using tables, ' + + 'nesting tags like
,

, or , or using non-SVG elements ' + + 'in an parent. Try inspecting the child nodes of the element ' + + 'with React ID `%s`.', + updatedIndex, + parentID + ) : invariant(updatedChild)); + + initialChildren = initialChildren || {}; + initialChildren[parentID] = initialChildren[parentID] || []; + initialChildren[parentID][updatedIndex] = updatedChild; + + updatedChildren = updatedChildren || []; + updatedChildren.push(updatedChild); + } + } + + var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); + + // Remove updated children first so that `toIndex` is consistent. + if (updatedChildren) { + for (var j = 0; j < updatedChildren.length; j++) { + updatedChildren[j].parentNode.removeChild(updatedChildren[j]); + } + } + + for (var k = 0; k < updates.length; k++) { + update = updates[k]; + switch (update.type) { + case ReactMultiChildUpdateTypes.INSERT_MARKUP: + insertChildAt( + update.parentNode, + renderedMarkup[update.markupIndex], + update.toIndex + ); + break; + case ReactMultiChildUpdateTypes.MOVE_EXISTING: + insertChildAt( + update.parentNode, + initialChildren[update.parentID][update.fromIndex], + update.toIndex + ); + break; + case ReactMultiChildUpdateTypes.TEXT_CONTENT: + setTextContent( + update.parentNode, + update.textContent + ); + break; + case ReactMultiChildUpdateTypes.REMOVE_NODE: + // Already removed by the for-loop above. + break; + } + } + } + + }; + + module.exports = DOMChildrenOperations; + + +/***/ }, +/* 59 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule Danger + * @typechecks static-only + */ + + /*jslint evil: true, sub: true */ + + 'use strict'; + + var ExecutionEnvironment = __webpack_require__(51); + + var createNodesFromMarkup = __webpack_require__(60); + var emptyFunction = __webpack_require__(16); + var getMarkupWrap = __webpack_require__(63); + var invariant = __webpack_require__(7); + + var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; + var RESULT_INDEX_ATTR = 'data-danger-index'; + + /** + * Extracts the `nodeName` from a string of markup. + * + * NOTE: Extracting the `nodeName` does not require a regular expression match + * because we make assumptions about React-generated markup (i.e. there are no + * spaces surrounding the opening tag and there is at least one attribute). + * + * @param {string} markup String of markup. + * @return {string} Node name of the supplied markup. + * @see http://jsperf.com/extract-nodename + */ + function getNodeName(markup) { + return markup.substring(1, markup.indexOf(' ')); + } + + var Danger = { + + /** + * Renders markup into an array of nodes. The markup is expected to render + * into a list of root nodes. Also, the length of `resultList` and + * `markupList` should be the same. + * + * @param {array} markupList List of markup strings to render. + * @return {array} List of rendered nodes. + * @internal + */ + dangerouslyRenderMarkup: function(markupList) { + ( false ? invariant( + ExecutionEnvironment.canUseDOM, + 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + + 'thread. Make sure `window` and `document` are available globally ' + + 'before requiring React when unit testing or use ' + + 'React.renderToString for server rendering.' + ) : invariant(ExecutionEnvironment.canUseDOM)); + var nodeName; + var markupByNodeName = {}; + // Group markup by `nodeName` if a wrap is necessary, else by '*'. + for (var i = 0; i < markupList.length; i++) { + ( false ? invariant( + markupList[i], + 'dangerouslyRenderMarkup(...): Missing markup.' + ) : invariant(markupList[i])); + nodeName = getNodeName(markupList[i]); + nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; + markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; + markupByNodeName[nodeName][i] = markupList[i]; + } + var resultList = []; + var resultListAssignmentCount = 0; + for (nodeName in markupByNodeName) { + if (!markupByNodeName.hasOwnProperty(nodeName)) { + continue; + } + var markupListByNodeName = markupByNodeName[nodeName]; + + // This for-in loop skips the holes of the sparse array. The order of + // iteration should follow the order of assignment, which happens to match + // numerical index order, but we don't rely on that. + var resultIndex; + for (resultIndex in markupListByNodeName) { + if (markupListByNodeName.hasOwnProperty(resultIndex)) { + var markup = markupListByNodeName[resultIndex]; + + // Push the requested markup with an additional RESULT_INDEX_ATTR + // attribute. If the markup does not start with a < character, it + // will be discarded below (with an appropriate console.error). + markupListByNodeName[resultIndex] = markup.replace( + OPEN_TAG_NAME_EXP, + // This index will be parsed back out below. + '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' + ); + } + } + + // Render each group of markup with similar wrapping `nodeName`. + var renderNodes = createNodesFromMarkup( + markupListByNodeName.join(''), + emptyFunction // Do nothing special with

, + // they will be initialized in the wrong namespace (and will not display). + 'circle': true, + 'clipPath': true, + 'defs': true, + 'ellipse': true, + 'g': true, + 'line': true, + 'linearGradient': true, + 'path': true, + 'polygon': true, + 'polyline': true, + 'radialGradient': true, + 'rect': true, + 'stop': true, + 'text': true + }; + + var selectWrap = [1, '']; + var tableWrap = [1, '', '
']; + var trWrap = [3, '', '
']; + + var svgWrap = [1, '', '']; + + var markupWrap = { + '*': [1, '?
', '
'], + + 'area': [1, '', ''], + 'col': [2, '', '
'], + 'legend': [1, '
', '
'], + 'param': [1, '', ''], + 'tr': [2, '', '
'], + + 'optgroup': selectWrap, + 'option': selectWrap, + + 'caption': tableWrap, + 'colgroup': tableWrap, + 'tbody': tableWrap, + 'tfoot': tableWrap, + 'thead': tableWrap, + + 'td': trWrap, + 'th': trWrap, + + 'circle': svgWrap, + 'clipPath': svgWrap, + 'defs': svgWrap, + 'ellipse': svgWrap, + 'g': svgWrap, + 'line': svgWrap, + 'linearGradient': svgWrap, + 'path': svgWrap, + 'polygon': svgWrap, + 'polyline': svgWrap, + 'radialGradient': svgWrap, + 'rect': svgWrap, + 'stop': svgWrap, + 'text': svgWrap + }; + + /** + * Gets the markup wrap configuration for the supplied `nodeName`. + * + * NOTE: This lazily detects which wraps are necessary for the current browser. + * + * @param {string} nodeName Lowercase `nodeName`. + * @return {?array} Markup wrap configuration, if applicable. + */ + function getMarkupWrap(nodeName) { + ( false ? invariant(!!dummyNode, 'Markup wrapping node not initialized') : invariant(!!dummyNode)); + if (!markupWrap.hasOwnProperty(nodeName)) { + nodeName = '*'; + } + if (!shouldWrap.hasOwnProperty(nodeName)) { + if (nodeName === '*') { + dummyNode.innerHTML = ''; + } else { + dummyNode.innerHTML = '<' + nodeName + '>'; + } + shouldWrap[nodeName] = !dummyNode.firstChild; + } + return shouldWrap[nodeName] ? markupWrap[nodeName] : null; + } + + + module.exports = getMarkupWrap; + + +/***/ }, +/* 64 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactMultiChildUpdateTypes + */ + + 'use strict'; + + var keyMirror = __webpack_require__(6); + + /** + * When a component's children are updated, a series of update configuration + * objects are created in order to batch and serialize the required changes. + * + * Enumerates all the possible types of update configurations. + * + * @internal + */ + var ReactMultiChildUpdateTypes = keyMirror({ + INSERT_MARKUP: null, + MOVE_EXISTING: null, + REMOVE_NODE: null, + TEXT_CONTENT: null + }); + + module.exports = ReactMultiChildUpdateTypes; + + +/***/ }, +/* 65 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule setTextContent + */ + + 'use strict'; + + var ExecutionEnvironment = __webpack_require__(51); + var escapeTextContentForBrowser = __webpack_require__(46); + var setInnerHTML = __webpack_require__(66); + + /** + * Set the textContent property of a node, ensuring that whitespace is preserved + * even in IE8. innerText is a poor substitute for textContent and, among many + * issues, inserts
instead of the literal newline chars. innerHTML behaves + * as it should. + * + * @param {DOMElement} node + * @param {string} text + * @internal + */ + var setTextContent = function(node, text) { + node.textContent = text; + }; + + if (ExecutionEnvironment.canUseDOM) { + if (!('textContent' in document.documentElement)) { + setTextContent = function(node, text) { + setInnerHTML(node, escapeTextContentForBrowser(text)); + }; + } + } + + module.exports = setTextContent; + + +/***/ }, +/* 66 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule setInnerHTML + */ + + /* globals MSApp */ + + 'use strict'; + + var ExecutionEnvironment = __webpack_require__(51); + + var WHITESPACE_TEST = /^[ \r\n\t\f]/; + var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; + + /** + * Set the innerHTML property of a node, ensuring that whitespace is preserved + * even in IE8. + * + * @param {DOMElement} node + * @param {string} html + * @internal + */ + var setInnerHTML = function(node, html) { + node.innerHTML = html; + }; + + // Win8 apps: Allow all html to be inserted + if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { + setInnerHTML = function(node, html) { + MSApp.execUnsafeLocalFunction(function() { + node.innerHTML = html; + }); + }; + } + + if (ExecutionEnvironment.canUseDOM) { + // IE8: When updating a just created node with innerHTML only leading + // whitespace is removed. When updating an existing node with innerHTML + // whitespace in root TextNodes is also collapsed. + // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html + + // Feature detection; only IE8 is known to behave improperly like this. + var testElement = document.createElement('div'); + testElement.innerHTML = ' '; + if (testElement.innerHTML === '') { + setInnerHTML = function(node, html) { + // Magic theory: IE8 supposedly differentiates between added and updated + // nodes when processing innerHTML, innerHTML on updated nodes suffers + // from worse whitespace behavior. Re-adding a node like this triggers + // the initial and more favorable whitespace behavior. + // TODO: What to do on a detached node? + if (node.parentNode) { + node.parentNode.replaceChild(node, node); + } + + // We also implement a workaround for non-visible tags disappearing into + // thin air on IE8, this only happens if there is no visible text + // in-front of the non-visible tags. Piggyback on the whitespace fix + // and simply check if any non-visible tags appear in the source. + if (WHITESPACE_TEST.test(html) || + html[0] === '<' && NONVISIBLE_TEST.test(html)) { + // Recover leading whitespace by temporarily prepending any character. + // \uFEFF has the potential advantage of being zero-width/invisible. + node.innerHTML = '\uFEFF' + html; + + // deleteData leaves an empty `TextNode` which offsets the index of all + // children. Definitely want to avoid this. + var textNode = node.firstChild; + if (textNode.data.length === 1) { + node.removeChild(textNode); + } else { + textNode.deleteData(0, 1); + } + } else { + node.innerHTML = html; + } + }; + } + } + + module.exports = setInnerHTML; + + +/***/ }, +/* 67 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactMount + */ + + 'use strict'; + + var DOMProperty = __webpack_require__(44); + var ReactBrowserEventEmitter = __webpack_require__(68); + var ReactCurrentOwner = __webpack_require__(17); + var ReactElement = __webpack_require__(11); + var ReactElementValidator = __webpack_require__(32); + var ReactEmptyComponent = __webpack_require__(76); + var ReactInstanceHandles = __webpack_require__(19); + var ReactInstanceMap = __webpack_require__(25); + var ReactMarkupChecksum = __webpack_require__(77); + var ReactPerf = __webpack_require__(28); + var ReactReconciler = __webpack_require__(29); + var ReactUpdateQueue = __webpack_require__(23); + var ReactUpdates = __webpack_require__(26); + + var emptyObject = __webpack_require__(14); + var containsNode = __webpack_require__(79); + var getReactRootElementInContainer = __webpack_require__(82); + var instantiateReactComponent = __webpack_require__(83); + var invariant = __webpack_require__(7); + var setInnerHTML = __webpack_require__(66); + var shouldUpdateReactComponent = __webpack_require__(86); + var warning = __webpack_require__(15); + + var SEPARATOR = ReactInstanceHandles.SEPARATOR; + + var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; + var nodeCache = {}; + + var ELEMENT_NODE_TYPE = 1; + var DOC_NODE_TYPE = 9; + + /** Mapping from reactRootID to React component instance. */ + var instancesByReactRootID = {}; + + /** Mapping from reactRootID to `container` nodes. */ + var containersByReactRootID = {}; + + if (false) { + /** __DEV__-only mapping from reactRootID to root elements. */ + var rootElementsByReactRootID = {}; + } + + // Used to store breadth-first search state in findComponentRoot. + var findComponentRootReusableArray = []; + + /** + * Finds the index of the first character + * that's not common between the two given strings. + * + * @return {number} the index of the character where the strings diverge + */ + function firstDifferenceIndex(string1, string2) { + var minLen = Math.min(string1.length, string2.length); + for (var i = 0; i < minLen; i++) { + if (string1.charAt(i) !== string2.charAt(i)) { + return i; + } + } + return string1.length === string2.length ? -1 : minLen; + } + + /** + * @param {DOMElement} container DOM element that may contain a React component. + * @return {?string} A "reactRoot" ID, if a React component is rendered. + */ + function getReactRootID(container) { + var rootElement = getReactRootElementInContainer(container); + return rootElement && ReactMount.getID(rootElement); + } + + /** + * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form + * element can return its control whose name or ID equals ATTR_NAME. All + * DOM nodes support `getAttributeNode` but this can also get called on + * other objects so just return '' if we're given something other than a + * DOM node (such as window). + * + * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node. + * @return {string} ID of the supplied `domNode`. + */ + function getID(node) { + var id = internalGetID(node); + if (id) { + if (nodeCache.hasOwnProperty(id)) { + var cached = nodeCache[id]; + if (cached !== node) { + ( false ? invariant( + !isValid(cached, id), + 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', + ATTR_NAME, id + ) : invariant(!isValid(cached, id))); + + nodeCache[id] = node; + } + } else { + nodeCache[id] = node; + } + } + + return id; + } + + function internalGetID(node) { + // If node is something like a window, document, or text node, none of + // which support attributes or a .getAttribute method, gracefully return + // the empty string, as if the attribute were missing. + return node && node.getAttribute && node.getAttribute(ATTR_NAME) || ''; + } + + /** + * Sets the React-specific ID of the given node. + * + * @param {DOMElement} node The DOM node whose ID will be set. + * @param {string} id The value of the ID attribute. + */ + function setID(node, id) { + var oldID = internalGetID(node); + if (oldID !== id) { + delete nodeCache[oldID]; + } + node.setAttribute(ATTR_NAME, id); + nodeCache[id] = node; + } + + /** + * Finds the node with the supplied React-generated DOM ID. + * + * @param {string} id A React-generated DOM ID. + * @return {DOMElement} DOM node with the suppled `id`. + * @internal + */ + function getNode(id) { + if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { + nodeCache[id] = ReactMount.findReactNodeByID(id); + } + return nodeCache[id]; + } + + /** + * Finds the node with the supplied public React instance. + * + * @param {*} instance A public React instance. + * @return {?DOMElement} DOM node with the suppled `id`. + * @internal + */ + function getNodeFromInstance(instance) { + var id = ReactInstanceMap.get(instance)._rootNodeID; + if (ReactEmptyComponent.isNullComponentID(id)) { + return null; + } + if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { + nodeCache[id] = ReactMount.findReactNodeByID(id); + } + return nodeCache[id]; + } + + /** + * A node is "valid" if it is contained by a currently mounted container. + * + * This means that the node does not have to be contained by a document in + * order to be considered valid. + * + * @param {?DOMElement} node The candidate DOM node. + * @param {string} id The expected ID of the node. + * @return {boolean} Whether the node is contained by a mounted container. + */ + function isValid(node, id) { + if (node) { + ( false ? invariant( + internalGetID(node) === id, + 'ReactMount: Unexpected modification of `%s`', + ATTR_NAME + ) : invariant(internalGetID(node) === id)); + + var container = ReactMount.findReactContainerForID(id); + if (container && containsNode(container, node)) { + return true; + } + } + + return false; + } + + /** + * Causes the cache to forget about one React-specific ID. + * + * @param {string} id The ID to forget. + */ + function purgeID(id) { + delete nodeCache[id]; + } + + var deepestNodeSoFar = null; + function findDeepestCachedAncestorImpl(ancestorID) { + var ancestor = nodeCache[ancestorID]; + if (ancestor && isValid(ancestor, ancestorID)) { + deepestNodeSoFar = ancestor; + } else { + // This node isn't populated in the cache, so presumably none of its + // descendants are. Break out of the loop. + return false; + } + } + + /** + * Return the deepest cached node whose ID is a prefix of `targetID`. + */ + function findDeepestCachedAncestor(targetID) { + deepestNodeSoFar = null; + ReactInstanceHandles.traverseAncestors( + targetID, + findDeepestCachedAncestorImpl + ); + + var foundNode = deepestNodeSoFar; + deepestNodeSoFar = null; + return foundNode; + } + + /** + * Mounts this component and inserts it into the DOM. + * + * @param {ReactComponent} componentInstance The instance to mount. + * @param {string} rootID DOM ID of the root node. + * @param {DOMElement} container DOM element to mount into. + * @param {ReactReconcileTransaction} transaction + * @param {boolean} shouldReuseMarkup If true, do not insert markup + */ + function mountComponentIntoNode( + componentInstance, + rootID, + container, + transaction, + shouldReuseMarkup) { + var markup = ReactReconciler.mountComponent( + componentInstance, rootID, transaction, emptyObject + ); + componentInstance._isTopLevel = true; + ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup); + } + + /** + * Batched mount. + * + * @param {ReactComponent} componentInstance The instance to mount. + * @param {string} rootID DOM ID of the root node. + * @param {DOMElement} container DOM element to mount into. + * @param {boolean} shouldReuseMarkup If true, do not insert markup + */ + function batchedMountComponentIntoNode( + componentInstance, + rootID, + container, + shouldReuseMarkup) { + var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); + transaction.perform( + mountComponentIntoNode, + null, + componentInstance, + rootID, + container, + transaction, + shouldReuseMarkup + ); + ReactUpdates.ReactReconcileTransaction.release(transaction); + } + + /** + * Mounting is the process of initializing a React component by creating its + * representative DOM elements and inserting them into a supplied `container`. + * Any prior content inside `container` is destroyed in the process. + * + * ReactMount.render( + * component, + * document.getElementById('container') + * ); + * + *
<-- Supplied `container`. + *
<-- Rendered reactRoot of React + * // ... component. + *
+ *
+ * + * Inside of `container`, the first element rendered is the "reactRoot". + */ + var ReactMount = { + /** Exposed for debugging purposes **/ + _instancesByReactRootID: instancesByReactRootID, + + /** + * This is a hook provided to support rendering React components while + * ensuring that the apparent scroll position of its `container` does not + * change. + * + * @param {DOMElement} container The `container` being rendered into. + * @param {function} renderCallback This must be called once to do the render. + */ + scrollMonitor: function(container, renderCallback) { + renderCallback(); + }, + + /** + * Take a component that's already mounted into the DOM and replace its props + * @param {ReactComponent} prevComponent component instance already in the DOM + * @param {ReactElement} nextElement component instance to render + * @param {DOMElement} container container to render into + * @param {?function} callback function triggered on completion + */ + _updateRootComponent: function( + prevComponent, + nextElement, + container, + callback) { + if (false) { + ReactElementValidator.checkAndWarnForMutatedProps(nextElement); + } + + ReactMount.scrollMonitor(container, function() { + ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement); + if (callback) { + ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); + } + }); + + if (false) { + // Record the root element in case it later gets transplanted. + rootElementsByReactRootID[getReactRootID(container)] = + getReactRootElementInContainer(container); + } + + return prevComponent; + }, + + /** + * Register a component into the instance map and starts scroll value + * monitoring + * @param {ReactComponent} nextComponent component instance to render + * @param {DOMElement} container container to render into + * @return {string} reactRoot ID prefix + */ + _registerComponent: function(nextComponent, container) { + ( false ? invariant( + container && ( + (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) + ), + '_registerComponent(...): Target container is not a DOM element.' + ) : invariant(container && ( + (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) + ))); + + ReactBrowserEventEmitter.ensureScrollValueMonitoring(); + + var reactRootID = ReactMount.registerContainer(container); + instancesByReactRootID[reactRootID] = nextComponent; + return reactRootID; + }, + + /** + * Render a new component into the DOM. + * @param {ReactElement} nextElement element to render + * @param {DOMElement} container container to render into + * @param {boolean} shouldReuseMarkup if we should skip the markup insertion + * @return {ReactComponent} nextComponent + */ + _renderNewRootComponent: function( + nextElement, + container, + shouldReuseMarkup + ) { + // Various parts of our code (such as ReactCompositeComponent's + // _renderValidatedComponent) assume that calls to render aren't nested; + // verify that that's the case. + ( false ? warning( + ReactCurrentOwner.current == null, + '_renderNewRootComponent(): Render methods should be a pure function ' + + 'of props and state; triggering nested component updates from ' + + 'render is not allowed. If necessary, trigger nested updates in ' + + 'componentDidUpdate.' + ) : null); + + var componentInstance = instantiateReactComponent(nextElement, null); + var reactRootID = ReactMount._registerComponent( + componentInstance, + container + ); + + // The initial render is synchronous but any updates that happen during + // rendering, in componentWillMount or componentDidMount, will be batched + // according to the current batching strategy. + + ReactUpdates.batchedUpdates( + batchedMountComponentIntoNode, + componentInstance, + reactRootID, + container, + shouldReuseMarkup + ); + + if (false) { + // Record the root element in case it later gets transplanted. + rootElementsByReactRootID[reactRootID] = + getReactRootElementInContainer(container); + } + + return componentInstance; + }, + + /** + * Renders a React component into the DOM in the supplied `container`. + * + * If the React component was previously rendered into `container`, this will + * perform an update on it and only mutate the DOM as necessary to reflect the + * latest React component. + * + * @param {ReactElement} nextElement Component element to render. + * @param {DOMElement} container DOM element to render into. + * @param {?function} callback function triggered on completion + * @return {ReactComponent} Component instance rendered in `container`. + */ + render: function(nextElement, container, callback) { + ( false ? invariant( + ReactElement.isValidElement(nextElement), + 'React.render(): Invalid component element.%s', + ( + typeof nextElement === 'string' ? + ' Instead of passing an element string, make sure to instantiate ' + + 'it by passing it to React.createElement.' : + typeof nextElement === 'function' ? + ' Instead of passing a component class, make sure to instantiate ' + + 'it by passing it to React.createElement.' : + // Check if it quacks like an element + nextElement != null && nextElement.props !== undefined ? + ' This may be caused by unintentionally loading two independent ' + + 'copies of React.' : + '' + ) + ) : invariant(ReactElement.isValidElement(nextElement))); + + var prevComponent = instancesByReactRootID[getReactRootID(container)]; + + if (prevComponent) { + var prevElement = prevComponent._currentElement; + if (shouldUpdateReactComponent(prevElement, nextElement)) { + return ReactMount._updateRootComponent( + prevComponent, + nextElement, + container, + callback + ).getPublicInstance(); + } else { + ReactMount.unmountComponentAtNode(container); + } + } + + var reactRootElement = getReactRootElementInContainer(container); + var containerHasReactMarkup = + reactRootElement && ReactMount.isRenderedByReact(reactRootElement); + + if (false) { + if (!containerHasReactMarkup || reactRootElement.nextSibling) { + var rootElementSibling = reactRootElement; + while (rootElementSibling) { + if (ReactMount.isRenderedByReact(rootElementSibling)) { + ("production" !== process.env.NODE_ENV ? warning( + false, + 'render(): Target node has markup rendered by React, but there ' + + 'are unrelated nodes as well. This is most commonly caused by ' + + 'white-space inserted around server-rendered markup.' + ) : null); + break; + } + + rootElementSibling = rootElementSibling.nextSibling; + } + } + } + + var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; + + var component = ReactMount._renderNewRootComponent( + nextElement, + container, + shouldReuseMarkup + ).getPublicInstance(); + if (callback) { + callback.call(component); + } + return component; + }, + + /** + * Constructs a component instance of `constructor` with `initialProps` and + * renders it into the supplied `container`. + * + * @param {function} constructor React component constructor. + * @param {?object} props Initial props of the component instance. + * @param {DOMElement} container DOM element to render into. + * @return {ReactComponent} Component instance rendered in `container`. + */ + constructAndRenderComponent: function(constructor, props, container) { + var element = ReactElement.createElement(constructor, props); + return ReactMount.render(element, container); + }, + + /** + * Constructs a component instance of `constructor` with `initialProps` and + * renders it into a container node identified by supplied `id`. + * + * @param {function} componentConstructor React component constructor + * @param {?object} props Initial props of the component instance. + * @param {string} id ID of the DOM element to render into. + * @return {ReactComponent} Component instance rendered in the container node. + */ + constructAndRenderComponentByID: function(constructor, props, id) { + var domNode = document.getElementById(id); + ( false ? invariant( + domNode, + 'Tried to get element with id of "%s" but it is not present on the page.', + id + ) : invariant(domNode)); + return ReactMount.constructAndRenderComponent(constructor, props, domNode); + }, + + /** + * Registers a container node into which React components will be rendered. + * This also creates the "reactRoot" ID that will be assigned to the element + * rendered within. + * + * @param {DOMElement} container DOM element to register as a container. + * @return {string} The "reactRoot" ID of elements rendered within. + */ + registerContainer: function(container) { + var reactRootID = getReactRootID(container); + if (reactRootID) { + // If one exists, make sure it is a valid "reactRoot" ID. + reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID); + } + if (!reactRootID) { + // No valid "reactRoot" ID found, create one. + reactRootID = ReactInstanceHandles.createReactRootID(); + } + containersByReactRootID[reactRootID] = container; + return reactRootID; + }, + + /** + * Unmounts and destroys the React component rendered in the `container`. + * + * @param {DOMElement} container DOM element containing a React component. + * @return {boolean} True if a component was found in and unmounted from + * `container` + */ + unmountComponentAtNode: function(container) { + // Various parts of our code (such as ReactCompositeComponent's + // _renderValidatedComponent) assume that calls to render aren't nested; + // verify that that's the case. (Strictly speaking, unmounting won't cause a + // render but we still don't expect to be in a render call here.) + ( false ? warning( + ReactCurrentOwner.current == null, + 'unmountComponentAtNode(): Render methods should be a pure function of ' + + 'props and state; triggering nested component updates from render is ' + + 'not allowed. If necessary, trigger nested updates in ' + + 'componentDidUpdate.' + ) : null); + + ( false ? invariant( + container && ( + (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) + ), + 'unmountComponentAtNode(...): Target container is not a DOM element.' + ) : invariant(container && ( + (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) + ))); + + var reactRootID = getReactRootID(container); + var component = instancesByReactRootID[reactRootID]; + if (!component) { + return false; + } + ReactMount.unmountComponentFromNode(component, container); + delete instancesByReactRootID[reactRootID]; + delete containersByReactRootID[reactRootID]; + if (false) { + delete rootElementsByReactRootID[reactRootID]; + } + return true; + }, + + /** + * Unmounts a component and removes it from the DOM. + * + * @param {ReactComponent} instance React component instance. + * @param {DOMElement} container DOM element to unmount from. + * @final + * @internal + * @see {ReactMount.unmountComponentAtNode} + */ + unmountComponentFromNode: function(instance, container) { + ReactReconciler.unmountComponent(instance); + + if (container.nodeType === DOC_NODE_TYPE) { + container = container.documentElement; + } + + // http://jsperf.com/emptying-a-node + while (container.lastChild) { + container.removeChild(container.lastChild); + } + }, + + /** + * Finds the container DOM element that contains React component to which the + * supplied DOM `id` belongs. + * + * @param {string} id The ID of an element rendered by a React component. + * @return {?DOMElement} DOM element that contains the `id`. + */ + findReactContainerForID: function(id) { + var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id); + var container = containersByReactRootID[reactRootID]; + + if (false) { + var rootElement = rootElementsByReactRootID[reactRootID]; + if (rootElement && rootElement.parentNode !== container) { + ("production" !== process.env.NODE_ENV ? invariant( + // Call internalGetID here because getID calls isValid which calls + // findReactContainerForID (this function). + internalGetID(rootElement) === reactRootID, + 'ReactMount: Root element ID differed from reactRootID.' + ) : invariant(// Call internalGetID here because getID calls isValid which calls + // findReactContainerForID (this function). + internalGetID(rootElement) === reactRootID)); + + var containerChild = container.firstChild; + if (containerChild && + reactRootID === internalGetID(containerChild)) { + // If the container has a new child with the same ID as the old + // root element, then rootElementsByReactRootID[reactRootID] is + // just stale and needs to be updated. The case that deserves a + // warning is when the container is empty. + rootElementsByReactRootID[reactRootID] = containerChild; + } else { + ("production" !== process.env.NODE_ENV ? warning( + false, + 'ReactMount: Root element has been removed from its original ' + + 'container. New container:', rootElement.parentNode + ) : null); + } + } + } + + return container; + }, + + /** + * Finds an element rendered by React with the supplied ID. + * + * @param {string} id ID of a DOM node in the React component. + * @return {DOMElement} Root DOM node of the React component. + */ + findReactNodeByID: function(id) { + var reactRoot = ReactMount.findReactContainerForID(id); + return ReactMount.findComponentRoot(reactRoot, id); + }, + + /** + * True if the supplied `node` is rendered by React. + * + * @param {*} node DOM Element to check. + * @return {boolean} True if the DOM Element appears to be rendered by React. + * @internal + */ + isRenderedByReact: function(node) { + if (node.nodeType !== 1) { + // Not a DOMElement, therefore not a React component + return false; + } + var id = ReactMount.getID(node); + return id ? id.charAt(0) === SEPARATOR : false; + }, + + /** + * Traverses up the ancestors of the supplied node to find a node that is a + * DOM representation of a React component. + * + * @param {*} node + * @return {?DOMEventTarget} + * @internal + */ + getFirstReactDOM: function(node) { + var current = node; + while (current && current.parentNode !== current) { + if (ReactMount.isRenderedByReact(current)) { + return current; + } + current = current.parentNode; + } + return null; + }, + + /** + * Finds a node with the supplied `targetID` inside of the supplied + * `ancestorNode`. Exploits the ID naming scheme to perform the search + * quickly. + * + * @param {DOMEventTarget} ancestorNode Search from this root. + * @pararm {string} targetID ID of the DOM representation of the component. + * @return {DOMEventTarget} DOM node with the supplied `targetID`. + * @internal + */ + findComponentRoot: function(ancestorNode, targetID) { + var firstChildren = findComponentRootReusableArray; + var childIndex = 0; + + var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode; + + firstChildren[0] = deepestAncestor.firstChild; + firstChildren.length = 1; + + while (childIndex < firstChildren.length) { + var child = firstChildren[childIndex++]; + var targetChild; + + while (child) { + var childID = ReactMount.getID(child); + if (childID) { + // Even if we find the node we're looking for, we finish looping + // through its siblings to ensure they're cached so that we don't have + // to revisit this node again. Otherwise, we make n^2 calls to getID + // when visiting the many children of a single node in order. + + if (targetID === childID) { + targetChild = child; + } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) { + // If we find a child whose ID is an ancestor of the given ID, + // then we can be sure that we only want to search the subtree + // rooted at this child, so we can throw out the rest of the + // search state. + firstChildren.length = childIndex = 0; + firstChildren.push(child.firstChild); + } + + } else { + // If this child had no ID, then there's a chance that it was + // injected automatically by the browser, as when a `` + // element sprouts an extra `` child as a side effect of + // `.innerHTML` parsing. Optimistically continue down this + // branch, but not before examining the other siblings. + firstChildren.push(child.firstChild); + } + + child = child.nextSibling; + } + + if (targetChild) { + // Emptying firstChildren/findComponentRootReusableArray is + // not necessary for correctness, but it helps the GC reclaim + // any nodes that were left at the end of the search. + firstChildren.length = 0; + + return targetChild; + } + } + + firstChildren.length = 0; + + ( false ? invariant( + false, + 'findComponentRoot(..., %s): Unable to find element. This probably ' + + 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + + 'usually due to forgetting a when using tables, nesting tags ' + + 'like ,

, or , or using non-SVG elements in an ' + + 'parent. ' + + 'Try inspecting the child nodes of the element with React ID `%s`.', + targetID, + ReactMount.getID(ancestorNode) + ) : invariant(false)); + }, + + _mountImageIntoNode: function(markup, container, shouldReuseMarkup) { + ( false ? invariant( + container && ( + (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) + ), + 'mountComponentIntoNode(...): Target container is not valid.' + ) : invariant(container && ( + (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE) + ))); + + if (shouldReuseMarkup) { + var rootElement = getReactRootElementInContainer(container); + if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) { + return; + } else { + var checksum = rootElement.getAttribute( + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + ); + rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); + + var rootMarkup = rootElement.outerHTML; + rootElement.setAttribute( + ReactMarkupChecksum.CHECKSUM_ATTR_NAME, + checksum + ); + + var diffIndex = firstDifferenceIndex(markup, rootMarkup); + var difference = ' (client) ' + + markup.substring(diffIndex - 20, diffIndex + 20) + + '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); + + ( false ? invariant( + container.nodeType !== DOC_NODE_TYPE, + 'You\'re trying to render a component to the document using ' + + 'server rendering but the checksum was invalid. This usually ' + + 'means you rendered a different component type or props on ' + + 'the client from the one on the server, or your render() ' + + 'methods are impure. React cannot handle this case due to ' + + 'cross-browser quirks by rendering at the document root. You ' + + 'should look for environment dependent code in your components ' + + 'and ensure the props are the same client and server side:\n%s', + difference + ) : invariant(container.nodeType !== DOC_NODE_TYPE)); + + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + false, + 'React attempted to reuse markup in a container but the ' + + 'checksum was invalid. This generally means that you are ' + + 'using server rendering and the markup generated on the ' + + 'server was not what the client was expecting. React injected ' + + 'new markup to compensate which works but you have lost many ' + + 'of the benefits of server rendering. Instead, figure out ' + + 'why the markup being generated is different on the client ' + + 'or server:\n%s', + difference + ) : null); + } + } + } + + ( false ? invariant( + container.nodeType !== DOC_NODE_TYPE, + 'You\'re trying to render a component to the document but ' + + 'you didn\'t use server rendering. We can\'t do this ' + + 'without using server rendering due to cross-browser quirks. ' + + 'See React.renderToString() for server rendering.' + ) : invariant(container.nodeType !== DOC_NODE_TYPE)); + + setInnerHTML(container, markup); + }, + + /** + * React ID utilities. + */ + + getReactRootID: getReactRootID, + + getID: getID, + + setID: setID, + + getNode: getNode, + + getNodeFromInstance: getNodeFromInstance, + + purgeID: purgeID + }; + + ReactPerf.measureMethods(ReactMount, 'ReactMount', { + _renderNewRootComponent: '_renderNewRootComponent', + _mountImageIntoNode: '_mountImageIntoNode' + }); + + module.exports = ReactMount; + + +/***/ }, +/* 68 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactBrowserEventEmitter + * @typechecks static-only + */ + + 'use strict'; + + var EventConstants = __webpack_require__(5); + var EventPluginHub = __webpack_require__(69); + var EventPluginRegistry = __webpack_require__(70); + var ReactEventEmitterMixin = __webpack_require__(73); + var ViewportMetrics = __webpack_require__(74); + + var assign = __webpack_require__(13); + var isEventSupported = __webpack_require__(75); + + /** + * Summary of `ReactBrowserEventEmitter` event handling: + * + * - Top-level delegation is used to trap most native browser events. This + * may only occur in the main thread and is the responsibility of + * ReactEventListener, which is injected and can therefore support pluggable + * event sources. This is the only work that occurs in the main thread. + * + * - We normalize and de-duplicate events to account for browser quirks. This + * may be done in the worker thread. + * + * - Forward these native events (with the associated top-level type used to + * trap it) to `EventPluginHub`, which in turn will ask plugins if they want + * to extract any synthetic events. + * + * - The `EventPluginHub` will then process each event by annotating them with + * "dispatches", a sequence of listeners and IDs that care about that event. + * + * - The `EventPluginHub` then dispatches the events. + * + * Overview of React and the event system: + * + * +------------+ . + * | DOM | . + * +------------+ . + * | . + * v . + * +------------+ . + * | ReactEvent | . + * | Listener | . + * +------------+ . +-----------+ + * | . +--------+|SimpleEvent| + * | . | |Plugin | + * +-----|------+ . v +-----------+ + * | | | . +--------------+ +------------+ + * | +-----------.--->|EventPluginHub| | Event | + * | | . | | +-----------+ | Propagators| + * | ReactEvent | . | | |TapEvent | |------------| + * | Emitter | . | |<---+|Plugin | |other plugin| + * | | . | | +-----------+ | utilities | + * | +-----------.--->| | +------------+ + * | | | . +--------------+ + * +-----|------+ . ^ +-----------+ + * | . | |Enter/Leave| + * + . +-------+|Plugin | + * +-------------+ . +-----------+ + * | application | . + * |-------------| . + * | | . + * | | . + * +-------------+ . + * . + * React Core . General Purpose Event Plugin System + */ + + var alreadyListeningTo = {}; + var isMonitoringScrollValue = false; + var reactTopListenersCounter = 0; + + // For events like 'submit' which don't consistently bubble (which we trap at a + // lower node than `document`), binding at `document` would cause duplicate + // events so we don't include them here + var topEventMapping = { + topBlur: 'blur', + topChange: 'change', + topClick: 'click', + topCompositionEnd: 'compositionend', + topCompositionStart: 'compositionstart', + topCompositionUpdate: 'compositionupdate', + topContextMenu: 'contextmenu', + topCopy: 'copy', + topCut: 'cut', + topDoubleClick: 'dblclick', + topDrag: 'drag', + topDragEnd: 'dragend', + topDragEnter: 'dragenter', + topDragExit: 'dragexit', + topDragLeave: 'dragleave', + topDragOver: 'dragover', + topDragStart: 'dragstart', + topDrop: 'drop', + topFocus: 'focus', + topInput: 'input', + topKeyDown: 'keydown', + topKeyPress: 'keypress', + topKeyUp: 'keyup', + topMouseDown: 'mousedown', + topMouseMove: 'mousemove', + topMouseOut: 'mouseout', + topMouseOver: 'mouseover', + topMouseUp: 'mouseup', + topPaste: 'paste', + topScroll: 'scroll', + topSelectionChange: 'selectionchange', + topTextInput: 'textInput', + topTouchCancel: 'touchcancel', + topTouchEnd: 'touchend', + topTouchMove: 'touchmove', + topTouchStart: 'touchstart', + topWheel: 'wheel' + }; + + /** + * To ensure no conflicts with other potential React instances on the page + */ + var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2); + + function getListeningForDocument(mountAt) { + // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` + // directly. + if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { + mountAt[topListenersIDKey] = reactTopListenersCounter++; + alreadyListeningTo[mountAt[topListenersIDKey]] = {}; + } + return alreadyListeningTo[mountAt[topListenersIDKey]]; + } + + /** + * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For + * example: + * + * ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction); + * + * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. + * + * @internal + */ + var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { + + /** + * Injectable event backend + */ + ReactEventListener: null, + + injection: { + /** + * @param {object} ReactEventListener + */ + injectReactEventListener: function(ReactEventListener) { + ReactEventListener.setHandleTopLevel( + ReactBrowserEventEmitter.handleTopLevel + ); + ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; + } + }, + + /** + * Sets whether or not any created callbacks should be enabled. + * + * @param {boolean} enabled True if callbacks should be enabled. + */ + setEnabled: function(enabled) { + if (ReactBrowserEventEmitter.ReactEventListener) { + ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); + } + }, + + /** + * @return {boolean} True if callbacks are enabled. + */ + isEnabled: function() { + return !!( + (ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled()) + ); + }, + + /** + * We listen for bubbled touch events on the document object. + * + * Firefox v8.01 (and possibly others) exhibited strange behavior when + * mounting `onmousemove` events at some node that was not the document + * element. The symptoms were that if your mouse is not moving over something + * contained within that mount point (for example on the background) the + * top-level listeners for `onmousemove` won't be called. However, if you + * register the `mousemove` on the document object, then it will of course + * catch all `mousemove`s. This along with iOS quirks, justifies restricting + * top-level listeners to the document object only, at least for these + * movement types of events and possibly all events. + * + * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html + * + * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but + * they bubble to document. + * + * @param {string} registrationName Name of listener (e.g. `onClick`). + * @param {object} contentDocumentHandle Document which owns the container + */ + listenTo: function(registrationName, contentDocumentHandle) { + var mountAt = contentDocumentHandle; + var isListening = getListeningForDocument(mountAt); + var dependencies = EventPluginRegistry. + registrationNameDependencies[registrationName]; + + var topLevelTypes = EventConstants.topLevelTypes; + for (var i = 0, l = dependencies.length; i < l; i++) { + var dependency = dependencies[i]; + if (!( + (isListening.hasOwnProperty(dependency) && isListening[dependency]) + )) { + if (dependency === topLevelTypes.topWheel) { + if (isEventSupported('wheel')) { + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topWheel, + 'wheel', + mountAt + ); + } else if (isEventSupported('mousewheel')) { + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topWheel, + 'mousewheel', + mountAt + ); + } else { + // Firefox needs to capture a different mouse scroll event. + // @see http://www.quirksmode.org/dom/events/tests/scroll.html + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topWheel, + 'DOMMouseScroll', + mountAt + ); + } + } else if (dependency === topLevelTypes.topScroll) { + + if (isEventSupported('scroll', true)) { + ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( + topLevelTypes.topScroll, + 'scroll', + mountAt + ); + } else { + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topScroll, + 'scroll', + ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE + ); + } + } else if (dependency === topLevelTypes.topFocus || + dependency === topLevelTypes.topBlur) { + + if (isEventSupported('focus', true)) { + ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( + topLevelTypes.topFocus, + 'focus', + mountAt + ); + ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( + topLevelTypes.topBlur, + 'blur', + mountAt + ); + } else if (isEventSupported('focusin')) { + // IE has `focusin` and `focusout` events which bubble. + // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topFocus, + 'focusin', + mountAt + ); + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topBlur, + 'focusout', + mountAt + ); + } + + // to make sure blur and focus event listeners are only attached once + isListening[topLevelTypes.topBlur] = true; + isListening[topLevelTypes.topFocus] = true; + } else if (topEventMapping.hasOwnProperty(dependency)) { + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + dependency, + topEventMapping[dependency], + mountAt + ); + } + + isListening[dependency] = true; + } + } + }, + + trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { + return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelType, + handlerBaseName, + handle + ); + }, + + trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { + return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( + topLevelType, + handlerBaseName, + handle + ); + }, + + /** + * Listens to window scroll and resize events. We cache scroll values so that + * application code can access them without triggering reflows. + * + * NOTE: Scroll events do not bubble. + * + * @see http://www.quirksmode.org/dom/events/scroll.html + */ + ensureScrollValueMonitoring: function() { + if (!isMonitoringScrollValue) { + var refresh = ViewportMetrics.refreshScrollValues; + ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); + isMonitoringScrollValue = true; + } + }, + + eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs, + + registrationNameModules: EventPluginHub.registrationNameModules, + + putListener: EventPluginHub.putListener, + + getListener: EventPluginHub.getListener, + + deleteListener: EventPluginHub.deleteListener, + + deleteAllListeners: EventPluginHub.deleteAllListeners + + }); + + module.exports = ReactBrowserEventEmitter; + + +/***/ }, +/* 69 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule EventPluginHub + */ + + 'use strict'; + + var EventPluginRegistry = __webpack_require__(70); + var EventPluginUtils = __webpack_require__(4); + + var accumulateInto = __webpack_require__(71); + var forEachAccumulated = __webpack_require__(72); + var invariant = __webpack_require__(7); + + /** + * Internal store for event listeners + */ + var listenerBank = {}; + + /** + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. + */ + var eventQueue = null; + + /** + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @private + */ + var executeDispatchesAndRelease = function(event) { + if (event) { + var executeDispatch = EventPluginUtils.executeDispatch; + // Plugins can provide custom behavior when dispatching events. + var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event); + if (PluginModule && PluginModule.executeDispatch) { + executeDispatch = PluginModule.executeDispatch; + } + EventPluginUtils.executeDispatchesInOrder(event, executeDispatch); + + if (!event.isPersistent()) { + event.constructor.release(event); + } + } + }; + + /** + * - `InstanceHandle`: [required] Module that performs logical traversals of DOM + * hierarchy given ids of the logical DOM elements involved. + */ + var InstanceHandle = null; + + function validateInstanceHandle() { + var valid = + InstanceHandle && + InstanceHandle.traverseTwoPhase && + InstanceHandle.traverseEnterLeave; + ( false ? invariant( + valid, + 'InstanceHandle not injected before use!' + ) : invariant(valid)); + } + + /** + * This is a unified interface for event plugins to be installed and configured. + * + * Event plugins can implement the following properties: + * + * `extractEvents` {function(string, DOMEventTarget, string, object): *} + * Required. When a top-level event is fired, this method is expected to + * extract synthetic events that will in turn be queued and dispatched. + * + * `eventTypes` {object} + * Optional, plugins that fire events must publish a mapping of registration + * names that are used to register listeners. Values of this mapping must + * be objects that contain `registrationName` or `phasedRegistrationNames`. + * + * `executeDispatch` {function(object, function, string)} + * Optional, allows plugins to override how an event gets dispatched. By + * default, the listener is simply invoked. + * + * Each plugin that is injected into `EventsPluginHub` is immediately operable. + * + * @public + */ + var EventPluginHub = { + + /** + * Methods for injecting dependencies. + */ + injection: { + + /** + * @param {object} InjectedMount + * @public + */ + injectMount: EventPluginUtils.injection.injectMount, + + /** + * @param {object} InjectedInstanceHandle + * @public + */ + injectInstanceHandle: function(InjectedInstanceHandle) { + InstanceHandle = InjectedInstanceHandle; + if (false) { + validateInstanceHandle(); + } + }, + + getInstanceHandle: function() { + if (false) { + validateInstanceHandle(); + } + return InstanceHandle; + }, + + /** + * @param {array} InjectedEventPluginOrder + * @public + */ + injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, + + /** + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + */ + injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName + + }, + + eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs, + + registrationNameModules: EventPluginRegistry.registrationNameModules, + + /** + * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent. + * + * @param {string} id ID of the DOM element. + * @param {string} registrationName Name of listener (e.g. `onClick`). + * @param {?function} listener The callback to store. + */ + putListener: function(id, registrationName, listener) { + ( false ? invariant( + !listener || typeof listener === 'function', + 'Expected %s listener to be a function, instead got type %s', + registrationName, typeof listener + ) : invariant(!listener || typeof listener === 'function')); + + var bankForRegistrationName = + listenerBank[registrationName] || (listenerBank[registrationName] = {}); + bankForRegistrationName[id] = listener; + }, + + /** + * @param {string} id ID of the DOM element. + * @param {string} registrationName Name of listener (e.g. `onClick`). + * @return {?function} The stored callback. + */ + getListener: function(id, registrationName) { + var bankForRegistrationName = listenerBank[registrationName]; + return bankForRegistrationName && bankForRegistrationName[id]; + }, + + /** + * Deletes a listener from the registration bank. + * + * @param {string} id ID of the DOM element. + * @param {string} registrationName Name of listener (e.g. `onClick`). + */ + deleteListener: function(id, registrationName) { + var bankForRegistrationName = listenerBank[registrationName]; + if (bankForRegistrationName) { + delete bankForRegistrationName[id]; + } + }, + + /** + * Deletes all listeners for the DOM element with the supplied ID. + * + * @param {string} id ID of the DOM element. + */ + deleteAllListeners: function(id) { + for (var registrationName in listenerBank) { + delete listenerBank[registrationName][id]; + } + }, + + /** + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. + * + * @param {string} topLevelType Record from `EventConstants`. + * @param {DOMEventTarget} topLevelTarget The listening component root node. + * @param {string} topLevelTargetID ID of `topLevelTarget`. + * @param {object} nativeEvent Native browser event. + * @return {*} An accumulation of synthetic events. + * @internal + */ + extractEvents: function( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent) { + var events; + var plugins = EventPluginRegistry.plugins; + for (var i = 0, l = plugins.length; i < l; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = plugins[i]; + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent + ); + if (extractedEvents) { + events = accumulateInto(events, extractedEvents); + } + } + } + return events; + }, + + /** + * Enqueues a synthetic event that should be dispatched when + * `processEventQueue` is invoked. + * + * @param {*} events An accumulation of synthetic events. + * @internal + */ + enqueueEvents: function(events) { + if (events) { + eventQueue = accumulateInto(eventQueue, events); + } + }, + + /** + * Dispatches all synthetic events on the event queue. + * + * @internal + */ + processEventQueue: function() { + // Set `eventQueue` to null before processing it so that we can tell if more + // events get enqueued while processing. + var processingEventQueue = eventQueue; + eventQueue = null; + forEachAccumulated(processingEventQueue, executeDispatchesAndRelease); + ( false ? invariant( + !eventQueue, + 'processEventQueue(): Additional events were enqueued while processing ' + + 'an event queue. Support for this has not yet been implemented.' + ) : invariant(!eventQueue)); + }, + + /** + * These are needed for tests only. Do not use! + */ + __purge: function() { + listenerBank = {}; + }, + + __getListenerBank: function() { + return listenerBank; + } + + }; + + module.exports = EventPluginHub; + + +/***/ }, +/* 70 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule EventPluginRegistry + * @typechecks static-only + */ + + 'use strict'; + + var invariant = __webpack_require__(7); + + /** + * Injectable ordering of event plugins. + */ + var EventPluginOrder = null; + + /** + * Injectable mapping from names to event plugin modules. + */ + var namesToPlugins = {}; + + /** + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private + */ + function recomputePluginOrdering() { + if (!EventPluginOrder) { + // Wait until an `EventPluginOrder` is injected. + return; + } + for (var pluginName in namesToPlugins) { + var PluginModule = namesToPlugins[pluginName]; + var pluginIndex = EventPluginOrder.indexOf(pluginName); + ( false ? invariant( + pluginIndex > -1, + 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + + 'the plugin ordering, `%s`.', + pluginName + ) : invariant(pluginIndex > -1)); + if (EventPluginRegistry.plugins[pluginIndex]) { + continue; + } + ( false ? invariant( + PluginModule.extractEvents, + 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + + 'method, but `%s` does not.', + pluginName + ) : invariant(PluginModule.extractEvents)); + EventPluginRegistry.plugins[pluginIndex] = PluginModule; + var publishedEvents = PluginModule.eventTypes; + for (var eventName in publishedEvents) { + ( false ? invariant( + publishEventForPlugin( + publishedEvents[eventName], + PluginModule, + eventName + ), + 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', + eventName, + pluginName + ) : invariant(publishEventForPlugin( + publishedEvents[eventName], + PluginModule, + eventName + ))); + } + } + } + + /** + * Publishes an event so that it can be dispatched by the supplied plugin. + * + * @param {object} dispatchConfig Dispatch configuration for the event. + * @param {object} PluginModule Plugin publishing the event. + * @return {boolean} True if the event was successfully published. + * @private + */ + function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { + ( false ? invariant( + !EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName), + 'EventPluginHub: More than one plugin attempted to publish the same ' + + 'event name, `%s`.', + eventName + ) : invariant(!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName))); + EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; + + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName( + phasedRegistrationName, + PluginModule, + eventName + ); + } + } + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName( + dispatchConfig.registrationName, + PluginModule, + eventName + ); + return true; + } + return false; + } + + /** + * Publishes a registration name that is used to identify dispatched events and + * can be used with `EventPluginHub.putListener` to register listeners. + * + * @param {string} registrationName Registration name to add. + * @param {object} PluginModule Plugin publishing the event. + * @private + */ + function publishRegistrationName(registrationName, PluginModule, eventName) { + ( false ? invariant( + !EventPluginRegistry.registrationNameModules[registrationName], + 'EventPluginHub: More than one plugin attempted to publish the same ' + + 'registration name, `%s`.', + registrationName + ) : invariant(!EventPluginRegistry.registrationNameModules[registrationName])); + EventPluginRegistry.registrationNameModules[registrationName] = PluginModule; + EventPluginRegistry.registrationNameDependencies[registrationName] = + PluginModule.eventTypes[eventName].dependencies; + } + + /** + * Registers plugins so that they can extract and dispatch events. + * + * @see {EventPluginHub} + */ + var EventPluginRegistry = { + + /** + * Ordered list of injected plugins. + */ + plugins: [], + + /** + * Mapping from event name to dispatch config + */ + eventNameDispatchConfigs: {}, + + /** + * Mapping from registration name to plugin module + */ + registrationNameModules: {}, + + /** + * Mapping from registration name to event name + */ + registrationNameDependencies: {}, + + /** + * Injects an ordering of plugins (by plugin name). This allows the ordering + * to be decoupled from injection of the actual plugins so that ordering is + * always deterministic regardless of packaging, on-the-fly injection, etc. + * + * @param {array} InjectedEventPluginOrder + * @internal + * @see {EventPluginHub.injection.injectEventPluginOrder} + */ + injectEventPluginOrder: function(InjectedEventPluginOrder) { + ( false ? invariant( + !EventPluginOrder, + 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + + 'once. You are likely trying to load more than one copy of React.' + ) : invariant(!EventPluginOrder)); + // Clone the ordering so it cannot be dynamically mutated. + EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder); + recomputePluginOrdering(); + }, + + /** + * Injects plugins to be used by `EventPluginHub`. The plugin names must be + * in the ordering injected by `injectEventPluginOrder`. + * + * Plugins can be injected as part of page initialization or on-the-fly. + * + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + * @internal + * @see {EventPluginHub.injection.injectEventPluginsByName} + */ + injectEventPluginsByName: function(injectedNamesToPlugins) { + var isOrderingDirty = false; + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; + } + var PluginModule = injectedNamesToPlugins[pluginName]; + if (!namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== PluginModule) { + ( false ? invariant( + !namesToPlugins[pluginName], + 'EventPluginRegistry: Cannot inject two different event plugins ' + + 'using the same name, `%s`.', + pluginName + ) : invariant(!namesToPlugins[pluginName])); + namesToPlugins[pluginName] = PluginModule; + isOrderingDirty = true; + } + } + if (isOrderingDirty) { + recomputePluginOrdering(); + } + }, + + /** + * Looks up the plugin for the supplied event. + * + * @param {object} event A synthetic event. + * @return {?object} The plugin that created the supplied event. + * @internal + */ + getPluginModuleForEvent: function(event) { + var dispatchConfig = event.dispatchConfig; + if (dispatchConfig.registrationName) { + return EventPluginRegistry.registrationNameModules[ + dispatchConfig.registrationName + ] || null; + } + for (var phase in dispatchConfig.phasedRegistrationNames) { + if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) { + continue; + } + var PluginModule = EventPluginRegistry.registrationNameModules[ + dispatchConfig.phasedRegistrationNames[phase] + ]; + if (PluginModule) { + return PluginModule; + } + } + return null; + }, + + /** + * Exposed for unit testing. + * @private + */ + _resetEventPlugins: function() { + EventPluginOrder = null; + for (var pluginName in namesToPlugins) { + if (namesToPlugins.hasOwnProperty(pluginName)) { + delete namesToPlugins[pluginName]; + } + } + EventPluginRegistry.plugins.length = 0; + + var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs; + for (var eventName in eventNameDispatchConfigs) { + if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { + delete eventNameDispatchConfigs[eventName]; + } + } + + var registrationNameModules = EventPluginRegistry.registrationNameModules; + for (var registrationName in registrationNameModules) { + if (registrationNameModules.hasOwnProperty(registrationName)) { + delete registrationNameModules[registrationName]; + } + } + } + + }; + + module.exports = EventPluginRegistry; + + +/***/ }, +/* 71 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule accumulateInto + */ + + 'use strict'; + + var invariant = __webpack_require__(7); + + /** + * + * Accumulates items that must not be null or undefined into the first one. This + * is used to conserve memory by avoiding array allocations, and thus sacrifices + * API cleanness. Since `current` can be null before being passed in and not + * null after this function, make sure to assign it back to `current`: + * + * `a = accumulateInto(a, b);` + * + * This API should be sparingly used. Try `accumulate` for something cleaner. + * + * @return {*|array<*>} An accumulation of items. + */ + + function accumulateInto(current, next) { + ( false ? invariant( + next != null, + 'accumulateInto(...): Accumulated items must not be null or undefined.' + ) : invariant(next != null)); + if (current == null) { + return next; + } + + // Both are not empty. Warning: Never call x.concat(y) when you are not + // certain that x is an Array (x could be a string with concat method). + var currentIsArray = Array.isArray(current); + var nextIsArray = Array.isArray(next); + + if (currentIsArray && nextIsArray) { + current.push.apply(current, next); + return current; + } + + if (currentIsArray) { + current.push(next); + return current; + } + + if (nextIsArray) { + // A bit too dangerous to mutate `next`. + return [current].concat(next); + } + + return [current, next]; + } + + module.exports = accumulateInto; + + +/***/ }, +/* 72 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule forEachAccumulated + */ + + 'use strict'; + + /** + * @param {array} an "accumulation" of items which is either an Array or + * a single item. Useful when paired with the `accumulate` module. This is a + * simple utility that allows us to reason about a collection of items, but + * handling the case when there is exactly one item (and we do not need to + * allocate an array). + */ + var forEachAccumulated = function(arr, cb, scope) { + if (Array.isArray(arr)) { + arr.forEach(cb, scope); + } else if (arr) { + cb.call(scope, arr); + } + }; + + module.exports = forEachAccumulated; + + +/***/ }, +/* 73 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactEventEmitterMixin + */ + + 'use strict'; + + var EventPluginHub = __webpack_require__(69); + + function runEventQueueInBatch(events) { + EventPluginHub.enqueueEvents(events); + EventPluginHub.processEventQueue(); + } + + var ReactEventEmitterMixin = { + + /** + * Streams a fired top-level event to `EventPluginHub` where plugins have the + * opportunity to create `ReactEvent`s to be dispatched. + * + * @param {string} topLevelType Record from `EventConstants`. + * @param {object} topLevelTarget The listening component root node. + * @param {string} topLevelTargetID ID of `topLevelTarget`. + * @param {object} nativeEvent Native environment event. + */ + handleTopLevel: function( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent) { + var events = EventPluginHub.extractEvents( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent + ); + + runEventQueueInBatch(events); + } + }; + + module.exports = ReactEventEmitterMixin; + + +/***/ }, +/* 74 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ViewportMetrics + */ + + 'use strict'; + + var ViewportMetrics = { + + currentScrollLeft: 0, + + currentScrollTop: 0, + + refreshScrollValues: function(scrollPosition) { + ViewportMetrics.currentScrollLeft = scrollPosition.x; + ViewportMetrics.currentScrollTop = scrollPosition.y; + } + + }; + + module.exports = ViewportMetrics; + + +/***/ }, +/* 75 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule isEventSupported + */ + + 'use strict'; + + var ExecutionEnvironment = __webpack_require__(51); + + var useHasFeature; + if (ExecutionEnvironment.canUseDOM) { + useHasFeature = + document.implementation && + document.implementation.hasFeature && + // always returns true in newer browsers as per the standard. + // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature + document.implementation.hasFeature('', '') !== true; + } + + /** + * Checks if an event is supported in the current execution environment. + * + * NOTE: This will not work correctly for non-generic events such as `change`, + * `reset`, `load`, `error`, and `select`. + * + * Borrows from Modernizr. + * + * @param {string} eventNameSuffix Event name, e.g. "click". + * @param {?boolean} capture Check if the capture phase is supported. + * @return {boolean} True if the event is supported. + * @internal + * @license Modernizr 3.0.0pre (Custom Build) | MIT + */ + function isEventSupported(eventNameSuffix, capture) { + if (!ExecutionEnvironment.canUseDOM || + capture && !('addEventListener' in document)) { + return false; + } + + var eventName = 'on' + eventNameSuffix; + var isSupported = eventName in document; + + if (!isSupported) { + var element = document.createElement('div'); + element.setAttribute(eventName, 'return;'); + isSupported = typeof element[eventName] === 'function'; + } + + if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { + // This is the only way to test support for the `wheel` event in IE9+. + isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); + } + + return isSupported; + } + + module.exports = isEventSupported; + + +/***/ }, +/* 76 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactEmptyComponent + */ + + 'use strict'; + + var ReactElement = __webpack_require__(11); + var ReactInstanceMap = __webpack_require__(25); + + var invariant = __webpack_require__(7); + + var component; + // This registry keeps track of the React IDs of the components that rendered to + // `null` (in reality a placeholder such as `noscript`) + var nullComponentIDsRegistry = {}; + + var ReactEmptyComponentInjection = { + injectEmptyComponent: function(emptyComponent) { + component = ReactElement.createFactory(emptyComponent); + } + }; + + var ReactEmptyComponentType = function() {}; + ReactEmptyComponentType.prototype.componentDidMount = function() { + var internalInstance = ReactInstanceMap.get(this); + // TODO: Make sure we run these methods in the correct order, we shouldn't + // need this check. We're going to assume if we're here it means we ran + // componentWillUnmount already so there is no internal instance (it gets + // removed as part of the unmounting process). + if (!internalInstance) { + return; + } + registerNullComponentID(internalInstance._rootNodeID); + }; + ReactEmptyComponentType.prototype.componentWillUnmount = function() { + var internalInstance = ReactInstanceMap.get(this); + // TODO: Get rid of this check. See TODO in componentDidMount. + if (!internalInstance) { + return; + } + deregisterNullComponentID(internalInstance._rootNodeID); + }; + ReactEmptyComponentType.prototype.render = function() { + ( false ? invariant( + component, + 'Trying to return null from a render, but no null placeholder component ' + + 'was injected.' + ) : invariant(component)); + return component(); + }; + + var emptyElement = ReactElement.createElement(ReactEmptyComponentType); + + /** + * Mark the component as having rendered to null. + * @param {string} id Component's `_rootNodeID`. + */ + function registerNullComponentID(id) { + nullComponentIDsRegistry[id] = true; + } + + /** + * Unmark the component as having rendered to null: it renders to something now. + * @param {string} id Component's `_rootNodeID`. + */ + function deregisterNullComponentID(id) { + delete nullComponentIDsRegistry[id]; + } + + /** + * @param {string} id Component's `_rootNodeID`. + * @return {boolean} True if the component is rendered to null. + */ + function isNullComponentID(id) { + return !!nullComponentIDsRegistry[id]; + } + + var ReactEmptyComponent = { + emptyElement: emptyElement, + injection: ReactEmptyComponentInjection, + isNullComponentID: isNullComponentID + }; + + module.exports = ReactEmptyComponent; + + +/***/ }, +/* 77 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactMarkupChecksum + */ + + 'use strict'; + + var adler32 = __webpack_require__(78); + + var ReactMarkupChecksum = { + CHECKSUM_ATTR_NAME: 'data-react-checksum', + + /** + * @param {string} markup Markup string + * @return {string} Markup string with checksum attribute attached + */ + addChecksumToMarkup: function(markup) { + var checksum = adler32(markup); + return markup.replace( + '>', + ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">' + ); + }, + + /** + * @param {string} markup to use + * @param {DOMElement} element root React element + * @returns {boolean} whether or not the markup is the same + */ + canReuseMarkup: function(markup, element) { + var existingChecksum = element.getAttribute( + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + ); + existingChecksum = existingChecksum && parseInt(existingChecksum, 10); + var markupChecksum = adler32(markup); + return markupChecksum === existingChecksum; + } + }; + + module.exports = ReactMarkupChecksum; + + +/***/ }, +/* 78 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule adler32 + */ + + /* jslint bitwise:true */ + + 'use strict'; + + var MOD = 65521; + + // This is a clean-room implementation of adler32 designed for detecting + // if markup is not what we expect it to be. It does not need to be + // cryptographically strong, only reasonably good at detecting if markup + // generated on the server is different than that on the client. + function adler32(data) { + var a = 1; + var b = 0; + for (var i = 0; i < data.length; i++) { + a = (a + data.charCodeAt(i)) % MOD; + b = (b + a) % MOD; + } + return a | (b << 16); + } + + module.exports = adler32; + + +/***/ }, +/* 79 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule containsNode + * @typechecks + */ + + var isTextNode = __webpack_require__(80); + + /*jslint bitwise:true */ + + /** + * Checks if a given DOM node contains or is another DOM node. + * + * @param {?DOMNode} outerNode Outer DOM node. + * @param {?DOMNode} innerNode Inner DOM node. + * @return {boolean} True if `outerNode` contains or is `innerNode`. + */ + function containsNode(outerNode, innerNode) { + if (!outerNode || !innerNode) { + return false; + } else if (outerNode === innerNode) { + return true; + } else if (isTextNode(outerNode)) { + return false; + } else if (isTextNode(innerNode)) { + return containsNode(outerNode, innerNode.parentNode); + } else if (outerNode.contains) { + return outerNode.contains(innerNode); + } else if (outerNode.compareDocumentPosition) { + return !!(outerNode.compareDocumentPosition(innerNode) & 16); + } else { + return false; + } + } + + module.exports = containsNode; + + +/***/ }, +/* 80 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule isTextNode + * @typechecks + */ + + var isNode = __webpack_require__(81); + + /** + * @param {*} object The object to check. + * @return {boolean} Whether or not the object is a DOM text node. + */ + function isTextNode(object) { + return isNode(object) && object.nodeType == 3; + } + + module.exports = isTextNode; + + +/***/ }, +/* 81 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule isNode + * @typechecks + */ + + /** + * @param {*} object The object to check. + * @return {boolean} Whether or not the object is a DOM node. + */ + function isNode(object) { + return !!(object && ( + ((typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && + typeof object.nodeType === 'number' && + typeof object.nodeName === 'string')) + )); + } + + module.exports = isNode; + + +/***/ }, +/* 82 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule getReactRootElementInContainer + */ + + 'use strict'; + + var DOC_NODE_TYPE = 9; + + /** + * @param {DOMElement|DOMDocument} container DOM element that may contain + * a React component + * @return {?*} DOM element that may have the reactRoot ID, or null. + */ + function getReactRootElementInContainer(container) { + if (!container) { + return null; + } + + if (container.nodeType === DOC_NODE_TYPE) { + return container.documentElement; + } else { + return container.firstChild; + } + } + + module.exports = getReactRootElementInContainer; + + +/***/ }, +/* 83 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule instantiateReactComponent + * @typechecks static-only + */ + + 'use strict'; + + var ReactCompositeComponent = __webpack_require__(84); + var ReactEmptyComponent = __webpack_require__(76); + var ReactNativeComponent = __webpack_require__(35); + + var assign = __webpack_require__(13); + var invariant = __webpack_require__(7); + var warning = __webpack_require__(15); + + // To avoid a cyclic dependency, we create the final class in this module + var ReactCompositeComponentWrapper = function() { }; + assign( + ReactCompositeComponentWrapper.prototype, + ReactCompositeComponent.Mixin, + { + _instantiateReactComponent: instantiateReactComponent + } + ); + + /** + * Check if the type reference is a known internal type. I.e. not a user + * provided composite type. + * + * @param {function} type + * @return {boolean} Returns true if this is a valid internal type. + */ + function isInternalComponentType(type) { + return ( + typeof type === 'function' && + typeof type.prototype !== 'undefined' && + typeof type.prototype.mountComponent === 'function' && + typeof type.prototype.receiveComponent === 'function' + ); + } + + /** + * Given a ReactNode, create an instance that will actually be mounted. + * + * @param {ReactNode} node + * @param {*} parentCompositeType The composite type that resolved this. + * @return {object} A new instance of the element's constructor. + * @protected + */ + function instantiateReactComponent(node, parentCompositeType) { + var instance; + + if (node === null || node === false) { + node = ReactEmptyComponent.emptyElement; + } + + if (typeof node === 'object') { + var element = node; + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + element && (typeof element.type === 'function' || + typeof element.type === 'string'), + 'Only functions or strings can be mounted as React components.' + ) : null); + } + + // Special case string values + if (parentCompositeType === element.type && + typeof element.type === 'string') { + // Avoid recursion if the wrapper renders itself. + instance = ReactNativeComponent.createInternalComponent(element); + // All native components are currently wrapped in a composite so we're + // safe to assume that this is what we should instantiate. + } else if (isInternalComponentType(element.type)) { + // This is temporarily available for custom components that are not string + // represenations. I.e. ART. Once those are updated to use the string + // representation, we can drop this code path. + instance = new element.type(element); + } else { + instance = new ReactCompositeComponentWrapper(); + } + } else if (typeof node === 'string' || typeof node === 'number') { + instance = ReactNativeComponent.createInstanceForText(node); + } else { + ( false ? invariant( + false, + 'Encountered invalid React node of type %s', + typeof node + ) : invariant(false)); + } + + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + typeof instance.construct === 'function' && + typeof instance.mountComponent === 'function' && + typeof instance.receiveComponent === 'function' && + typeof instance.unmountComponent === 'function', + 'Only React Components can be mounted.' + ) : null); + } + + // Sets up the instance. This can probably just move into the constructor now. + instance.construct(node); + + // These two fields are used by the DOM and ART diffing algorithms + // respectively. Instead of using expandos on components, we should be + // storing the state needed by the diffing algorithms elsewhere. + instance._mountIndex = 0; + instance._mountImage = null; + + if (false) { + instance._isOwnerNecessary = false; + instance._warnedAboutRefsInRender = false; + } + + // Internal instances should fully constructed at this point, so they should + // not get any new fields added to them at this point. + if (false) { + if (Object.preventExtensions) { + Object.preventExtensions(instance); + } + } + + return instance; + } + + module.exports = instantiateReactComponent; + + +/***/ }, +/* 84 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactCompositeComponent + */ + + 'use strict'; + + var ReactComponentEnvironment = __webpack_require__(85); + var ReactContext = __webpack_require__(12); + var ReactCurrentOwner = __webpack_require__(17); + var ReactElement = __webpack_require__(11); + var ReactElementValidator = __webpack_require__(32); + var ReactInstanceMap = __webpack_require__(25); + var ReactLifeCycle = __webpack_require__(24); + var ReactNativeComponent = __webpack_require__(35); + var ReactPerf = __webpack_require__(28); + var ReactPropTypeLocations = __webpack_require__(33); + var ReactPropTypeLocationNames = __webpack_require__(34); + var ReactReconciler = __webpack_require__(29); + var ReactUpdates = __webpack_require__(26); + + var assign = __webpack_require__(13); + var emptyObject = __webpack_require__(14); + var invariant = __webpack_require__(7); + var shouldUpdateReactComponent = __webpack_require__(86); + var warning = __webpack_require__(15); + + function getDeclarationErrorAddendum(component) { + var owner = component._currentElement._owner || null; + if (owner) { + var name = owner.getName(); + if (name) { + return ' Check the render method of `' + name + '`.'; + } + } + return ''; + } + + /** + * ------------------ The Life-Cycle of a Composite Component ------------------ + * + * - constructor: Initialization of state. The instance is now retained. + * - componentWillMount + * - render + * - [children's constructors] + * - [children's componentWillMount and render] + * - [children's componentDidMount] + * - componentDidMount + * + * Update Phases: + * - componentWillReceiveProps (only called if parent updated) + * - shouldComponentUpdate + * - componentWillUpdate + * - render + * - [children's constructors or receive props phases] + * - componentDidUpdate + * + * - componentWillUnmount + * - [children's componentWillUnmount] + * - [children destroyed] + * - (destroyed): The instance is now blank, released by React and ready for GC. + * + * ----------------------------------------------------------------------------- + */ + + /** + * An incrementing ID assigned to each component when it is mounted. This is + * used to enforce the order in which `ReactUpdates` updates dirty components. + * + * @private + */ + var nextMountID = 1; + + /** + * @lends {ReactCompositeComponent.prototype} + */ + var ReactCompositeComponentMixin = { + + /** + * Base constructor for all composite component. + * + * @param {ReactElement} element + * @final + * @internal + */ + construct: function(element) { + this._currentElement = element; + this._rootNodeID = null; + this._instance = null; + + // See ReactUpdateQueue + this._pendingElement = null; + this._pendingStateQueue = null; + this._pendingReplaceState = false; + this._pendingForceUpdate = false; + + this._renderedComponent = null; + + this._context = null; + this._mountOrder = 0; + this._isTopLevel = false; + + // See ReactUpdates and ReactUpdateQueue. + this._pendingCallbacks = null; + }, + + /** + * Initializes the component, renders markup, and registers event listeners. + * + * @param {string} rootID DOM ID of the root node. + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @return {?string} Rendered markup to be inserted into the DOM. + * @final + * @internal + */ + mountComponent: function(rootID, transaction, context) { + this._context = context; + this._mountOrder = nextMountID++; + this._rootNodeID = rootID; + + var publicProps = this._processProps(this._currentElement.props); + var publicContext = this._processContext(this._currentElement._context); + + var Component = ReactNativeComponent.getComponentClassForElement( + this._currentElement + ); + + // Initialize the public class + var inst = new Component(publicProps, publicContext); + + if (false) { + // This will throw later in _renderValidatedComponent, but add an early + // warning now to help debugging + ("production" !== process.env.NODE_ENV ? warning( + inst.render != null, + '%s(...): No `render` method found on the returned component ' + + 'instance: you may have forgotten to define `render` in your ' + + 'component or you may have accidentally tried to render an element ' + + 'whose type is a function that isn\'t a React component.', + Component.displayName || Component.name || 'Component' + ) : null); + } + + // These should be set up in the constructor, but as a convenience for + // simpler class abstractions, we set them up after the fact. + inst.props = publicProps; + inst.context = publicContext; + inst.refs = emptyObject; + + this._instance = inst; + + // Store a reference from the instance back to the internal representation + ReactInstanceMap.set(inst, this); + + if (false) { + this._warnIfContextsDiffer(this._currentElement._context, context); + } + + if (false) { + // Since plain JS classes are defined without any special initialization + // logic, we can not catch common errors early. Therefore, we have to + // catch them here, at initialization time, instead. + ("production" !== process.env.NODE_ENV ? warning( + !inst.getInitialState || + inst.getInitialState.isReactClassApproved, + 'getInitialState was defined on %s, a plain JavaScript class. ' + + 'This is only supported for classes created using React.createClass. ' + + 'Did you mean to define a state property instead?', + this.getName() || 'a component' + ) : null); + ("production" !== process.env.NODE_ENV ? warning( + !inst.getDefaultProps || + inst.getDefaultProps.isReactClassApproved, + 'getDefaultProps was defined on %s, a plain JavaScript class. ' + + 'This is only supported for classes created using React.createClass. ' + + 'Use a static property to define defaultProps instead.', + this.getName() || 'a component' + ) : null); + ("production" !== process.env.NODE_ENV ? warning( + !inst.propTypes, + 'propTypes was defined as an instance property on %s. Use a static ' + + 'property to define propTypes instead.', + this.getName() || 'a component' + ) : null); + ("production" !== process.env.NODE_ENV ? warning( + !inst.contextTypes, + 'contextTypes was defined as an instance property on %s. Use a ' + + 'static property to define contextTypes instead.', + this.getName() || 'a component' + ) : null); + ("production" !== process.env.NODE_ENV ? warning( + typeof inst.componentShouldUpdate !== 'function', + '%s has a method called ' + + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + + 'The name is phrased as a question because the function is ' + + 'expected to return a value.', + (this.getName() || 'A component') + ) : null); + } + + var initialState = inst.state; + if (initialState === undefined) { + inst.state = initialState = null; + } + ( false ? invariant( + typeof initialState === 'object' && !Array.isArray(initialState), + '%s.state: must be set to an object or null', + this.getName() || 'ReactCompositeComponent' + ) : invariant(typeof initialState === 'object' && !Array.isArray(initialState))); + + this._pendingStateQueue = null; + this._pendingReplaceState = false; + this._pendingForceUpdate = false; + + var childContext; + var renderedElement; + + var previouslyMounting = ReactLifeCycle.currentlyMountingInstance; + ReactLifeCycle.currentlyMountingInstance = this; + try { + if (inst.componentWillMount) { + inst.componentWillMount(); + // When mounting, calls to `setState` by `componentWillMount` will set + // `this._pendingStateQueue` without triggering a re-render. + if (this._pendingStateQueue) { + inst.state = this._processPendingState(inst.props, inst.context); + } + } + + childContext = this._getValidatedChildContext(context); + renderedElement = this._renderValidatedComponent(childContext); + } finally { + ReactLifeCycle.currentlyMountingInstance = previouslyMounting; + } + + this._renderedComponent = this._instantiateReactComponent( + renderedElement, + this._currentElement.type // The wrapping type + ); + + var markup = ReactReconciler.mountComponent( + this._renderedComponent, + rootID, + transaction, + this._mergeChildContext(context, childContext) + ); + if (inst.componentDidMount) { + transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); + } + + return markup; + }, + + /** + * Releases any resources allocated by `mountComponent`. + * + * @final + * @internal + */ + unmountComponent: function() { + var inst = this._instance; + + if (inst.componentWillUnmount) { + var previouslyUnmounting = ReactLifeCycle.currentlyUnmountingInstance; + ReactLifeCycle.currentlyUnmountingInstance = this; + try { + inst.componentWillUnmount(); + } finally { + ReactLifeCycle.currentlyUnmountingInstance = previouslyUnmounting; + } + } + + ReactReconciler.unmountComponent(this._renderedComponent); + this._renderedComponent = null; + + // Reset pending fields + this._pendingStateQueue = null; + this._pendingReplaceState = false; + this._pendingForceUpdate = false; + this._pendingCallbacks = null; + this._pendingElement = null; + + // These fields do not really need to be reset since this object is no + // longer accessible. + this._context = null; + this._rootNodeID = null; + + // Delete the reference from the instance to this internal representation + // which allow the internals to be properly cleaned up even if the user + // leaks a reference to the public instance. + ReactInstanceMap.remove(inst); + + // Some existing components rely on inst.props even after they've been + // destroyed (in event handlers). + // TODO: inst.props = null; + // TODO: inst.state = null; + // TODO: inst.context = null; + }, + + /** + * Schedule a partial update to the props. Only used for internal testing. + * + * @param {object} partialProps Subset of the next props. + * @param {?function} callback Called after props are updated. + * @final + * @internal + */ + _setPropsInternal: function(partialProps, callback) { + // This is a deoptimized path. We optimize for always having an element. + // This creates an extra internal element. + var element = this._pendingElement || this._currentElement; + this._pendingElement = ReactElement.cloneAndReplaceProps( + element, + assign({}, element.props, partialProps) + ); + ReactUpdates.enqueueUpdate(this, callback); + }, + + /** + * Filters the context object to only contain keys specified in + * `contextTypes` + * + * @param {object} context + * @return {?object} + * @private + */ + _maskContext: function(context) { + var maskedContext = null; + // This really should be getting the component class for the element, + // but we know that we're not going to need it for built-ins. + if (typeof this._currentElement.type === 'string') { + return emptyObject; + } + var contextTypes = this._currentElement.type.contextTypes; + if (!contextTypes) { + return emptyObject; + } + maskedContext = {}; + for (var contextName in contextTypes) { + maskedContext[contextName] = context[contextName]; + } + return maskedContext; + }, + + /** + * Filters the context object to only contain keys specified in + * `contextTypes`, and asserts that they are valid. + * + * @param {object} context + * @return {?object} + * @private + */ + _processContext: function(context) { + var maskedContext = this._maskContext(context); + if (false) { + var Component = ReactNativeComponent.getComponentClassForElement( + this._currentElement + ); + if (Component.contextTypes) { + this._checkPropTypes( + Component.contextTypes, + maskedContext, + ReactPropTypeLocations.context + ); + } + } + return maskedContext; + }, + + /** + * @param {object} currentContext + * @return {object} + * @private + */ + _getValidatedChildContext: function(currentContext) { + var inst = this._instance; + var childContext = inst.getChildContext && inst.getChildContext(); + if (childContext) { + ( false ? invariant( + typeof inst.constructor.childContextTypes === 'object', + '%s.getChildContext(): childContextTypes must be defined in order to ' + + 'use getChildContext().', + this.getName() || 'ReactCompositeComponent' + ) : invariant(typeof inst.constructor.childContextTypes === 'object')); + if (false) { + this._checkPropTypes( + inst.constructor.childContextTypes, + childContext, + ReactPropTypeLocations.childContext + ); + } + for (var name in childContext) { + ( false ? invariant( + name in inst.constructor.childContextTypes, + '%s.getChildContext(): key "%s" is not defined in childContextTypes.', + this.getName() || 'ReactCompositeComponent', + name + ) : invariant(name in inst.constructor.childContextTypes)); + } + return childContext; + } + return null; + }, + + _mergeChildContext: function(currentContext, childContext) { + if (childContext) { + return assign({}, currentContext, childContext); + } + return currentContext; + }, + + /** + * Processes props by setting default values for unspecified props and + * asserting that the props are valid. Does not mutate its argument; returns + * a new props object with defaults merged in. + * + * @param {object} newProps + * @return {object} + * @private + */ + _processProps: function(newProps) { + if (false) { + var Component = ReactNativeComponent.getComponentClassForElement( + this._currentElement + ); + if (Component.propTypes) { + this._checkPropTypes( + Component.propTypes, + newProps, + ReactPropTypeLocations.prop + ); + } + } + return newProps; + }, + + /** + * Assert that the props are valid + * + * @param {object} propTypes Map of prop name to a ReactPropType + * @param {object} props + * @param {string} location e.g. "prop", "context", "child context" + * @private + */ + _checkPropTypes: function(propTypes, props, location) { + // TODO: Stop validating prop types here and only use the element + // validation. + var componentName = this.getName(); + for (var propName in propTypes) { + if (propTypes.hasOwnProperty(propName)) { + var error; + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + ( false ? invariant( + typeof propTypes[propName] === 'function', + '%s: %s type `%s` is invalid; it must be a function, usually ' + + 'from React.PropTypes.', + componentName || 'React class', + ReactPropTypeLocationNames[location], + propName + ) : invariant(typeof propTypes[propName] === 'function')); + error = propTypes[propName](props, propName, componentName, location); + } catch (ex) { + error = ex; + } + if (error instanceof Error) { + // We may want to extend this logic for similar errors in + // React.render calls, so I'm abstracting it away into + // a function to minimize refactoring in the future + var addendum = getDeclarationErrorAddendum(this); + + if (location === ReactPropTypeLocations.prop) { + // Preface gives us something to blacklist in warning module + ( false ? warning( + false, + 'Failed Composite propType: %s%s', + error.message, + addendum + ) : null); + } else { + ( false ? warning( + false, + 'Failed Context Types: %s%s', + error.message, + addendum + ) : null); + } + } + } + } + }, + + receiveComponent: function(nextElement, transaction, nextContext) { + var prevElement = this._currentElement; + var prevContext = this._context; + + this._pendingElement = null; + + this.updateComponent( + transaction, + prevElement, + nextElement, + prevContext, + nextContext + ); + }, + + /** + * If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate` + * is set, update the component. + * + * @param {ReactReconcileTransaction} transaction + * @internal + */ + performUpdateIfNecessary: function(transaction) { + if (this._pendingElement != null) { + ReactReconciler.receiveComponent( + this, + this._pendingElement || this._currentElement, + transaction, + this._context + ); + } + + if (this._pendingStateQueue !== null || this._pendingForceUpdate) { + if (false) { + ReactElementValidator.checkAndWarnForMutatedProps( + this._currentElement + ); + } + + this.updateComponent( + transaction, + this._currentElement, + this._currentElement, + this._context, + this._context + ); + } + }, + + /** + * Compare two contexts, warning if they are different + * TODO: Remove this check when owner-context is removed + */ + _warnIfContextsDiffer: function(ownerBasedContext, parentBasedContext) { + ownerBasedContext = this._maskContext(ownerBasedContext); + parentBasedContext = this._maskContext(parentBasedContext); + var parentKeys = Object.keys(parentBasedContext).sort(); + var displayName = this.getName() || 'ReactCompositeComponent'; + for (var i = 0; i < parentKeys.length; i++) { + var key = parentKeys[i]; + ( false ? warning( + ownerBasedContext[key] === parentBasedContext[key], + 'owner-based and parent-based contexts differ ' + + '(values: `%s` vs `%s`) for key (%s) while mounting %s ' + + '(see: http://fb.me/react-context-by-parent)', + ownerBasedContext[key], + parentBasedContext[key], + key, + displayName + ) : null); + } + }, + + /** + * Perform an update to a mounted component. The componentWillReceiveProps and + * shouldComponentUpdate methods are called, then (assuming the update isn't + * skipped) the remaining update lifecycle methods are called and the DOM + * representation is updated. + * + * By default, this implements React's rendering and reconciliation algorithm. + * Sophisticated clients may wish to override this. + * + * @param {ReactReconcileTransaction} transaction + * @param {ReactElement} prevParentElement + * @param {ReactElement} nextParentElement + * @internal + * @overridable + */ + updateComponent: function( + transaction, + prevParentElement, + nextParentElement, + prevUnmaskedContext, + nextUnmaskedContext + ) { + var inst = this._instance; + + var nextContext = inst.context; + var nextProps = inst.props; + + // Distinguish between a props update versus a simple state update + if (prevParentElement !== nextParentElement) { + nextContext = this._processContext(nextParentElement._context); + nextProps = this._processProps(nextParentElement.props); + + if (false) { + if (nextUnmaskedContext != null) { + this._warnIfContextsDiffer( + nextParentElement._context, + nextUnmaskedContext + ); + } + } + + // An update here will schedule an update but immediately set + // _pendingStateQueue which will ensure that any state updates gets + // immediately reconciled instead of waiting for the next batch. + + if (inst.componentWillReceiveProps) { + inst.componentWillReceiveProps(nextProps, nextContext); + } + } + + var nextState = this._processPendingState(nextProps, nextContext); + + var shouldUpdate = + this._pendingForceUpdate || + !inst.shouldComponentUpdate || + inst.shouldComponentUpdate(nextProps, nextState, nextContext); + + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + typeof shouldUpdate !== 'undefined', + '%s.shouldComponentUpdate(): Returned undefined instead of a ' + + 'boolean value. Make sure to return true or false.', + this.getName() || 'ReactCompositeComponent' + ) : null); + } + + if (shouldUpdate) { + this._pendingForceUpdate = false; + // Will set `this.props`, `this.state` and `this.context`. + this._performComponentUpdate( + nextParentElement, + nextProps, + nextState, + nextContext, + transaction, + nextUnmaskedContext + ); + } else { + // If it's determined that a component should not update, we still want + // to set props and state but we shortcut the rest of the update. + this._currentElement = nextParentElement; + this._context = nextUnmaskedContext; + inst.props = nextProps; + inst.state = nextState; + inst.context = nextContext; + } + }, + + _processPendingState: function(props, context) { + var inst = this._instance; + var queue = this._pendingStateQueue; + var replace = this._pendingReplaceState; + this._pendingReplaceState = false; + this._pendingStateQueue = null; + + if (!queue) { + return inst.state; + } + + if (replace && queue.length === 1) { + return queue[0]; + } + + var nextState = assign({}, replace ? queue[0] : inst.state); + for (var i = replace ? 1 : 0; i < queue.length; i++) { + var partial = queue[i]; + assign( + nextState, + typeof partial === 'function' ? + partial.call(inst, nextState, props, context) : + partial + ); + } + + return nextState; + }, + + /** + * Merges new props and state, notifies delegate methods of update and + * performs update. + * + * @param {ReactElement} nextElement Next element + * @param {object} nextProps Next public object to set as properties. + * @param {?object} nextState Next object to set as state. + * @param {?object} nextContext Next public object to set as context. + * @param {ReactReconcileTransaction} transaction + * @param {?object} unmaskedContext + * @private + */ + _performComponentUpdate: function( + nextElement, + nextProps, + nextState, + nextContext, + transaction, + unmaskedContext + ) { + var inst = this._instance; + + var prevProps = inst.props; + var prevState = inst.state; + var prevContext = inst.context; + + if (inst.componentWillUpdate) { + inst.componentWillUpdate(nextProps, nextState, nextContext); + } + + this._currentElement = nextElement; + this._context = unmaskedContext; + inst.props = nextProps; + inst.state = nextState; + inst.context = nextContext; + + this._updateRenderedComponent(transaction, unmaskedContext); + + if (inst.componentDidUpdate) { + transaction.getReactMountReady().enqueue( + inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), + inst + ); + } + }, + + /** + * Call the component's `render` method and update the DOM accordingly. + * + * @param {ReactReconcileTransaction} transaction + * @internal + */ + _updateRenderedComponent: function(transaction, context) { + var prevComponentInstance = this._renderedComponent; + var prevRenderedElement = prevComponentInstance._currentElement; + var childContext = this._getValidatedChildContext(); + var nextRenderedElement = this._renderValidatedComponent(childContext); + if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { + ReactReconciler.receiveComponent( + prevComponentInstance, + nextRenderedElement, + transaction, + this._mergeChildContext(context, childContext) + ); + } else { + // These two IDs are actually the same! But nothing should rely on that. + var thisID = this._rootNodeID; + var prevComponentID = prevComponentInstance._rootNodeID; + ReactReconciler.unmountComponent(prevComponentInstance); + + this._renderedComponent = this._instantiateReactComponent( + nextRenderedElement, + this._currentElement.type + ); + var nextMarkup = ReactReconciler.mountComponent( + this._renderedComponent, + thisID, + transaction, + this._mergeChildContext(context, childContext) + ); + this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup); + } + }, + + /** + * @protected + */ + _replaceNodeWithMarkupByID: function(prevComponentID, nextMarkup) { + ReactComponentEnvironment.replaceNodeWithMarkupByID( + prevComponentID, + nextMarkup + ); + }, + + /** + * @protected + */ + _renderValidatedComponentWithoutOwnerOrContext: function() { + var inst = this._instance; + var renderedComponent = inst.render(); + if (false) { + // We allow auto-mocks to proceed as if they're returning null. + if (typeof renderedComponent === 'undefined' && + inst.render._isMockFunction) { + // This is probably bad practice. Consider warning here and + // deprecating this convenience. + renderedComponent = null; + } + } + + return renderedComponent; + }, + + /** + * @private + */ + _renderValidatedComponent: function(childContext) { + var renderedComponent; + var previousContext = ReactContext.current; + ReactContext.current = this._mergeChildContext( + this._currentElement._context, + childContext + ); + ReactCurrentOwner.current = this; + try { + renderedComponent = + this._renderValidatedComponentWithoutOwnerOrContext(); + } finally { + ReactContext.current = previousContext; + ReactCurrentOwner.current = null; + } + ( false ? invariant( + // TODO: An `isValidNode` function would probably be more appropriate + renderedComponent === null || renderedComponent === false || + ReactElement.isValidElement(renderedComponent), + '%s.render(): A valid ReactComponent must be returned. You may have ' + + 'returned undefined, an array or some other invalid object.', + this.getName() || 'ReactCompositeComponent' + ) : invariant(// TODO: An `isValidNode` function would probably be more appropriate + renderedComponent === null || renderedComponent === false || + ReactElement.isValidElement(renderedComponent))); + return renderedComponent; + }, + + /** + * Lazily allocates the refs object and stores `component` as `ref`. + * + * @param {string} ref Reference name. + * @param {component} component Component to store as `ref`. + * @final + * @private + */ + attachRef: function(ref, component) { + var inst = this.getPublicInstance(); + var refs = inst.refs === emptyObject ? (inst.refs = {}) : inst.refs; + refs[ref] = component.getPublicInstance(); + }, + + /** + * Detaches a reference name. + * + * @param {string} ref Name to dereference. + * @final + * @private + */ + detachRef: function(ref) { + var refs = this.getPublicInstance().refs; + delete refs[ref]; + }, + + /** + * Get a text description of the component that can be used to identify it + * in error messages. + * @return {string} The name or null. + * @internal + */ + getName: function() { + var type = this._currentElement.type; + var constructor = this._instance && this._instance.constructor; + return ( + type.displayName || (constructor && constructor.displayName) || + type.name || (constructor && constructor.name) || + null + ); + }, + + /** + * Get the publicly accessible representation of this component - i.e. what + * is exposed by refs and returned by React.render. Can be null for stateless + * components. + * + * @return {ReactComponent} the public component instance. + * @internal + */ + getPublicInstance: function() { + return this._instance; + }, + + // Stub + _instantiateReactComponent: null + + }; + + ReactPerf.measureMethods( + ReactCompositeComponentMixin, + 'ReactCompositeComponent', + { + mountComponent: 'mountComponent', + updateComponent: 'updateComponent', + _renderValidatedComponent: '_renderValidatedComponent' + } + ); + + var ReactCompositeComponent = { + + Mixin: ReactCompositeComponentMixin + + }; + + module.exports = ReactCompositeComponent; + + +/***/ }, +/* 85 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2014-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactComponentEnvironment + */ + + 'use strict'; + + var invariant = __webpack_require__(7); + + var injected = false; + + var ReactComponentEnvironment = { + + /** + * Optionally injectable environment dependent cleanup hook. (server vs. + * browser etc). Example: A browser system caches DOM nodes based on component + * ID and must remove that cache entry when this instance is unmounted. + */ + unmountIDFromEnvironment: null, + + /** + * Optionally injectable hook for swapping out mount images in the middle of + * the tree. + */ + replaceNodeWithMarkupByID: null, + + /** + * Optionally injectable hook for processing a queue of child updates. Will + * later move into MultiChildComponents. + */ + processChildrenUpdates: null, + + injection: { + injectEnvironment: function(environment) { + ( false ? invariant( + !injected, + 'ReactCompositeComponent: injectEnvironment() can only be called once.' + ) : invariant(!injected)); + ReactComponentEnvironment.unmountIDFromEnvironment = + environment.unmountIDFromEnvironment; + ReactComponentEnvironment.replaceNodeWithMarkupByID = + environment.replaceNodeWithMarkupByID; + ReactComponentEnvironment.processChildrenUpdates = + environment.processChildrenUpdates; + injected = true; + } + } + + }; + + module.exports = ReactComponentEnvironment; + + +/***/ }, +/* 86 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule shouldUpdateReactComponent + * @typechecks static-only + */ + + 'use strict'; + + var warning = __webpack_require__(15); + + /** + * Given a `prevElement` and `nextElement`, determines if the existing + * instance should be updated as opposed to being destroyed or replaced by a new + * instance. Both arguments are elements. This ensures that this logic can + * operate on stateless trees without any backing instance. + * + * @param {?object} prevElement + * @param {?object} nextElement + * @return {boolean} True if the existing instance should be updated. + * @protected + */ + function shouldUpdateReactComponent(prevElement, nextElement) { + if (prevElement != null && nextElement != null) { + var prevType = typeof prevElement; + var nextType = typeof nextElement; + if (prevType === 'string' || prevType === 'number') { + return (nextType === 'string' || nextType === 'number'); + } else { + if (nextType === 'object' && + prevElement.type === nextElement.type && + prevElement.key === nextElement.key) { + var ownersMatch = prevElement._owner === nextElement._owner; + var prevName = null; + var nextName = null; + var nextDisplayName = null; + if (false) { + if (!ownersMatch) { + if (prevElement._owner != null && + prevElement._owner.getPublicInstance() != null && + prevElement._owner.getPublicInstance().constructor != null) { + prevName = + prevElement._owner.getPublicInstance().constructor.displayName; + } + if (nextElement._owner != null && + nextElement._owner.getPublicInstance() != null && + nextElement._owner.getPublicInstance().constructor != null) { + nextName = + nextElement._owner.getPublicInstance().constructor.displayName; + } + if (nextElement.type != null && + nextElement.type.displayName != null) { + nextDisplayName = nextElement.type.displayName; + } + if (nextElement.type != null && typeof nextElement.type === 'string') { + nextDisplayName = nextElement.type; + } + if (typeof nextElement.type !== 'string' || + nextElement.type === 'input' || + nextElement.type === 'textarea') { + if ((prevElement._owner != null && + prevElement._owner._isOwnerNecessary === false) || + (nextElement._owner != null && + nextElement._owner._isOwnerNecessary === false)) { + if (prevElement._owner != null) { + prevElement._owner._isOwnerNecessary = true; + } + if (nextElement._owner != null) { + nextElement._owner._isOwnerNecessary = true; + } + ("production" !== process.env.NODE_ENV ? warning( + false, + '<%s /> is being rendered by both %s and %s using the same ' + + 'key (%s) in the same place. Currently, this means that ' + + 'they don\'t preserve state. This behavior should be very ' + + 'rare so we\'re considering deprecating it. Please contact ' + + 'the React team and explain your use case so that we can ' + + 'take that into consideration.', + nextDisplayName || 'Unknown Component', + prevName || '[Unknown]', + nextName || '[Unknown]', + prevElement.key + ) : null); + } + } + } + } + return ownersMatch; + } + } + } + return false; + } + + module.exports = shouldUpdateReactComponent; + + +/***/ }, +/* 87 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOMComponent + * @typechecks static-only + */ + + /* global hasOwnProperty:true */ + + 'use strict'; + + var CSSPropertyOperations = __webpack_require__(49); + var DOMProperty = __webpack_require__(44); + var DOMPropertyOperations = __webpack_require__(43); + var ReactBrowserEventEmitter = __webpack_require__(68); + var ReactComponentBrowserEnvironment = + __webpack_require__(47); + var ReactMount = __webpack_require__(67); + var ReactMultiChild = __webpack_require__(88); + var ReactPerf = __webpack_require__(28); + + var assign = __webpack_require__(13); + var escapeTextContentForBrowser = __webpack_require__(46); + var invariant = __webpack_require__(7); + var isEventSupported = __webpack_require__(75); + var keyOf = __webpack_require__(39); + var warning = __webpack_require__(15); + + var deleteListener = ReactBrowserEventEmitter.deleteListener; + var listenTo = ReactBrowserEventEmitter.listenTo; + var registrationNameModules = ReactBrowserEventEmitter.registrationNameModules; + + // For quickly matching children type, to test if can be treated as content. + var CONTENT_TYPES = {'string': true, 'number': true}; + + var STYLE = keyOf({style: null}); + + var ELEMENT_NODE_TYPE = 1; + + /** + * Optionally injectable operations for mutating the DOM + */ + var BackendIDOperations = null; + + /** + * @param {?object} props + */ + function assertValidProps(props) { + if (!props) { + return; + } + // Note the use of `==` which checks for null or undefined. + if (props.dangerouslySetInnerHTML != null) { + ( false ? invariant( + props.children == null, + 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.' + ) : invariant(props.children == null)); + ( false ? invariant( + typeof props.dangerouslySetInnerHTML === 'object' && + '__html' in props.dangerouslySetInnerHTML, + '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + + 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + + 'for more information.' + ) : invariant(typeof props.dangerouslySetInnerHTML === 'object' && + '__html' in props.dangerouslySetInnerHTML)); + } + if (false) { + ("production" !== process.env.NODE_ENV ? warning( + props.innerHTML == null, + 'Directly setting property `innerHTML` is not permitted. ' + + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.' + ) : null); + ("production" !== process.env.NODE_ENV ? warning( + !props.contentEditable || props.children == null, + 'A component is `contentEditable` and contains `children` managed by ' + + 'React. It is now your responsibility to guarantee that none of ' + + 'those nodes are unexpectedly modified or duplicated. This is ' + + 'probably not intentional.' + ) : null); + } + ( false ? invariant( + props.style == null || typeof props.style === 'object', + 'The `style` prop expects a mapping from style properties to values, ' + + 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' + + 'using JSX.' + ) : invariant(props.style == null || typeof props.style === 'object')); + } + + function putListener(id, registrationName, listener, transaction) { + if (false) { + // IE8 has no API for event capturing and the `onScroll` event doesn't + // bubble. + ("production" !== process.env.NODE_ENV ? warning( + registrationName !== 'onScroll' || isEventSupported('scroll', true), + 'This browser doesn\'t support the `onScroll` event' + ) : null); + } + var container = ReactMount.findReactContainerForID(id); + if (container) { + var doc = container.nodeType === ELEMENT_NODE_TYPE ? + container.ownerDocument : + container; + listenTo(registrationName, doc); + } + transaction.getPutListenerQueue().enqueuePutListener( + id, + registrationName, + listener + ); + } + + // For HTML, certain tags should omit their close tag. We keep a whitelist for + // those special cased tags. + + var omittedCloseTags = { + 'area': true, + 'base': true, + 'br': true, + 'col': true, + 'embed': true, + 'hr': true, + 'img': true, + 'input': true, + 'keygen': true, + 'link': true, + 'meta': true, + 'param': true, + 'source': true, + 'track': true, + 'wbr': true + // NOTE: menuitem's close tag should be omitted, but that causes problems. + }; + + // We accept any tag to be rendered but since this gets injected into abitrary + // HTML, we want to make sure that it's a safe tag. + // http://www.w3.org/TR/REC-xml/#NT-Name + + var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset + var validatedTagCache = {}; + var hasOwnProperty = {}.hasOwnProperty; + + function validateDangerousTag(tag) { + if (!hasOwnProperty.call(validatedTagCache, tag)) { + ( false ? invariant(VALID_TAG_REGEX.test(tag), 'Invalid tag: %s', tag) : invariant(VALID_TAG_REGEX.test(tag))); + validatedTagCache[tag] = true; + } + } + + /** + * Creates a new React class that is idempotent and capable of containing other + * React components. It accepts event listeners and DOM properties that are + * valid according to `DOMProperty`. + * + * - Event listeners: `onClick`, `onMouseDown`, etc. + * - DOM properties: `className`, `name`, `title`, etc. + * + * The `style` property functions differently from the DOM API. It accepts an + * object mapping of style properties to values. + * + * @constructor ReactDOMComponent + * @extends ReactMultiChild + */ + function ReactDOMComponent(tag) { + validateDangerousTag(tag); + this._tag = tag; + this._renderedChildren = null; + this._previousStyleCopy = null; + this._rootNodeID = null; + } + + ReactDOMComponent.displayName = 'ReactDOMComponent'; + + ReactDOMComponent.Mixin = { + + construct: function(element) { + this._currentElement = element; + }, + + /** + * Generates root tag markup then recurses. This method has side effects and + * is not idempotent. + * + * @internal + * @param {string} rootID The root DOM ID for this node. + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @return {string} The computed markup. + */ + mountComponent: function(rootID, transaction, context) { + this._rootNodeID = rootID; + assertValidProps(this._currentElement.props); + var closeTag = omittedCloseTags[this._tag] ? '' : ''; + return ( + this._createOpenTagMarkupAndPutListeners(transaction) + + this._createContentMarkup(transaction, context) + + closeTag + ); + }, + + /** + * Creates markup for the open tag and all attributes. + * + * This method has side effects because events get registered. + * + * Iterating over object properties is faster than iterating over arrays. + * @see http://jsperf.com/obj-vs-arr-iteration + * + * @private + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @return {string} Markup of opening tag. + */ + _createOpenTagMarkupAndPutListeners: function(transaction) { + var props = this._currentElement.props; + var ret = '<' + this._tag; + + for (var propKey in props) { + if (!props.hasOwnProperty(propKey)) { + continue; + } + var propValue = props[propKey]; + if (propValue == null) { + continue; + } + if (registrationNameModules.hasOwnProperty(propKey)) { + putListener(this._rootNodeID, propKey, propValue, transaction); + } else { + if (propKey === STYLE) { + if (propValue) { + propValue = this._previousStyleCopy = assign({}, props.style); + } + propValue = CSSPropertyOperations.createMarkupForStyles(propValue); + } + var markup = + DOMPropertyOperations.createMarkupForProperty(propKey, propValue); + if (markup) { + ret += ' ' + markup; + } + } + } + + // For static pages, no need to put React ID and checksum. Saves lots of + // bytes. + if (transaction.renderToStaticMarkup) { + return ret + '>'; + } + + var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID); + return ret + ' ' + markupForID + '>'; + }, + + /** + * Creates markup for the content between the tags. + * + * @private + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @param {object} context + * @return {string} Content markup. + */ + _createContentMarkup: function(transaction, context) { + var prefix = ''; + if (this._tag === 'listing' || + this._tag === 'pre' || + this._tag === 'textarea') { + // Add an initial newline because browsers ignore the first newline in + // a

,
, or