From 001bda28d9e8e7bfda68eb03cf7e2cf2a367aedd Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Mon, 28 Oct 2013 14:51:52 -0400 Subject: [PATCH 01/47] Generate the browser test list at built time --- .gitignore | 1 + grunt/tasks/populist.js | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fce7d1d993be4..635740490da14 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ docs/js/examples docs/downloads examples/shared/*.js +test/the files to test.generated.js \ No newline at end of file diff --git a/grunt/tasks/populist.js b/grunt/tasks/populist.js index b9b848bf884e4..cca0498c14a3c 100644 --- a/grunt/tasks/populist.js +++ b/grunt/tasks/populist.js @@ -1,11 +1,19 @@ 'use strict'; var grunt = require('grunt'); +var fs = require('fs') module.exports = function() { var config = this.data; var done = this.async(); + var theFilesToTestScript = fs.createWriteStream(__dirname + '/../../test/the files to test.generated.js'); + theFilesToTestScript.write('// Generated by '); + theFilesToTestScript.write(JSON.stringify(__filename.split(/(?=grunt)/)[1])); + theFilesToTestScript.write(' at '); + theFilesToTestScript.write(JSON.stringify(new Date())); + theFilesToTestScript.write('\n\n'); + // create the bundle we'll work with var args = config.args; @@ -15,7 +23,9 @@ module.exports = function() { nonull: true, // Keep IDs that don't expand to anything. cwd: config.rootDirectory }, requires).forEach(function(name) { - args.push(name.replace(/\.js$/i, "")); + name = name.replace(/\.js$/i, ""); + args.push(name); + theFilesToTestScript.write('harness.enableTest(' + JSON.stringify(name) + ');\n'); }); require("populist").buildP({ @@ -23,6 +33,7 @@ module.exports = function() { args: args }).then(function(output) { grunt.file.write(config.outfile, output); + theFilesToTestScript.end(); done(); }); }; From c4ba8f8997bd228f8fef90c5a5dc47b966fce929 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Mon, 28 Oct 2013 14:54:37 -0400 Subject: [PATCH 02/47] Browser test runner --- test/browser-runner.js | 27 +++++++++++++++++++++++++++ test/browser.html | 3 +++ test/jasmine-execute.js | 11 +++++++++++ 3 files changed, 41 insertions(+) create mode 100644 test/browser-runner.js create mode 100644 test/browser.html create mode 100644 test/jasmine-execute.js diff --git a/test/browser-runner.js b/test/browser-runner.js new file mode 100644 index 0000000000000..c311ca8f10941 --- /dev/null +++ b/test/browser-runner.js @@ -0,0 +1,27 @@ +;(function(){ + + var __filename = (function(){ + var scripts = document.getElementsByTagName('script'); + var a = document.createElement('a'); + a.href = scripts[scripts.length-1].src; + return a.pathname; + }()); + + var __dirname = __filename.split('/').reverse().slice(1).reverse().join('/'); + + document.head.appendChild(function(){ + var link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = __dirname + '/../vendor/jasmine/jasmine.css'; + return link; + }()); + + var cacheBust = '?_=' + Date.now().toString(36); + + document.write(' diff --git a/test/jasmine-execute.js b/test/jasmine-execute.js new file mode 100644 index 0000000000000..7ff9e153a9c7d --- /dev/null +++ b/test/jasmine-execute.js @@ -0,0 +1,11 @@ +;(function(env){ + // Clean up any nodes the previous test might have added. + env.afterEach(function() { + harness.removeNextSiblings(document.body); + harness.removeNextSiblings(document.getElementById("HTMLReporter")); + }); + + window.onload = function(){ + env.execute(); + } +})(jasmine.getEnv()); From 8205c681eb214dd8155d4ab05c4189d55a6a9737 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Mon, 28 Oct 2013 16:34:23 -0400 Subject: [PATCH 03/47] serve worker.js from its actual relative path --- src/environment/__tests__/ReactWebWorker-test.js | 2 +- src/test/worker.js | 2 +- test/browser-runner.js | 2 ++ test/phantom-harness.js | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/environment/__tests__/ReactWebWorker-test.js b/src/environment/__tests__/ReactWebWorker-test.js index 87f093f8c0d5e..2b89b715c026e 100644 --- a/src/environment/__tests__/ReactWebWorker-test.js +++ b/src/environment/__tests__/ReactWebWorker-test.js @@ -26,7 +26,7 @@ describe('ReactWebWorker', function() { var done = false; var error; - var worker = new Worker('/worker.js'); + var worker = new Worker(window.ReactWebWorker_URL || '/src/test/worker.js?_=' + Date.now().toString(36)); worker.addEventListener('message', function(e) { var data = JSON.parse(e.data); if (data.type == 'error') { diff --git a/src/test/worker.js b/src/test/worker.js index 2918cb6e4deda..7ba7e1ffc734c 100644 --- a/src/test/worker.js +++ b/src/test/worker.js @@ -6,7 +6,7 @@ var global = {}; importScripts("phantomjs-shims.js"); try { - importScripts("react.js"); + importScripts("../../build/react.js"); } catch (e) { postMessage(JSON.stringify({ type: 'error', diff --git a/test/browser-runner.js b/test/browser-runner.js index c311ca8f10941..8fed423f6c333 100644 --- a/test/browser-runner.js +++ b/test/browser-runner.js @@ -18,6 +18,8 @@ var cacheBust = '?_=' + Date.now().toString(36); + window.ReactWebWorker_URL = __dirname + '/../src/test/worker.js' + cacheBust; + document.write('
1) {\n props.testProp = value;\n }\n return declaration.bind(null, props, 'testProp', 'testComponent');\n}\n\ndescribe('Primitive Types', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n it(\"should throw for invalid strings\", function() {\n expect(typeCheck(Props.string, [])).toThrow(\n 'Invariant Violation: Invalid prop `testProp` of type `array` ' +\n 'supplied to `testComponent`, expected `string`.'\n );\n expect(typeCheck(Props.string, false)).toThrow(\n 'Invariant Violation: Invalid prop `testProp` of type `boolean` ' +\n 'supplied to `testComponent`, expected `string`.'\n );\n expect(typeCheck(Props.string, 1)).toThrow(\n 'Invariant Violation: Invalid prop `testProp` of type `number` ' +\n 'supplied to `testComponent`, expected `string`.'\n );\n expect(typeCheck(Props.string, {})).toThrow(\n 'Invariant Violation: Invalid prop `testProp` of type `object` ' +\n 'supplied to `testComponent`, expected `string`.'\n );\n });\n\n it(\"should not throw for valid values\", function() {\n expect(typeCheck(Props.array, [])).not.toThrow();\n expect(typeCheck(Props.bool, false)).not.toThrow();\n expect(typeCheck(Props.func, function() {})).not.toThrow();\n expect(typeCheck(Props.number, 0)).not.toThrow();\n expect(typeCheck(Props.object, {})).not.toThrow();\n expect(typeCheck(Props.string, '')).not.toThrow();\n });\n\n it(\"should be implicitly optional and not throw without values\", function() {\n expect(typeCheck(Props.string, null)).not.toThrow();\n expect(typeCheck(Props.string, undefined)).not.toThrow();\n });\n\n it(\"should throw for missing required values\", function() {\n expect(typeCheck(Props.string.isRequired, null)).toThrow(\n 'Invariant Violation: Required prop `testProp` was not specified in ' +\n '`testComponent`.'\n );\n expect(typeCheck(Props.string.isRequired, undefined)).toThrow(\n 'Invariant Violation: Required prop `testProp` was not specified in ' +\n '`testComponent`.'\n );\n });\n});\n\ndescribe('Enum Types', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n it(\"should throw for invalid strings\", function() {\n expect(typeCheck(Props.oneOf(['red', 'blue']), true)).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected one of [\"blue\",\"red\"].'\n );\n expect(typeCheck(Props.oneOf(['red', 'blue']), [])).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected one of [\"blue\",\"red\"].'\n );\n expect(typeCheck(Props.oneOf(['red', 'blue']), '')).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected one of [\"blue\",\"red\"].'\n );\n });\n\n it(\"should not throw for valid values\", function() {\n expect(typeCheck(Props.oneOf(['red', 'blue']), 'red')).not.toThrow();\n expect(typeCheck(Props.oneOf(['red', 'blue']), 'blue')).not.toThrow();\n });\n\n it(\"should be implicitly optional and not throw without values\", function() {\n expect(typeCheck(Props.oneOf(['red', 'blue']), null)).not.toThrow();\n expect(typeCheck(Props.oneOf(['red', 'blue']), undefined)).not.toThrow();\n });\n});\n\ndescribe('Instance Types', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n it(\"should throw for invalid instances\", function() {\n function Person() {}\n\n expect(typeCheck(Props.instanceOf(Person), false)).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected instance of `Person`.'\n );\n expect(typeCheck(Props.instanceOf(Person), {})).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected instance of `Person`.'\n );\n expect(typeCheck(Props.instanceOf(Person), '')).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected instance of `Person`.'\n );\n });\n\n it(\"should not throw for valid values\", function() {\n function Person() {}\n function Engineer() {}\n Engineer.prototype = new Person();\n\n expect(typeCheck(Props.instanceOf(Person), new Person())).not.toThrow();\n expect(typeCheck(Props.instanceOf(Person), new Engineer())).not.toThrow();\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactPropTypes-test\", module);\n", +"core/__tests__/ReactRenderDocument-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar React;\nvar ReactMount;\n\nvar getTestDocument;\n\nvar testDocument;\n\ndescribe('rendering React components at document', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n\n React = require(\"../../React\");\n ReactMount = require(\"../../ReactMount\");\n getTestDocument = require(\"../../getTestDocument\");\n\n testDocument = getTestDocument();\n });\n\n it('should be able to switch root constructors via state', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n \" Hello world \"\n )\n )\n );\n }\n });\n\n var Component2 = React.createClass({displayName: 'Component2',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n \" Goodbye world \"\n )\n )\n );\n }\n });\n\n var Root = React.createClass({displayName: 'Root',\n getInitialState: function() {\n return {toggled: false};\n },\n toggle: function() {\n this.setState({toggled: !this.state.toggled});\n },\n render: function() {\n if (this.state.toggled) {\n return Component2(null );\n }\n return Component(null );\n }\n });\n\n ReactMount.allowFullPageRender = true;\n var component = React.renderComponent(Root(null ), testDocument);\n expect(testDocument.body.innerHTML).toBe(' Hello world ');\n\n // Reactive update via state transition\n component.toggle();\n\n expect(testDocument.body.innerHTML).toBe(' Goodbye world ');\n\n });\n\n it('should be able to switch root constructors', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n \" Hello world \"\n )\n )\n );\n }\n });\n\n var Component2 = React.createClass({displayName: 'Component2',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n \" Goodbye world \"\n )\n )\n );\n }\n });\n\n ReactMount.allowFullPageRender = true;\n React.renderComponent(Component(null ), testDocument);\n\n expect(testDocument.body.innerHTML).toBe(' Hello world ');\n\n // Reactive update\n React.renderComponent(Component2(null ), testDocument);\n\n expect(testDocument.body.innerHTML).toBe(' Goodbye world ');\n\n });\n\n it('should be able to mount into document', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n this.props.text\n )\n )\n );\n }\n });\n ReactMount.allowFullPageRender = true;\n React.renderComponent(Component( {text:\"Hello world\"} ), testDocument);\n\n expect(testDocument.body.innerHTML).toBe('Hello world');\n });\n\n it('should throw on full document render', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var container = testDocument;\n expect(function() {\n React.renderComponent(React.DOM.html(null ), container);\n }).toThrow(\n 'Invariant Violation: mountComponentIntoNode(...): Target container is ' +\n 'not valid.'\n );\n ReactMount.allowFullPageRender = true;\n expect(function() {\n React.renderComponent(React.DOM.html(null ), container);\n }).not.toThrow();\n });\n\n it('should throw on full document render of non-html', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var container = testDocument;\n ReactMount.allowFullPageRender = true;\n expect(function() {\n React.renderComponent(React.DOM.div(null ), container);\n }).toThrow(\n 'Invariant Violation: mutateHTMLNodeWithMarkup(): ' +\n 'markup must start with = 0; i--) {\n triggerUpdate(components[i]);\n }\n });\n\n expectUpdates(expectation);\n }\n\n testUpdates(\n [root.refs.switcher.refs.box, root.refs.switcher],\n ['Switcher', 'Box', 'Child']\n );\n\n testUpdates(\n [root.refs.child, root.refs.switcher.refs.box],\n ['Box', 'Child']\n );\n\n testUpdates(\n [root.refs.child, root.refs.switcher],\n ['Switcher', 'Box', 'Child']\n );\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactUpdates-test\", module);\n", +"core/__tests__/refs-destruction-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React = require(\"../../React\");\nvar ReactTestUtils = require(\"../../ReactTestUtils\");\nvar reactComponentExpect= require(\"../../reactComponentExpect\");\n\nvar TestComponent = React.createClass({displayName: 'TestComponent',\n render: function() {\n return (\n React.DOM.div(null, \n React.DOM.div( {ref:\"theInnerDiv\"}, \n \" Lets try to destroy this. \"\n )\n )\n );\n }\n});\n\ndescribe('refs-destruction', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n it(\"should remove refs when destroying the parent\", function() {\n var testInstance = ReactTestUtils.renderIntoDocument(TestComponent(null ));\n reactComponentExpect(testInstance.refs.theInnerDiv)\n .toBeDOMComponentWithTag('div');\n expect(Object.keys(testInstance.refs || {}).length).toEqual(1);\n testInstance.unmountComponent();\n expect(Object.keys(testInstance.refs || {}).length).toEqual(0);\n });\n\n it(\"should remove refs when destroying the child\", function() {\n var testInstance = ReactTestUtils.renderIntoDocument(TestComponent(null ));\n reactComponentExpect(testInstance.refs.theInnerDiv)\n .toBeDOMComponentWithTag('div');\n expect(Object.keys(testInstance.refs || {}).length).toEqual(1);\n testInstance.refs.theInnerDiv.unmountComponent();\n expect(Object.keys(testInstance.refs || {}).length).toEqual(0);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/refs-destruction-test\", module);\n", +"core/__tests__/refs-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React = require(\"../../React\");\nvar ReactTestUtils = require(\"../../ReactTestUtils\");\n\nvar reactComponentExpect= require(\"../../reactComponentExpect\");\n\n\n/**\n * Counts clicks and has a renders an item for each click. Each item rendered\n * has a ref of the form \"clickLogN\".\n */\nvar ClickCounter = React.createClass({displayName: 'ClickCounter',\n getInitialState: function() {\n return {count: this.props.initialCount};\n },\n triggerReset: function() {\n this.setState({count: this.props.initialCount});\n },\n handleClick: function() {\n this.setState({count: this.state.count + 1});\n },\n render: function() {\n var children = [];\n var i;\n for (i=0; i < this.state.count; i++) {\n children.push(\n React.DOM.div(\n {className:\"clickLogDiv\",\n key:\"clickLog\" + i,\n ref:\"clickLog\" + i}\n )\n );\n }\n return (\n React.DOM.span( {className:\"clickIncrementer\", onClick:this.handleClick}, \n children\n )\n );\n }\n});\n\n/**\n * Only purpose is to test that refs are tracked even when applied to a\n * component that is injected down several layers. Ref systems are difficult to\n * build in such a way that ownership is maintained in an airtight manner.\n */\nvar GeneralContainerComponent = React.createClass({displayName: 'GeneralContainerComponent',\n render: function() {\n return React.DOM.div(null, this.props.children );\n }\n});\n\n/**\n * Notice how refs ownership is maintained even when injecting a component\n * into a different parent.\n */\nvar TestRefsComponent = React.createClass({displayName: 'TestRefsComponent',\n doReset: function() {\n this.refs.myCounter.triggerReset();\n },\n render: function() {\n return (\n React.DOM.div(null, \n React.DOM.div( {ref:\"resetDiv\", onClick:this.doReset}, \n \" Reset Me By Clicking This. \"\n ),\n GeneralContainerComponent( {ref:\"myContainer\"}, \n ClickCounter( {ref:\"myCounter\", initialCount:1})\n )\n )\n );\n }\n});\n\n/**\n * Render a TestRefsComponent and ensure that the main refs are wired up.\n */\nvar renderTestRefsComponent = function() {\n var testRefsComponent =\n ReactTestUtils.renderIntoDocument(TestRefsComponent(null ));\n\n reactComponentExpect(testRefsComponent)\n .toBeCompositeComponentWithType(TestRefsComponent);\n\n var generalContainer = testRefsComponent.refs.myContainer;\n var counter = testRefsComponent.refs.myCounter;\n\n reactComponentExpect(generalContainer)\n .toBeCompositeComponentWithType(GeneralContainerComponent);\n reactComponentExpect(counter)\n .toBeCompositeComponentWithType(ClickCounter);\n\n return testRefsComponent;\n};\n\n\nvar expectClickLogsLengthToBe = function(instance, length) {\n var clickLogs =\n ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, 'clickLogDiv');\n expect(clickLogs.length).toBe(length);\n expect(Object.keys(instance.refs.myCounter.refs).length).toBe(length);\n};\n\ndescribe('reactiverefs', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n /**\n * Ensure that for every click log there is a corresponding ref (from the\n * perspective of the injected ClickCounter component.\n */\n it(\"Should increase refs with an increase in divs\", function() {\n var testRefsComponent = renderTestRefsComponent();\n var clickIncrementer =\n ReactTestUtils.findRenderedDOMComponentWithClass(\n testRefsComponent,\n 'clickIncrementer'\n );\n\n expectClickLogsLengthToBe(testRefsComponent, 1);\n\n // After clicking the reset, there should still only be one click log ref.\n ReactTestUtils.Simulate.click(testRefsComponent.refs.resetDiv);\n expectClickLogsLengthToBe(testRefsComponent, 1);\n\n // Begin incrementing clicks (and therefore refs).\n ReactTestUtils.Simulate.click(clickIncrementer);\n expectClickLogsLengthToBe(testRefsComponent, 2);\n\n ReactTestUtils.Simulate.click(clickIncrementer);\n expectClickLogsLengthToBe(testRefsComponent, 3);\n\n // Now reset again\n ReactTestUtils.Simulate.click(testRefsComponent.refs.resetDiv);\n expectClickLogsLengthToBe(testRefsComponent, 1);\n\n });\n\n});\n\n\n\n/**\n * Tests that when a ref hops around children, we can track that correctly.\n */\ndescribe('ref swapping', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n var RefHopsAround = React.createClass({displayName: 'RefHopsAround',\n getInitialState: function() {\n return {count: 0};\n },\n moveRef: function() {\n this.setState({ count: this.state.count + 1 });\n },\n render: function() {\n var count = this.state.count;\n /**\n * What we have here, is three divs with refs (div1/2/3), but a single\n * moving cursor ref `hopRef` that \"hops\" around the three. We'll call the\n * `moveRef()` function several times and make sure that the hop ref\n * points to the correct divs.\n */\n return (\n React.DOM.div(null, \n React.DOM.div(\n {className:\"first\",\n ref:count % 3 === 0 ? 'hopRef' : 'divOneRef'}\n ),\n React.DOM.div(\n {className:\"second\",\n ref:count % 3 === 1 ? 'hopRef' : 'divTwoRef'}\n ),\n React.DOM.div(\n {className:\"third\",\n ref:count % 3 === 2 ? 'hopRef' : 'divThreeRef'}\n )\n )\n );\n }\n });\n\n it(\"Allow refs to hop around children correctly\", function() {\n var refHopsAround = ReactTestUtils.renderIntoDocument(RefHopsAround(null ));\n\n var firstDiv =\n ReactTestUtils.findRenderedDOMComponentWithClass(refHopsAround, 'first');\n var secondDiv =\n ReactTestUtils.findRenderedDOMComponentWithClass(refHopsAround, 'second');\n var thirdDiv =\n ReactTestUtils.findRenderedDOMComponentWithClass(refHopsAround, 'third');\n\n expect(refHopsAround.refs.hopRef).toEqual(firstDiv);\n expect(refHopsAround.refs.divTwoRef).toEqual(secondDiv);\n expect(refHopsAround.refs.divThreeRef).toEqual(thirdDiv);\n\n refHopsAround.moveRef();\n expect(refHopsAround.refs.divOneRef).toEqual(firstDiv);\n expect(refHopsAround.refs.hopRef).toEqual(secondDiv);\n expect(refHopsAround.refs.divThreeRef).toEqual(thirdDiv);\n\n refHopsAround.moveRef();\n expect(refHopsAround.refs.divOneRef).toEqual(firstDiv);\n expect(refHopsAround.refs.divTwoRef).toEqual(secondDiv);\n expect(refHopsAround.refs.hopRef).toEqual(thirdDiv);\n\n /**\n * Make sure that after the third, we're back to where we started and the\n * refs are completely restored.\n */\n refHopsAround.moveRef();\n expect(refHopsAround.refs.hopRef).toEqual(firstDiv);\n expect(refHopsAround.refs.divTwoRef).toEqual(secondDiv);\n expect(refHopsAround.refs.divThreeRef).toEqual(thirdDiv);\n });\n});\n\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/refs-test\", module);\n", +"dom/__tests__/CSSPropertyOperations-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar React = require(\"../../React\");\n\ndescribe('CSSPropertyOperations', function() {\n var CSSPropertyOperations;\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n CSSPropertyOperations = require(\"../../CSSPropertyOperations\");\n });\n\n it('should create markup for simple styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n backgroundColor: '#3b5998',\n display: 'none'\n })).toBe('background-color:#3b5998;display:none;');\n });\n\n it('should ignore undefined styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n backgroundColor: undefined,\n display: 'none'\n })).toBe('display:none;');\n });\n\n it('should ignore null styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n backgroundColor: null,\n display: 'none'\n })).toBe('display:none;');\n });\n\n it('should return null for no styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n backgroundColor: null,\n display: null\n })).toBe(null);\n });\n\n it('should automatically append `px` to relevant styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n left: 0,\n margin: 16,\n opacity: 0.5,\n padding: '4px'\n })).toBe('left:0;margin:16px;opacity:0.5;padding:4px;');\n });\n\n it('should not append `px` to styles that might need a number', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n fillOpacity: 1,\n fontWeight: 2,\n opacity: 3,\n orphans: 4,\n zIndex: 5,\n zoom: 6,\n lineHeight: 7\n })).toBe(\n 'fill-opacity:1;font-weight:2;opacity:3;orphans:4;z-index:5;zoom:6;' +\n 'line-height:7;'\n );\n });\n\n it('should set style attribute when styles exist', function() {\n var styles = {\n backgroundColor: '#000',\n display: 'none'\n };\n var div = React.DOM.div( {style:styles} );\n var root = document.createElement('div');\n React.renderComponent(div, root);\n expect(/style=\".*\"/.test(root.innerHTML)).toBe(true);\n });\n\n it('should not set style attribute when no styles exist', function() {\n var styles = {\n backgroundColor: null,\n display: null\n };\n var div = React.DOM.div( {style:styles} );\n var root = document.createElement('div');\n React.renderComponent(div, root);\n expect(/style=\".*\"/.test(root.innerHTML)).toBe(false);\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/CSSPropertyOperations-test\", module);\n", +"dom/__tests__/DOMPropertyOperations-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\ndescribe('DOMPropertyOperations', function() {\n var DOMPropertyOperations;\n var DOMProperty;\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n var ReactDefaultInjection = require(\"../../ReactDefaultInjection\");\n ReactDefaultInjection.inject();\n\n DOMPropertyOperations = require(\"../../DOMPropertyOperations\");\n DOMProperty = require(\"../../DOMProperty\");\n });\n\n describe('createMarkupForProperty', function() {\n\n it('should create markup for simple properties', function() {\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'name',\n 'simple'\n )).toBe('name=\"simple\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'name',\n false\n )).toBe('name=\"false\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'name',\n null\n )).toBe('');\n });\n\n it('should work with the id attribute', function() {\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'id',\n 'simple'\n )).toBe('id=\"simple\"');\n });\n\n it('should warn about incorrect casing', function() {\n spyOn(console, 'warn');\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'tabindex',\n '1'\n )).toBe(null);\n expect(console.warn.argsForCall.length).toBe(1);\n expect(console.warn.argsForCall[0][0]).toContain('tabIndex');\n });\n\n it('should warn about class', function() {\n spyOn(console, 'warn');\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'class',\n 'muffins'\n )).toBe(null);\n expect(console.warn.argsForCall.length).toBe(1);\n expect(console.warn.argsForCall[0][0]).toContain('className');\n });\n\n it('should create markup for boolean properties', function() {\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'checked',\n 'simple'\n )).toBe('checked=\"simple\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'checked',\n true\n )).toBe('checked=\"true\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'checked',\n false\n )).toBe('');\n });\n\n it('should create markup for custom attributes', function() {\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'aria-label',\n 'simple'\n )).toBe('aria-label=\"simple\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'aria-label',\n false\n )).toBe('aria-label=\"false\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'aria-label',\n null\n )).toBe('');\n });\n\n });\n\n describe('setValueForProperty', function() {\n var stubNode;\n\n beforeEach(function() {\n stubNode = document.createElement('div');\n });\n\n it('should set values as properties by default', function() {\n DOMPropertyOperations.setValueForProperty(stubNode, 'title', 'Tip!');\n expect(stubNode.title).toBe('Tip!');\n });\n\n it('should set values as attributes if necessary', function() {\n DOMPropertyOperations.setValueForProperty(stubNode, 'role', '#');\n expect(stubNode.getAttribute('role')).toBe('#');\n expect(stubNode.role).toBeUndefined();\n });\n\n it('should convert attribute values to string first', function() {\n // Browsers default to this behavior, but some test environments do not.\n // This ensures that we have consistent behavior.\n var obj = {toString: function() { return ''; }};\n DOMPropertyOperations.setValueForProperty(stubNode, 'role', obj);\n expect(stubNode.getAttribute('role')).toBe('');\n });\n\n it('should remove for falsey boolean properties', function() {\n DOMPropertyOperations.setValueForProperty(\n stubNode,\n 'allowFullScreen',\n false\n );\n expect(stubNode.hasAttribute('allowFullScreen')).toBe(false);\n });\n\n it('should use mutation method where applicable', function() {\n DOMPropertyOperations.setValueForProperty(\n stubNode,\n 'className',\n 'selected'\n );\n expect(stubNode.className).toBe('selected');\n\n DOMPropertyOperations.setValueForProperty(\n stubNode,\n 'className',\n null\n );\n expect(stubNode.className).toBe('');\n });\n\n });\n\n describe('injectDOMPropertyConfig', function() {\n it('should support custom attributes', function() {\n // foobar does not exist yet\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'foobar',\n 'simple'\n )).toBe(null);\n\n // foo-* does not exist yet\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'foo-xyz',\n 'simple'\n )).toBe(null);\n\n // inject foobar DOM property\n DOMProperty.injection.injectDOMPropertyConfig({\n isCustomAttribute: function(name) {\n return name.indexOf('foo-') === 0;\n },\n Properties: {foobar: null}\n });\n\n // Ensure old attributes still work\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'name',\n 'simple'\n )).toBe('name=\"simple\"');\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'data-name',\n 'simple'\n )).toBe('data-name=\"simple\"');\n\n // foobar should work\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'foobar',\n 'simple'\n )).toBe('foobar=\"simple\"');\n\n // foo-* should work\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'foo-xyz',\n 'simple'\n )).toBe('foo-xyz=\"simple\"');\n\n // It should complain about double injections.\n expect(function() {\n DOMProperty.injection.injectDOMPropertyConfig(\n {Properties: {foobar: null}}\n );\n }).toThrow();\n });\n });\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/DOMPropertyOperations-test\", module);\n", +"dom/__tests__/Danger-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\nvar React = require(\"../../React\");\n\ndescribe('Danger', function() {\n\n describe('dangerouslyRenderMarkup', function() {\n var Danger;\n var transaction;\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n Danger = require(\"../../Danger\");\n\n var ReactReconcileTransaction = require(\"../../ReactReconcileTransaction\");\n transaction = new ReactReconcileTransaction();\n });\n\n it('should render markup', function() {\n var markup = (React.DOM.div(null )).mountComponent('.rX', transaction, 0);\n var output = Danger.dangerouslyRenderMarkup([markup])[0];\n\n expect(output.nodeName).toBe('DIV');\n });\n\n it('should render markup with props', function() {\n var markup = (React.DOM.div( {className:\"foo\"} )).mountComponent(\n '.rX',\n transaction,\n 0\n );\n var output = Danger.dangerouslyRenderMarkup([markup])[0];\n\n expect(output.nodeName).toBe('DIV');\n expect(output.className).toBe('foo');\n });\n\n it('should render wrapped markup', function() {\n var markup = (React.DOM.th(null )).mountComponent('.rX', transaction, 0);\n var output = Danger.dangerouslyRenderMarkup([markup])[0];\n\n expect(output.nodeName).toBe('TH');\n });\n\n it('should render lists of markup with similar `nodeName`', function() {\n var renderedMarkup = Danger.dangerouslyRenderMarkup(\n ['

1

', '

2

', '

3

']\n );\n\n expect(renderedMarkup.length).toBe(3);\n\n expect(renderedMarkup[0].nodeName).toBe('P');\n expect(renderedMarkup[1].nodeName).toBe('P');\n expect(renderedMarkup[2].nodeName).toBe('P');\n\n expect(renderedMarkup[0].innerHTML).toBe('1');\n expect(renderedMarkup[1].innerHTML).toBe('2');\n expect(renderedMarkup[2].innerHTML).toBe('3');\n });\n\n it('should render lists of markup with different `nodeName`', function() {\n var renderedMarkup = Danger.dangerouslyRenderMarkup(\n ['

1

', '2', '

3

']\n );\n\n expect(renderedMarkup.length).toBe(3);\n\n expect(renderedMarkup[0].nodeName).toBe('P');\n expect(renderedMarkup[1].nodeName).toBe('TD');\n expect(renderedMarkup[2].nodeName).toBe('P');\n\n expect(renderedMarkup[0].innerHTML).toBe('1');\n expect(renderedMarkup[1].innerHTML).toBe('2');\n expect(renderedMarkup[2].innerHTML).toBe('3');\n });\n\n it('should throw when rendering invalid markup', function() {\n expect(function() {\n Danger.dangerouslyRenderMarkup(['']);\n }).toThrow(\n 'Invariant Violation: dangerouslyRenderMarkup(...): Missing markup.'\n );\n\n spyOn(console, \"error\");\n\n var renderedMarkup = Danger.dangerouslyRenderMarkup(['

']);\n var args = console.error.argsForCall[0];\n\n expect(renderedMarkup.length).toBe(1);\n expect(renderedMarkup[0].nodeName).toBe('P');\n\n expect(console.error.argsForCall.length).toBe(1);\n\n expect(args.length).toBe(2);\n expect(args[0]).toBe('Danger: Discarding unexpected node:');\n expect(args[1].nodeName).toBe('P');\n });\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/Danger-test\", module);\n", +"dom/__tests__/getNodeForCharacterOffset-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar getTestDocument = require(\"../../getTestDocument\");\n\nvar getNodeForCharacterOffset = require(\"../../getNodeForCharacterOffset\");\n\n// Create node from HTML string\nfunction createNode(html) {\n var node = (getTestDocument() || document).createElement('div');\n node.innerHTML = html;\n return node;\n}\n\n// Check getNodeForCharacterOffset return value matches expected result.\nfunction expectNodeOffset(result, textContent, nodeOffset) {\n expect(result.node.textContent).toBe(textContent);\n expect(result.offset).toBe(nodeOffset);\n}\n\ndescribe('getNodeForCharacterOffset', function() {\n it('should handle siblings', function() {\n var node = createNode('123456789');\n\n expectNodeOffset(getNodeForCharacterOffset(node, 0), '123', 0);\n expectNodeOffset(getNodeForCharacterOffset(node, 4), '456', 1);\n });\n\n it('should handle trailing chars', function() {\n var node = createNode('123456789');\n\n expectNodeOffset(getNodeForCharacterOffset(node, 3), '123', 3);\n expectNodeOffset(getNodeForCharacterOffset(node, 9), '789', 3);\n });\n\n it('should handle trees', function() {\n var node = createNode(\n '' +\n '1' +\n '' +\n '' +\n '2' +\n '' +\n '' +\n '' +\n '' +\n '3' +\n '45' +\n '' +\n ''\n );\n\n expectNodeOffset(getNodeForCharacterOffset(node, 3), '3', 1);\n expectNodeOffset(getNodeForCharacterOffset(node, 5), '45', 2);\n expect(getNodeForCharacterOffset(node, 10)).toBeUndefined();\n });\n\n it('should handle non-existent offset', function() {\n var node = createNode('123');\n\n expect(getNodeForCharacterOffset(node, -1)).toBeUndefined();\n expect(getNodeForCharacterOffset(node, 4)).toBeUndefined();\n });\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/getNodeForCharacterOffset-test\", module);\n", +"dom/__tests__/mutateHTMLNodeWithMarkup-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar getTestDocument = require(\"../../getTestDocument\");\n\nvar mutateHTMLNodeWithMarkup = require(\"../../mutateHTMLNodeWithMarkup\");\n\ndescribe('mutateHTMLNodeWithMarkup', function() {\n it('should mutate the document html', function() {\n var html = 'testtest';\n var testDocument = getTestDocument() || document;\n\n mutateHTMLNodeWithMarkup(testDocument.documentElement, html);\n expect(testDocument.body.innerHTML).toBe('test');\n });\n\n it('should change attributes', function() {\n var html = 'testtest';\n var testDocument = getTestDocument() || document;\n\n mutateHTMLNodeWithMarkup(testDocument.documentElement, html);\n expect(!!testDocument.documentElement.getAttribute('lang')).toBe(false);\n\n var html2 = 'test' +\n 'test';\n mutateHTMLNodeWithMarkup(testDocument.documentElement, html2);\n expect(testDocument.documentElement.getAttribute('lang')).toBe('en');\n\n mutateHTMLNodeWithMarkup(testDocument.documentElement, html);\n expect(!!testDocument.documentElement.getAttribute('lang')).toBe(false);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/mutateHTMLNodeWithMarkup-test\", module);\n", +"dom/components/__tests__/ReactDOMButton-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n/*jshint evil:true */\n\nvar mocks = require(\"../../../mocks\");\n\ndescribe('ReactDOMButton', function() {\n var React;\n var ReactTestUtils;\n\n var onClick = mocks.getMockFunction();\n\n function expectClickThru(button) {\n onClick.mockClear();\n ReactTestUtils.Simulate.click(button.getDOMNode());\n expect(onClick.mock.calls.length).toBe(1);\n }\n\n function expectNoClickThru(button) {\n onClick.mockClear();\n ReactTestUtils.Simulate.click(button.getDOMNode());\n expect(onClick.mock.calls.length).toBe(0);\n }\n\n function mounted(button) {\n ReactTestUtils.renderIntoDocument(button);\n return button;\n }\n\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactTestUtils = require(\"../../../ReactTestUtils\");\n });\n\n it('should forward clicks when it starts out not disabled', function() {\n expectClickThru(mounted(React.DOM.button( {onClick:onClick} )));\n });\n\n it('should not forward clicks when it starts out disabled', function() {\n expectNoClickThru(\n mounted(React.DOM.button( {disabled:true, onClick:onClick} ))\n );\n });\n\n it('should forward clicks when it becomes not disabled', function() {\n var btn = mounted(React.DOM.button( {disabled:true, onClick:onClick} ));\n btn.setProps({disabled: false});\n expectClickThru(btn);\n });\n\n it('should not forward clicks when it becomes disabled', function() {\n var btn = mounted(React.DOM.button( {onClick:onClick} ));\n btn.setProps({disabled: true});\n expectNoClickThru(btn);\n });\n\n it('should work correctly if the listener is changed', function() {\n var btn = mounted(\n React.DOM.button( {disabled:true, onClick:function() {}} )\n );\n\n btn.setProps({\n disabled: false,\n onClick: onClick\n });\n\n expectClickThru(btn);\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"dom/components/__tests__/ReactDOMButton-test\", module);\n", +"dom/components/__tests__/ReactDOMInput-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n/*jshint evil:true */\n\nvar emptyFunction = require(\"../../../emptyFunction\");\nvar mocks = require(\"../../../mocks\");\n\ndescribe('ReactDOMInput', function() {\n var React;\n var ReactLink;\n var ReactTestUtils;\n\n var renderTextInput;\n\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactLink = require(\"../../../ReactLink\");\n ReactTestUtils = require(\"../../../ReactTestUtils\");\n\n renderTextInput = function(component) {\n var stub = ReactTestUtils.renderIntoDocument(component);\n var node = stub.getDOMNode();\n return node;\n };\n });\n\n it('should display `defaultValue` of number 0', function() {\n var stub = React.DOM.input( {type:\"text\", defaultValue:0} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('0');\n });\n\n it('should display \"true\" for `defaultValue` of `true`', function() {\n var stub = React.DOM.input( {type:\"text\", defaultValue:true} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('true');\n });\n\n it('should display \"false\" for `defaultValue` of `false`', function() {\n var stub = React.DOM.input( {type:\"text\", defaultValue:false} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('false');\n });\n\n it('should display \"foobar\" for `defaultValue` of `objToString`', function() {\n var objToString = {\n toString: function() {\n return \"foobar\";\n }\n };\n\n var stub = React.DOM.input( {type:\"text\", defaultValue:objToString} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('foobar');\n });\n\n it('should display `value` of number 0', function() {\n var stub = React.DOM.input( {type:\"text\", value:0} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('0');\n });\n\n it('should allow setting `value` to `true`', function() {\n var stub = React.DOM.input( {type:\"text\", value:\"yolo\"} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('yolo');\n\n stub.replaceProps({value: true});\n expect(node.value).toEqual('true');\n });\n\n it(\"should allow setting `value` to `false`\", function() {\n var stub = React.DOM.input( {type:\"text\", value:\"yolo\"} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('yolo');\n\n stub.replaceProps({value: false});\n expect(node.value).toEqual('false');\n });\n\n it('should allow setting `value` to `objToString`', function() {\n var stub = React.DOM.input( {type:\"text\", value:\"foo\"} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('foo');\n\n var objToString = {\n toString: function() {\n return \"foobar\";\n }\n };\n\n stub.replaceProps({value: objToString});\n expect(node.value).toEqual('foobar');\n });\n\n it('should properly control a value of number `0`', function() {\n var stub = React.DOM.input( {type:\"text\", value:0} );\n var node = renderTextInput(stub);\n\n node.value = 'giraffe';\n ReactTestUtils.Simulate.input(node);\n expect(node.value).toBe('0');\n });\n\n it('should control radio buttons', function() {\n var RadioGroup = React.createClass({displayName: 'RadioGroup',\n render: function() {\n return (\n React.DOM.div(null, \n React.DOM.input( {ref:\"a\", type:\"radio\", name:\"fruit\", checked:true} ),\"A \",\n React.DOM.input( {ref:\"b\", type:\"radio\", name:\"fruit\"} ),\"B \",\n React.DOM.form(null, \n React.DOM.input( {ref:\"c\", type:\"radio\", name:\"fruit\", defaultChecked:true} )\n )\n )\n );\n }\n });\n\n var stub = ReactTestUtils.renderIntoDocument(RadioGroup(null ));\n var aNode = stub.refs.a.getDOMNode();\n var bNode = stub.refs.b.getDOMNode();\n var cNode = stub.refs.c.getDOMNode();\n\n expect(aNode.checked).toBe(true);\n expect(bNode.checked).toBe(false);\n // c is in a separate form and shouldn't be affected at all here\n expect(cNode.checked).toBe(true);\n\n bNode.checked = true;\n // This next line isn't necessary in a proper browser environment, but\n // jsdom doesn't uncheck the others in a group (which makes this whole test\n // a little less effective)\n aNode.checked = false;\n expect(cNode.checked).toBe(true);\n\n // Now let's run the actual ReactDOMInput change event handler (on radio\n // inputs, ChangeEventPlugin listens for the `click` event so trigger that)\n ReactTestUtils.Simulate.click(bNode);\n\n // The original state should have been restored\n expect(aNode.checked).toBe(true);\n expect(cNode.checked).toBe(true);\n });\n\n it('should support ReactLink', function() {\n var container = document.createElement('div');\n var link = new ReactLink('yolo', mocks.getMockFunction());\n var instance = React.DOM.input( {type:\"text\", valueLink:link} );\n\n React.renderComponent(instance, container);\n\n expect(instance.getDOMNode().value).toBe('yolo');\n expect(link.value).toBe('yolo');\n expect(link.requestChange.mock.calls.length).toBe(0);\n\n instance.getDOMNode().value = 'test';\n ReactTestUtils.Simulate.input(instance.getDOMNode());\n\n expect(link.requestChange.mock.calls.length).toBe(1);\n expect(link.requestChange.mock.calls[0][0]).toEqual('test');\n });\n\n it('should throw if both value and valueLink are provided', function() {\n var node = document.createElement('div');\n var link = new ReactLink('yolo', mocks.getMockFunction());\n var instance = React.DOM.input( {type:\"text\", valueLink:link} );\n\n expect(React.renderComponent.bind(React, instance, node)).not.toThrow();\n\n instance = React.DOM.input( {type:\"text\", valueLink:link, value:\"test\"} );\n expect(React.renderComponent.bind(React, instance, node)).toThrow();\n\n instance = React.DOM.input( {type:\"text\", valueLink:link, onChange:emptyFunction} );\n expect(React.renderComponent.bind(React, instance, node)).toThrow();\n\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"dom/components/__tests__/ReactDOMInput-test\", module);\n", +"dom/components/__tests__/ReactDOMSelect-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n/*jshint evil:true */\n\nvar mocks = require(\"../../../mocks\");\n\ndescribe('ReactDOMSelect', function() {\n var React;\n var ReactLink;\n var ReactTestUtils;\n\n var renderSelect;\n\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactLink = require(\"../../../ReactLink\");\n ReactTestUtils = require(\"../../../ReactTestUtils\");\n\n renderSelect = function(component) {\n var stub = ReactTestUtils.renderIntoDocument(component);\n var node = stub.getDOMNode();\n return node;\n };\n });\n\n it('should allow setting `defaultValue`', function() {\n var stub =\n React.DOM.select( {defaultValue:\"giraffe\"}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.value).toBe('giraffe');\n\n // Changing `defaultValue` should do nothing.\n stub.setProps({defaultValue: 'gorilla'});\n expect(node.value).toEqual('giraffe');\n });\n\n it('should allow setting `defaultValue` with multiple', function() {\n var stub =\n React.DOM.select( {multiple:true, defaultValue:['giraffe', 'gorilla']}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(true); // gorilla\n\n // Changing `defaultValue` should do nothing.\n stub.setProps({defaultValue: ['monkey']});\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(true); // gorilla\n });\n\n it('should allow setting `value`', function() {\n var stub =\n React.DOM.select( {value:\"giraffe\"}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.value).toBe('giraffe');\n\n // Changing the `value` prop should change the selected option.\n stub.setProps({value: 'gorilla'});\n expect(node.value).toEqual('gorilla');\n });\n\n it('should allow setting `value` with multiple', function() {\n var stub =\n React.DOM.select( {multiple:true, value:['giraffe', 'gorilla']}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(true); // gorilla\n\n // Changing the `value` prop should change the selected options.\n stub.setProps({value: ['monkey']});\n\n expect(node.options[0].selected).toBe(true); // monkey\n expect(node.options[1].selected).toBe(false); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n });\n\n it('should allow setting `value` with `objectToString`', function() {\n var objectToString = {\n animal: \"giraffe\",\n toString: function() {\n return this.animal;\n }\n };\n\n var stub =\n React.DOM.select( {multiple:true, value:[objectToString]}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n\n // Changing the `value` prop should change the selected options.\n objectToString.animal = \"monkey\";\n stub.forceUpdate();\n\n expect(node.options[0].selected).toBe(true); // monkey\n expect(node.options[1].selected).toBe(false); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n });\n\n it('should allow switching to multiple', function() {\n var stub =\n React.DOM.select( {defaultValue:\"giraffe\"}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n\n // When making it multiple, giraffe should still be selected\n stub.setProps({multiple: true, defaultValue: null});\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n });\n\n it('should allow switching from multiple', function() {\n var stub =\n React.DOM.select( {multiple:true, defaultValue:['giraffe', 'gorilla']}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(true); // gorilla\n\n // When removing multiple, giraffe should still be selected (but gorilla\n // will no longer be)\n stub.setProps({multiple: false, defaultValue: null});\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n });\n\n it('should support ReactLink', function() {\n var link = new ReactLink('giraffe', mocks.getMockFunction());\n var stub =\n React.DOM.select( {valueLink:link}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n expect(link.requestChange.mock.calls.length).toBe(0);\n\n node.options[1].selected = false;\n node.options[2].selected = true;\n ReactTestUtils.Simulate.change(node);\n\n expect(link.requestChange.mock.calls.length).toBe(1);\n expect(link.requestChange.mock.calls[0][0]).toEqual('gorilla');\n\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"dom/components/__tests__/ReactDOMSelect-test\", module);\n", +"dom/components/__tests__/ReactDOMTextarea-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n/*jshint evil:true */\n\nvar mocks = require(\"../../../mocks\");\n\ndescribe('ReactDOMTextarea', function() {\n var React;\n var ReactLink;\n var ReactTestUtils;\n\n var renderTextarea;\n\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactLink = require(\"../../../ReactLink\");\n ReactTestUtils = require(\"../../../ReactTestUtils\");\n\n renderTextarea = function(component) {\n var stub = ReactTestUtils.renderIntoDocument(component);\n var node = stub.getDOMNode();\n // Polyfilling the browser's quirky behavior.\n node.value = node.innerHTML;\n return node;\n };\n });\n\n it('should allow setting `defaultValue`', function() {\n var stub = React.DOM.textarea( {defaultValue:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n // Changing `defaultValue` should do nothing.\n stub.replaceProps({defaultValue: 'gorilla'});\n expect(node.value).toEqual('giraffe');\n });\n\n it('should display `defaultValue` of number 0', function() {\n var stub = React.DOM.textarea( {defaultValue:0} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('0');\n });\n\n it('should display \"false\" for `defaultValue` of `false`', function() {\n var stub = React.DOM.textarea( {type:\"text\", defaultValue:false} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('false');\n });\n\n it('should display \"foobar\" for `defaultValue` of `objToString`', function() {\n var objToString = {\n toString: function() {\n return \"foobar\";\n }\n };\n\n var stub = React.DOM.textarea( {type:\"text\", defaultValue:objToString} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('foobar');\n });\n\n it('should display `value` of number 0', function() {\n var stub = React.DOM.textarea( {value:0} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('0');\n });\n\n it('should allow setting `value` to `giraffe`', function() {\n var stub = React.DOM.textarea( {value:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n stub.replaceProps({value: 'gorilla'});\n expect(node.value).toEqual('gorilla');\n });\n\n it('should allow setting `value` to `true`', function() {\n var stub = React.DOM.textarea( {value:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n stub.replaceProps({value: true});\n expect(node.value).toEqual('true');\n });\n\n it('should allow setting `value` to `false`', function() {\n var stub = React.DOM.textarea( {value:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n stub.replaceProps({value: false});\n expect(node.value).toEqual('false');\n });\n\n it('should allow setting `value` to `objToString`', function() {\n var stub = React.DOM.textarea( {value:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n var objToString = {\n toString: function() {\n return \"foo\";\n }\n };\n stub.replaceProps({value: objToString});\n expect(node.value).toEqual('foo');\n });\n\n it('should properly control a value of number `0`', function() {\n var stub = React.DOM.textarea( {value:0} );\n var node = renderTextarea(stub);\n\n node.value = 'giraffe';\n ReactTestUtils.Simulate.input(node);\n expect(node.value).toBe('0');\n });\n\n it('should treat children like `defaultValue`', function() {\n spyOn(console, 'warn');\n\n var stub = React.DOM.textarea(null, \"giraffe\");\n var node = renderTextarea(stub);\n\n expect(console.warn.argsForCall.length).toBe(1);\n expect(node.value).toBe('giraffe');\n\n // Changing children should do nothing, it functions like `defaultValue`.\n stub.replaceProps({children: 'gorilla'});\n expect(node.value).toEqual('giraffe');\n });\n\n it('should allow numbers as children', function() {\n spyOn(console, 'warn');\n var node = renderTextarea(React.DOM.textarea(null, 17));\n expect(console.warn.argsForCall.length).toBe(1);\n expect(node.value).toBe('17');\n });\n\n it('should allow booleans as children', function() {\n spyOn(console, 'warn');\n var node = renderTextarea(React.DOM.textarea(null, false));\n expect(console.warn.argsForCall.length).toBe(1);\n expect(node.value).toBe('false');\n });\n\n it('should allow objects as children', function() {\n spyOn(console, 'warn');\n var obj = {\n toString: function() {\n return \"sharkswithlasers\";\n }\n };\n var node = renderTextarea(React.DOM.textarea(null, obj));\n expect(console.warn.argsForCall.length).toBe(1);\n expect(node.value).toBe('sharkswithlasers');\n });\n\n it('should throw with multiple or invalid children', function() {\n spyOn(console, 'warn');\n\n expect(function() {\n ReactTestUtils.renderIntoDocument(\n React.DOM.textarea(null, 'hello','there')\n );\n }).toThrow();\n\n expect(console.warn.argsForCall.length).toBe(1);\n\n var stub;\n expect(function() {\n stub = renderTextarea(React.DOM.textarea(null, React.DOM.strong(null )));\n }).not.toThrow();\n\n expect(stub.value).toBe('[object Object]');\n\n expect(console.warn.argsForCall.length).toBe(2);\n });\n\n it('should support ReactLink', function() {\n var container = document.createElement('div');\n var link = new ReactLink('yolo', mocks.getMockFunction());\n var instance = React.DOM.textarea( {valueLink:link} );\n\n React.renderComponent(instance, container);\n\n expect(instance.getDOMNode().value).toBe('yolo');\n expect(link.value).toBe('yolo');\n expect(link.requestChange.mock.calls.length).toBe(0);\n\n instance.getDOMNode().value = 'test';\n ReactTestUtils.Simulate.input(instance.getDOMNode());\n\n expect(link.requestChange.mock.calls.length).toBe(1);\n expect(link.requestChange.mock.calls[0][0]).toEqual('test');\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"dom/components/__tests__/ReactDOMTextarea-test\", module);\n", +"environment/__tests__/ReactServerRendering-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\")\n .dontMock('ExecutionEnvironment')\n .dontMock('React')\n .dontMock('ReactMount')\n .dontMock('ReactServerRendering')\n .dontMock('ReactTestUtils')\n .dontMock('ReactMarkupChecksum');\n\nvar mocks = require(\"../../mocks\");\n\nvar React;\nvar ReactMount;\nvar ReactTestUtils;\nvar ReactServerRendering;\nvar ReactMarkupChecksum;\nvar ExecutionEnvironment;\n\ndescribe('ReactServerRendering', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n React = require(\"../../React\");\n ReactMount = require(\"../../ReactMount\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n ExecutionEnvironment = require(\"../../ExecutionEnvironment\");\n ExecutionEnvironment.canUseDOM = false;\n ReactServerRendering = require(\"../../ReactServerRendering\");\n ReactMarkupChecksum = require(\"../../ReactMarkupChecksum\");\n });\n\n it('should generate simple markup', function() {\n var response;\n ReactServerRendering.renderComponentToString(\n React.DOM.span(null, \"hello world\"),\n function(response_) {\n response = response_;\n }\n );\n expect(response).toMatch(\n 'hello world'\n );\n });\n\n it('should render composite components', function() {\n var Parent = React.createClass({displayName: 'Parent',\n render: function() {\n return React.DOM.div(null, Child( {name:\"child\"} ));\n }\n });\n var Child = React.createClass({displayName: 'Child',\n render: function() {\n return React.DOM.span(null, \"My name is \", this.props.name);\n }\n });\n var response;\n ReactServerRendering.renderComponentToString(\n Parent(null ),\n function(response_) {\n response = response_;\n }\n );\n expect(response).toMatch(\n '
' +\n '' +\n 'My name is ' +\n 'child' +\n '' +\n '
'\n );\n });\n\n it('should only execute certain lifecycle methods', function() {\n var lifecycle = [];\n var TestComponent = React.createClass({displayName: 'TestComponent',\n componentWillMount: function() {\n lifecycle.push('componentWillMount');\n },\n componentDidMount: function() {\n lifecycle.push('componentDidMount');\n },\n getInitialState: function() {\n lifecycle.push('getInitialState');\n return {name: 'TestComponent'};\n },\n render: function() {\n lifecycle.push('render');\n return React.DOM.span(null, \"Component name: \", this.state.name);\n },\n componentWillUpdate: function() {\n lifecycle.push('componentWillUpdate');\n },\n componentDidUpdate: function() {\n lifecycle.push('componentDidUpdate');\n },\n shouldComponentUpdate: function() {\n lifecycle.push('shouldComponentUpdate');\n },\n componentWillReceiveProps: function() {\n lifecycle.push('componentWillReceiveProps');\n },\n componentWillUnmount: function() {\n lifecycle.push('componentWillUnmount');\n }\n });\n\n var response;\n\n ReactServerRendering.renderComponentToString(\n TestComponent(null ),\n function (_response) {\n response = _response;\n }\n );\n\n expect(response).toMatch(\n '' +\n 'Component name: ' +\n 'TestComponent' +\n ''\n );\n expect(lifecycle).toEqual(\n ['getInitialState', 'componentWillMount', 'render']\n );\n });\n\n it('should have the correct mounting behavior', function() {\n // This test is testing client-side behavior.\n ExecutionEnvironment.canUseDOM = true;\n\n var mountCount = 0;\n var numClicks = 0;\n\n var TestComponent = React.createClass({displayName: 'TestComponent',\n componentDidMount: function() {\n mountCount++;\n },\n click: function() {\n numClicks++;\n },\n render: function() {\n return (\n React.DOM.span( {ref:\"span\", onClick:this.click}, \"Name: \", this.props.name)\n );\n }\n });\n\n var element = document.createElement('div');\n React.renderComponent(TestComponent(null ), element);\n\n var lastMarkup = element.innerHTML;\n\n // Exercise the update path. Markup should not change,\n // but some lifecycle methods should be run again.\n React.renderComponent(TestComponent( {name:\"x\"} ), element);\n expect(mountCount).toEqual(1);\n\n // Unmount and remount. We should get another mount event and\n // we should get different markup, as the IDs are unique each time.\n React.unmountComponentAtNode(element);\n expect(element.innerHTML).toEqual('');\n React.renderComponent(TestComponent( {name:\"x\"} ), element);\n expect(mountCount).toEqual(2);\n expect(element.innerHTML).not.toEqual(lastMarkup);\n\n // Now kill the node and render it on top of server-rendered markup, as if\n // we used server rendering. We should mount again, but the markup should be\n // unchanged. We will append a sentinel at the end of innerHTML to be sure\n // that innerHTML was not changed.\n React.unmountComponentAtNode(element);\n expect(element.innerHTML).toEqual('');\n\n ExecutionEnvironment.canUseDOM = false;\n ReactServerRendering.renderComponentToString(\n TestComponent( {name:\"x\"} ),\n function(markup) {\n lastMarkup = markup;\n }\n );\n ExecutionEnvironment.canUseDOM = true;\n\n element.innerHTML = lastMarkup + ' __sentinel__';\n\n React.renderComponent(TestComponent( {name:\"x\"} ), element);\n expect(mountCount).toEqual(3);\n expect(element.innerHTML.indexOf('__sentinel__') > -1).toBe(true);\n React.unmountComponentAtNode(element);\n expect(element.innerHTML).toEqual('');\n\n // Now simulate a situation where the app is not idempotent. React should\n // warn but do the right thing.\n var _warn = console.warn;\n console.warn = mocks.getMockFunction();\n element.innerHTML = lastMarkup;\n var instance = React.renderComponent(TestComponent( {name:\"y\"} ), element);\n expect(mountCount).toEqual(4);\n expect(console.warn.mock.calls.length).toBe(1);\n expect(element.innerHTML.length > 0).toBe(true);\n expect(element.innerHTML).not.toEqual(lastMarkup);\n console.warn = _warn;\n\n // Ensure the events system works\n expect(numClicks).toEqual(0);\n ReactTestUtils.Simulate.click(instance.refs.span.getDOMNode());\n expect(numClicks).toEqual(1);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"environment/__tests__/ReactServerRendering-test\", module);\n", +"environment/__tests__/ReactWebWorker-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\ndescribe('ReactWebWorker', function() {\n ;(typeof Worker == 'undefined' ? xit : it)('can run React in a web worker', function() {\n var done = false;\n var error;\n\n var worker = new Worker(window.ReactWebWorker_URL || '/src/test/worker.js?_=' + Date.now().toString(36));\n worker.addEventListener('message', function(e) {\n var data = JSON.parse(e.data);\n if (data.type == 'error') {\n error = data.message + \"\\n\" + data.stack;\n } else {\n expect(data.type).toBe('done');\n done = true;\n }\n });\n\n waitsFor(function() {\n return done;\n });\n runs(function() {\n if (error) {\n console.log(error);\n throw new Error(error);\n }\n });\n });\n});\n\nrequire(\"../../mock-modules\").register(\"environment/__tests__/ReactWebWorker-test\", module);\n", +"event/__tests__/EventPluginRegistry-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar merge = require(\"../../merge\");\n\ndescribe('EventPluginRegistry', function() {\n var EventPluginRegistry;\n var createPlugin;\n\n beforeEach(function() {\n EventPluginRegistry = require(\"../../EventPluginRegistry\");\n EventPluginRegistry._resetEventPlugins();\n\n createPlugin = function(properties) {\n return merge({extractEvents: function() {}}, properties);\n };\n });\n\n it('should be able to inject ordering before plugins', function() {\n var OnePlugin = createPlugin();\n var TwoPlugin = createPlugin();\n var ThreePlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n two: TwoPlugin\n });\n EventPluginRegistry.injectEventPluginsByName({\n three: ThreePlugin\n });\n\n expect(EventPluginRegistry.plugins.length).toBe(3);\n expect(EventPluginRegistry.plugins[0]).toBe(OnePlugin);\n expect(EventPluginRegistry.plugins[1]).toBe(TwoPlugin);\n expect(EventPluginRegistry.plugins[2]).toBe(ThreePlugin);\n });\n\n it('should be able to inject plugins before and after ordering', function() {\n var OnePlugin = createPlugin();\n var TwoPlugin = createPlugin();\n var ThreePlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n two: TwoPlugin\n });\n EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);\n EventPluginRegistry.injectEventPluginsByName({\n three: ThreePlugin\n });\n\n expect(EventPluginRegistry.plugins.length).toBe(3);\n expect(EventPluginRegistry.plugins[0]).toBe(OnePlugin);\n expect(EventPluginRegistry.plugins[1]).toBe(TwoPlugin);\n expect(EventPluginRegistry.plugins[2]).toBe(ThreePlugin);\n });\n\n it('should be able to inject repeated plugins and out-of-order', function() {\n var OnePlugin = createPlugin();\n var TwoPlugin = createPlugin();\n var ThreePlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n three: ThreePlugin\n });\n EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);\n EventPluginRegistry.injectEventPluginsByName({\n two: TwoPlugin,\n three: ThreePlugin\n });\n\n expect(EventPluginRegistry.plugins.length).toBe(3);\n expect(EventPluginRegistry.plugins[0]).toBe(OnePlugin);\n expect(EventPluginRegistry.plugins[1]).toBe(TwoPlugin);\n expect(EventPluginRegistry.plugins[2]).toBe(ThreePlugin);\n });\n\n it('should throw if plugin does not implement `extractEvents`', function() {\n var BadPlugin = {};\n\n EventPluginRegistry.injectEventPluginOrder(['bad']);\n\n expect(function() {\n EventPluginRegistry.injectEventPluginsByName({\n bad: BadPlugin\n });\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Event plugins must ' +\n 'implement an `extractEvents` method, but `bad` does not.'\n );\n });\n\n it('should throw if plugin does not exist in ordering', function() {\n var OnePlugin = createPlugin();\n var RandomPlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginOrder(['one']);\n\n expect(function() {\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n random: RandomPlugin\n });\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Cannot inject event plugins ' +\n 'that do not exist in the plugin ordering, `random`.'\n );\n });\n\n it('should throw if ordering is injected more than once', function() {\n var pluginOrdering = [];\n\n EventPluginRegistry.injectEventPluginOrder(pluginOrdering);\n\n expect(function() {\n EventPluginRegistry.injectEventPluginOrder(pluginOrdering);\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Cannot inject event plugin ' +\n 'ordering more than once.'\n );\n });\n\n it('should throw if different plugins injected using same name', function() {\n var OnePlugin = createPlugin();\n var TwoPlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginsByName({same: OnePlugin});\n\n expect(function() {\n EventPluginRegistry.injectEventPluginsByName({same: TwoPlugin});\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Cannot inject two different ' +\n 'event plugins using the same name, `same`.'\n );\n });\n\n it('should publish registration names of injected plugins', function() {\n var OnePlugin = createPlugin({\n eventTypes: {\n click: {registrationName: 'onClick'},\n focus: {registrationName: 'onFocus'}\n }\n });\n var TwoPlugin = createPlugin({\n eventTypes: {\n magic: {\n phasedRegistrationNames: {\n bubbled: 'onMagicBubble',\n captured: 'onMagicCapture'\n }\n }\n }\n });\n\n EventPluginRegistry.injectEventPluginsByName({one: OnePlugin});\n EventPluginRegistry.injectEventPluginOrder(['one', 'two']);\n\n expect(EventPluginRegistry.registrationNamesKeys.length).toBe(2);\n expect(EventPluginRegistry.registrationNames.onClick).toBe(OnePlugin);\n expect(EventPluginRegistry.registrationNames.onFocus).toBe(OnePlugin);\n\n EventPluginRegistry.injectEventPluginsByName({two: TwoPlugin});\n\n expect(EventPluginRegistry.registrationNamesKeys.length).toBe(4);\n expect(EventPluginRegistry.registrationNames.onMagicBubble).toBe(TwoPlugin);\n expect(\n EventPluginRegistry.registrationNames.onMagicCapture\n ).toBe(TwoPlugin);\n });\n\n it('should throw if multiple registration names collide', function() {\n var OnePlugin = createPlugin({\n eventTypes: {\n photoCapture: {registrationName: 'onPhotoCapture'}\n }\n });\n var TwoPlugin = createPlugin({\n eventTypes: {\n photo: {\n phasedRegistrationNames: {\n bubbled: 'onPhotoBubble',\n captured: 'onPhotoCapture'\n }\n }\n }\n });\n\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n two: TwoPlugin\n });\n\n expect(function() {\n EventPluginRegistry.injectEventPluginOrder(['one', 'two']);\n }).toThrow(\n 'Invariant Violation: EventPluginHub: More than one plugin attempted ' +\n 'to publish the same registration name, `onPhotoCapture`.'\n );\n });\n\n it('should throw if an invalid event is published', function() {\n var OnePlugin = createPlugin({\n eventTypes: {\n badEvent: {/* missing configuration */}\n }\n });\n\n EventPluginRegistry.injectEventPluginsByName({one: OnePlugin});\n\n expect(function() {\n EventPluginRegistry.injectEventPluginOrder(['one']);\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Failed to publish event ' +\n '`badEvent` for plugin `one`.'\n );\n });\n\n it('should be able to get the plugin from synthetic events', function() {\n var clickDispatchConfig = {\n registrationName: 'onClick'\n };\n var magicDispatchConfig = {\n phasedRegistrationNames: {\n bubbled: 'onMagicBubble',\n captured: 'onMagicCapture'\n }\n };\n\n var OnePlugin = createPlugin({\n eventTypes: {\n click: clickDispatchConfig,\n magic: magicDispatchConfig\n }\n });\n\n var clickEvent = {dispatchConfig: clickDispatchConfig};\n var magicEvent = {dispatchConfig: magicDispatchConfig};\n\n expect(EventPluginRegistry.getPluginModuleForEvent(clickEvent)).toBe(null);\n expect(EventPluginRegistry.getPluginModuleForEvent(magicEvent)).toBe(null);\n\n EventPluginRegistry.injectEventPluginsByName({one: OnePlugin});\n EventPluginRegistry.injectEventPluginOrder(['one']);\n\n expect(\n EventPluginRegistry.getPluginModuleForEvent(clickEvent)\n ).toBe(OnePlugin);\n expect(\n EventPluginRegistry.getPluginModuleForEvent(magicEvent)\n ).toBe(OnePlugin);\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"event/__tests__/EventPluginRegistry-test\", module);\n", +"event/synthetic/__tests__/SyntheticEvent-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar SyntheticEvent;\n\ndescribe('SyntheticEvent', function() {\n var createEvent;\n\n beforeEach(function() {\n SyntheticEvent = require(\"../../../SyntheticEvent\");\n\n createEvent = function(nativeEvent) {\n return SyntheticEvent.getPooled({}, '', nativeEvent);\n };\n });\n\n it('should normalize `target` from the nativeEvent', function() {\n var target = document.createElement('div');\n var syntheticEvent = createEvent({srcElement: target});\n\n expect(syntheticEvent.target).toBe(target);\n expect(syntheticEvent.type).toBe(undefined);\n });\n\n it('should be able to `preventDefault`', function() {\n var nativeEvent = {};\n var syntheticEvent = createEvent(nativeEvent);\n\n expect(syntheticEvent.isDefaultPrevented()).toBe(false);\n syntheticEvent.preventDefault();\n expect(syntheticEvent.isDefaultPrevented()).toBe(true);\n\n expect(syntheticEvent.defaultPrevented).toBe(true);\n\n expect(nativeEvent.returnValue).toBe(false);\n });\n\n it('should be prevented if nativeEvent is prevented', function() {\n expect(\n createEvent({defaultPrevented: true}).isDefaultPrevented()\n ).toBe(true);\n expect(createEvent({returnValue: false}).isDefaultPrevented()).toBe(true);\n });\n\n it('should be able to `stopPropagation`', function() {\n var nativeEvent = {};\n var syntheticEvent = createEvent(nativeEvent);\n\n expect(syntheticEvent.isPropagationStopped()).toBe(false);\n syntheticEvent.stopPropagation();\n expect(syntheticEvent.isPropagationStopped()).toBe(true);\n\n expect(nativeEvent.cancelBubble).toBe(true);\n });\n\n it('should be able to `persist`', function() {\n var syntheticEvent = createEvent({});\n\n expect(syntheticEvent.isPersistent()).toBe(false);\n syntheticEvent.persist();\n expect(syntheticEvent.isPersistent()).toBe(true);\n });\n\n});\n\nrequire(\"../../../mock-modules\").register(\"event/synthetic/__tests__/SyntheticEvent-test\", module);\n", +"event/synthetic/__tests__/SyntheticWheelEvent-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar SyntheticWheelEvent;\n\ndescribe('SyntheticWheelEvent', function() {\n var createEvent;\n\n beforeEach(function() {\n SyntheticWheelEvent = require(\"../../../SyntheticWheelEvent\");\n\n createEvent = function(nativeEvent) {\n return SyntheticWheelEvent.getPooled({}, '', nativeEvent);\n };\n });\n\n it('should normalize properties from the Event interface', function() {\n var target = document.createElement('div');\n var syntheticEvent = createEvent({srcElement: target});\n\n expect(syntheticEvent.target).toBe(target);\n expect(syntheticEvent.type).toBe(undefined);\n });\n\n it('should normalize properties from the MouseEvent interface', function() {\n expect(createEvent({which: 2, button: 1}).button).toBe(1);\n });\n\n it('should normalize properties from the WheelEvent interface', function() {\n var standardEvent = createEvent({deltaX: 10, deltaY: -50});\n expect(standardEvent.deltaX).toBe(10);\n expect(standardEvent.deltaY).toBe(50);\n\n var webkitEvent = createEvent({wheelDeltaX: -10, wheelDeltaY: 50});\n expect(webkitEvent.deltaX).toBe(10);\n expect(webkitEvent.deltaY).toBe(50);\n });\n\n it('should be able to `preventDefault` and `stopPropagation`', function() {\n var nativeEvent = {};\n var syntheticEvent = createEvent(nativeEvent);\n\n expect(syntheticEvent.isDefaultPrevented()).toBe(false);\n syntheticEvent.preventDefault();\n expect(syntheticEvent.isDefaultPrevented()).toBe(true);\n\n expect(syntheticEvent.isPropagationStopped()).toBe(false);\n syntheticEvent.stopPropagation();\n expect(syntheticEvent.isPropagationStopped()).toBe(true);\n });\n\n it('should be able to `persist`', function() {\n var syntheticEvent = createEvent({});\n\n expect(syntheticEvent.isPersistent()).toBe(false);\n syntheticEvent.persist();\n expect(syntheticEvent.isPersistent()).toBe(true);\n });\n\n});\n\nrequire(\"../../../mock-modules\").register(\"event/synthetic/__tests__/SyntheticWheelEvent-test\", module);\n", +"eventPlugins/__tests__/AnalyticsEventPlugin-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar mocks = require(\"../../mocks\");\n\ndescribe('AnalyticsEventPlugin', function() {\n var AnalyticsEventPluginFactory;\n var EventPluginHub;\n var EventPluginRegistry;\n var React;\n var ReactEventEmitter;\n var ReactTestUtils;\n\n var DefaultEventPluginOrder;\n var EnterLeaveEventPlugin;\n var ChangeEventPlugin;\n var ReactInstanceHandles;\n var SimpleEventPlugin;\n\n beforeEach(function() {\n AnalyticsEventPluginFactory = require(\"../../AnalyticsEventPluginFactory\");\n EventPluginHub = require(\"../../EventPluginHub\");\n EventPluginRegistry = require(\"../../EventPluginRegistry\");\n React = require(\"../../React\");\n ReactEventEmitter = require(\"../../ReactEventEmitter\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n\n EventPluginRegistry._resetEventPlugins();\n\n // Re-inject default events system after resetting.\n DefaultEventPluginOrder = require(\"../../DefaultEventPluginOrder\");\n EnterLeaveEventPlugin = require(\"../../EnterLeaveEventPlugin\");\n ChangeEventPlugin = require(\"../../ChangeEventPlugin\");\n ReactInstanceHandles = require(\"../../ReactInstanceHandles\");\n SimpleEventPlugin = require(\"../../SimpleEventPlugin\");\n\n EventPluginHub.injection.injectEventPluginOrder(DefaultEventPluginOrder);\n EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles);\n\n EventPluginHub.injection.injectEventPluginsByName({\n 'SimpleEventPlugin': SimpleEventPlugin,\n 'EnterLeaveEventPlugin': EnterLeaveEventPlugin,\n 'ChangeEventPlugin': ChangeEventPlugin\n });\n\n ReactEventEmitter.ensureListening(false, document);\n });\n\n it('should count events correctly', function() {\n var numClickEvents = 5;\n var numDoubleClickEvents = 7;\n var TEST_ANALYTICS_ID = 'test_analytics_id';\n var TestValidEvents = React.createClass({displayName: 'TestValidEvents',\n render: function() {\n return (\n React.DOM.div( {ref:\"testDiv\",\n 'data-analytics-id':TEST_ANALYTICS_ID,\n 'data-analytics-events':\"click,doubleClick\"}, \n \" Test \"\n )\n );\n }\n });\n var renderedComponent =\n ReactTestUtils.renderIntoDocument(TestValidEvents(null ));\n\n var cb = mocks.getMockFunction().mockImplementation(\n function(analyticsData) {\n expect(Object.keys(analyticsData).length).toBe(1);\n expect(Object.keys(analyticsData[TEST_ANALYTICS_ID]).length).toBe(2);\n expect(analyticsData[TEST_ANALYTICS_ID].click).toBe(numClickEvents);\n expect(analyticsData[TEST_ANALYTICS_ID].doubleClick).toBe(\n numDoubleClickEvents\n );\n }\n );\n\n EventPluginHub.injection.injectEventPluginsByName({\n AnalyticsEventPlugin:\n AnalyticsEventPluginFactory.createAnalyticsPlugin(cb)\n });\n\n // Simulate some clicks\n for (var i = 0; i < numClickEvents; i++) {\n ReactTestUtils.Simulate.click(renderedComponent.refs.testDiv);\n }\n // Simulate some double clicks\n for (i = 0; i < numDoubleClickEvents; i++) {\n ReactTestUtils.Simulate.doubleClick(renderedComponent.refs.testDiv);\n }\n // Simulate some other events not being tracked for analytics\n ReactTestUtils.Simulate.focus(renderedComponent.refs.testDiv);\n\n window.mockRunTimersOnce();\n expect(cb).toBeCalled();\n });\n\n it('error non no callback', function() {\n expect(function() {\n AnalyticsEventPluginFactory.createAnalyticsPlugin(null);\n }).toThrow();\n });\n\n it('error on invalid analytics events', function() {\n var TestInvalidEvents = React.createClass({displayName: 'TestInvalidEvents',\n render: function() {\n return (\n React.DOM.div( {ref:\"testDiv\",\n 'data-analytics-id':\"test_invalid_events\",\n 'data-analytics-events':\"click,123\"}, \n \" Test \"\n )\n );\n }\n });\n var renderedComponent =\n ReactTestUtils.renderIntoDocument(TestInvalidEvents(null ));\n\n var cb = mocks.getMockFunction();\n\n EventPluginHub.injection.injectEventPluginsByName({\n AnalyticsEventPlugin: AnalyticsEventPluginFactory.createAnalyticsPlugin(\n cb\n )\n });\n\n var error = false;\n try {\n ReactTestUtils.Simulate.click(renderedComponent.refs.testDiv);\n } catch(e) {\n error = true;\n }\n\n expect(error).toBe(true);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"eventPlugins/__tests__/AnalyticsEventPlugin-test\", module);\n", +"eventPlugins/__tests__/ResponderEventPlugin-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar CallbackRegistry;\nvar EventConstants;\nvar EventPropagators;\nvar ReactInstanceHandles;\nvar ResponderEventPlugin;\nvar SyntheticEvent;\n\nvar GRANDPARENT_ID = '.r[0]';\nvar PARENT_ID = '.r[0].0';\nvar CHILD_ID = '.r[0].0.0';\n\nvar topLevelTypes;\nvar responderEventTypes;\nvar spies;\n\nvar DUMMY_NATIVE_EVENT = {};\nvar DUMMY_RENDERED_TARGET = {};\n\nvar onStartShouldSetResponder = function(id, cb, capture) {\n var registrationNames = responderEventTypes\n .startShouldSetResponder\n .phasedRegistrationNames;\n CallbackRegistry.putListener(\n id,\n capture ? registrationNames.captured : registrationNames.bubbled,\n cb\n );\n};\n\nvar onScrollShouldSetResponder = function(id, cb, capture) {\n var registrationNames = responderEventTypes\n .scrollShouldSetResponder\n .phasedRegistrationNames;\n CallbackRegistry.putListener(\n id,\n capture ? registrationNames.captured : registrationNames.bubbled,\n cb\n );\n};\n\nvar onMoveShouldSetResponder = function(id, cb, capture) {\n var registrationNames = responderEventTypes\n .moveShouldSetResponder\n .phasedRegistrationNames;\n CallbackRegistry.putListener(\n id,\n capture ? registrationNames.captured : registrationNames.bubbled,\n cb\n );\n};\n\n\nvar onResponderGrant = function(id, cb) {\n CallbackRegistry.putListener(\n id,\n responderEventTypes.responderGrant.registrationName,\n cb\n );\n};\n\nvar extractForTouchStart = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topTouchStart,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForTouchMove = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topTouchMove,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForTouchEnd = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topTouchEnd,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForMouseDown = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topMouseDown,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForMouseMove = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topMouseMove,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\n\nvar extractForMouseUp = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topMouseUp,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForScroll = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topScroll,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\n\nvar onGrantChild;\nvar onGrantParent;\nvar onGrantGrandParent;\n\n\nvar existsInExtraction = function(extracted, test) {\n if (Array.isArray(extracted)) {\n for (var i = 0; i < extracted.length; i++) {\n if (test(extracted[i])) {\n return true;\n }\n }\n } else if (extracted) {\n return test(extracted);\n }\n return false;\n};\n\n/**\n * Helper validators.\n */\nfunction assertGrantEvent(id, extracted) {\n var test = function(event) {\n return event instanceof SyntheticEvent &&\n event.dispatchConfig === responderEventTypes.responderGrant &&\n event.dispatchMarker === id;\n };\n expect(ResponderEventPlugin.getResponderID()).toBe(id);\n expect(existsInExtraction(extracted, test)).toBe(true);\n}\n\nfunction assertResponderMoveEvent(id, extracted) {\n var test = function(event) {\n return event instanceof SyntheticEvent &&\n event.dispatchConfig === responderEventTypes.responderMove &&\n event.dispatchMarker === id;\n };\n expect(ResponderEventPlugin.getResponderID()).toBe(id);\n expect(existsInExtraction(extracted, test)).toBe(true);\n}\n\nfunction assertTerminateEvent(id, extracted) {\n var test = function(event) {\n return event instanceof SyntheticEvent &&\n event.dispatchConfig === responderEventTypes.responderTerminate &&\n event.dispatchMarker === id;\n };\n expect(ResponderEventPlugin.getResponderID()).not.toBe(id);\n expect(existsInExtraction(extracted, test)).toBe(true);\n}\n\nfunction assertRelease(id, extracted) {\n var test = function(event) {\n return event instanceof SyntheticEvent &&\n event.dispatchConfig === responderEventTypes.responderRelease &&\n event.dispatchMarker === id;\n };\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n expect(existsInExtraction(extracted, test)).toBe(true);\n}\n\n\nfunction assertNothingExtracted(extracted) {\n expect(Array.isArray(extracted)).toBe(false); // No grant events.\n expect(Array.isArray(extracted)).toBeFalsy();\n}\n\n\n/**\n * TODO:\n * - Test that returning false from `responderTerminationRequest` will never\n * cause the responder to be lost.\n * - Automate some of this testing by providing config data - generalize.\n */\n\ndescribe('ResponderEventPlugin', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n\n CallbackRegistry = require(\"../../CallbackRegistry\");\n EventConstants = require(\"../../EventConstants\");\n EventPropagators = require(\"../../EventPropagators\");\n ReactInstanceHandles = require(\"../../ReactInstanceHandles\");\n ResponderEventPlugin = require(\"../../ResponderEventPlugin\");\n SyntheticEvent = require(\"../../SyntheticEvent\");\n EventPropagators.injection.injectInstanceHandle(ReactInstanceHandles);\n\n // dumpCache, in open-source tests, only resets existing mocks. It does not\n // reset module-state though -- so we need to do this explicitly in the test\n // for now. Once that's no longer the case, we can delete this line.\n CallbackRegistry.__purge();\n\n topLevelTypes = EventConstants.topLevelTypes;\n responderEventTypes = ResponderEventPlugin.eventTypes;\n\n spies = {\n onStartShouldSetResponderChild: function() {},\n onStartShouldSetResponderParent: function() {},\n onStartShouldSetResponderParentCapture: function() {},\n onStartShouldSetResponderGrandParent: function() {},\n onMoveShouldSetResponderParent: function() {},\n onScrollShouldSetResponderParent: function() {}\n };\n\n onGrantChild = function() {};\n onGrantParent = function() {};\n onGrantGrandParent = function() {};\n });\n\n it('should not auto-set responder on touch start', function() {\n // Notice we're not registering the startShould* handler.\n var extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n });\n\n it('should not auto-set responder on mouse down', function() {\n // Notice we're not registering the startShould* handler.\n var extracted = extractForMouseDown(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n extractForMouseUp(CHILD_ID); // Let up!\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n\n // Register `onMoveShould*` handler.\n spyOn(spies, 'onMoveShouldSetResponderParent').andReturn(true);\n onMoveShouldSetResponder(PARENT_ID, spies.onMoveShouldSetResponderParent);\n onResponderGrant(PARENT_ID, onGrantParent);\n // Move mouse while not pressing down\n extracted = extractForMouseMove(CHILD_ID);\n assertNothingExtracted(extracted);\n // Not going to call `onMoveShould`* if not touching.\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(0);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n\n // Now try the move extraction again, this time while holding down, and not\n // letting up.\n extracted = extractForMouseDown(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n\n // Now moving can set the responder, if pressing down, even if there is no\n // current responder.\n extracted = extractForMouseMove(CHILD_ID);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(1);\n expect(ResponderEventPlugin.getResponderID()).toBe(PARENT_ID);\n assertGrantEvent(PARENT_ID, extracted);\n\n extractForMouseUp(CHILD_ID);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n });\n\n it('should not extract a grant/release event if double start', function() {\n // Return true - we should become the responder.\n var extracted;\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onResponderGrant(CHILD_ID, onGrantChild);\n\n extracted = extractForTouchStart(CHILD_ID);\n assertGrantEvent(CHILD_ID, extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n\n // Now we do *not* clear out the touch via a simulated touch end. This mocks\n // out an environment that likely will never happen, but could in some odd\n // error state so it's nice to make sure we recover gracefully.\n // extractForTouchEnd(CHILD_ID); // Clear the responder\n extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted();\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(2);\n });\n\n it('should bubble/capture responder on start', function() {\n // Return true - we should become the responder.\n var extracted;\n spyOn(spies, 'onStartShouldSetResponderParent').andReturn(true);\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onStartShouldSetResponder(PARENT_ID, spies.onStartShouldSetResponderParent);\n onResponderGrant(CHILD_ID, onGrantChild);\n onResponderGrant(PARENT_ID, onGrantParent);\n\n // Nothing extracted if no responder.\n extracted = extractForTouchMove(GRANDPARENT_ID);\n assertNothingExtracted(extracted);\n\n extracted = extractForTouchStart(CHILD_ID);\n assertGrantEvent(CHILD_ID, extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(spies.onStartShouldSetResponderParent.callCount).toBe(0);\n\n // Even if moving on the grandparent, the child will receive responder moves\n // (This is even true for mouse interactions - which we should absolutely\n // test)\n extracted = extractForTouchMove(GRANDPARENT_ID);\n assertResponderMoveEvent(CHILD_ID, extracted);\n extracted = extractForTouchMove(CHILD_ID); // Test move on child node too.\n assertResponderMoveEvent(CHILD_ID, extracted);\n\n // Reset the responder - id passed here shouldn't matter:\n // TODO: Test varying the id here.\n extracted = extractForTouchEnd(GRANDPARENT_ID); // Clear the responder\n assertRelease(CHILD_ID, extracted);\n\n // Now make sure the parent requests responder on capture.\n spyOn(spies, 'onStartShouldSetResponderParentCapture').andReturn(true);\n onStartShouldSetResponder(\n PARENT_ID,\n spies.onStartShouldSetResponderParent,\n true // Capture\n );\n onResponderGrant(PARENT_ID, onGrantGrandParent);\n extracted = extractForTouchStart(PARENT_ID);\n expect(ResponderEventPlugin.getResponderID()).toBe(PARENT_ID);\n assertGrantEvent(PARENT_ID, extracted);\n // Now move on various nodes, ensuring that the responder move is emitted to\n // the parent node.\n extracted = extractForTouchMove(GRANDPARENT_ID);\n assertResponderMoveEvent(PARENT_ID, extracted);\n extracted = extractForTouchMove(CHILD_ID); // Test move on child node too.\n assertResponderMoveEvent(PARENT_ID, extracted);\n\n // Reset the responder - id passed here shouldn't matter:\n // TODO: Test varying the id here.\n extracted = extractForTouchEnd(GRANDPARENT_ID); // Clear the responder\n assertRelease(PARENT_ID, extracted);\n\n });\n\n it('should invoke callback to ask if responder is desired', function() {\n // Return true - we should become the responder.\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n\n var extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(ResponderEventPlugin.getResponderID()).toBe(CHILD_ID);\n extractForTouchEnd(CHILD_ID); // Clear the responder\n\n // Now try returning false - we should not become the responder.\n spies.onStartShouldSetResponderChild.andReturn(false);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(2);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n extractForTouchEnd(CHILD_ID);\n expect(ResponderEventPlugin.getResponderID()).toBe(null); // Still null\n\n // Same thing as before but return true from \"shouldSet\".\n spies.onStartShouldSetResponderChild.andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onResponderGrant(CHILD_ID, onGrantChild);\n extracted = extractForTouchStart(CHILD_ID);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(3);\n assertGrantEvent(CHILD_ID, extracted);\n extracted = extractForTouchEnd(CHILD_ID); // Clear the responder\n assertRelease(CHILD_ID, extracted);\n });\n\n it('should give up responder to parent on move iff allowed', function() {\n // Return true - we should become the responder.\n var extracted;\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n spyOn(spies, 'onMoveShouldSetResponderParent').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onMoveShouldSetResponder(PARENT_ID, spies.onMoveShouldSetResponderParent);\n onResponderGrant(CHILD_ID, onGrantChild);\n onResponderGrant(PARENT_ID, onGrantParent);\n\n spies.onStartShouldSetResponderChild.andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n extracted = extractForTouchStart(CHILD_ID);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(0); // none yet\n assertGrantEvent(CHILD_ID, extracted); // Child is the current responder\n\n extracted = extractForTouchMove(CHILD_ID);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(1);\n assertGrantEvent(PARENT_ID, extracted);\n assertTerminateEvent(CHILD_ID, extracted);\n\n extracted = extractForTouchEnd(CHILD_ID); // Clear the responder\n assertRelease(PARENT_ID, extracted);\n });\n\n it('should responder move only on direct responder', function() {\n // Return true - we should become the responder.\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n\n var extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(ResponderEventPlugin.getResponderID()).toBe(CHILD_ID);\n extractForTouchEnd(CHILD_ID); // Clear the responder\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n\n // Now try returning false - we should not become the responder.\n spies.onStartShouldSetResponderChild.andReturn(false);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(2);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n extractForTouchEnd(CHILD_ID); // Clear the responder\n\n // Same thing as before but return true from \"shouldSet\".\n spies.onStartShouldSetResponderChild.andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onResponderGrant(CHILD_ID, onGrantChild);\n extracted = extractForTouchStart(CHILD_ID);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(3);\n assertGrantEvent(CHILD_ID, extracted);\n extracted = extractForTouchEnd(CHILD_ID); // Clear the responder\n assertRelease(CHILD_ID, extracted);\n });\n\n it('should give up responder to parent on scroll iff allowed', function() {\n // Return true - we should become the responder.\n var extracted;\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n spyOn(spies, 'onMoveShouldSetResponderParent').andReturn(false);\n spyOn(spies, 'onScrollShouldSetResponderParent').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onMoveShouldSetResponder(PARENT_ID, spies.onMoveShouldSetResponderParent);\n onScrollShouldSetResponder(\n PARENT_ID,\n spies.onScrollShouldSetResponderParent\n );\n onResponderGrant(CHILD_ID, onGrantChild);\n onResponderGrant(PARENT_ID, onGrantParent);\n\n spies.onStartShouldSetResponderChild.andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n extracted = extractForTouchStart(CHILD_ID);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(0); // none yet\n assertGrantEvent(CHILD_ID, extracted); // Child is the current responder\n\n extracted = extractForTouchMove(CHILD_ID);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(1);\n assertNothingExtracted(extracted);\n\n extracted = extractForScroll(CHILD_ID); // Could have been parent here too.\n expect(spies.onScrollShouldSetResponderParent.callCount).toBe(1);\n assertGrantEvent(PARENT_ID, extracted);\n assertTerminateEvent(CHILD_ID, extracted);\n\n extracted = extractForTouchEnd(CHILD_ID); // Clear the responder\n assertRelease(PARENT_ID, extracted);\n });\n\n\n});\n\nrequire(\"../../mock-modules\").register(\"eventPlugins/__tests__/ResponderEventPlugin-test\", module);\n", +"utils/__tests__/ImmutableObject-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\")\n .dontMock('ImmutableObject');\n\nvar ImmutableObject;\n\n/**\n * To perform performance testing of using `ImmutableObject` vs. not using\n * `ImmutableObject`, such testing must be done with __DEV__ set to false.\n */\ndescribe('ImmutableObject', function() {\n var message;\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n ImmutableObject = require(\"../../ImmutableObject\");\n this.addMatchers({\n /**\n * Equivalent with respect to serialization. Must stringify because\n * constructors are different and other comparison methods will not\n * consider them structurally equal. Probably not useful for use outside\n * of this test module.\n */\n toBeSeriallyEqualTo: function(expected) {\n var actual = this.actual;\n var notText = this.isNot ? \" not\" : \"\";\n this.message = function () {\n return \"Expected \" + JSON.stringify(actual) + notText +\n \" to be serially equal to \" + JSON.stringify(expected);\n };\n\n return JSON.stringify(actual) === JSON.stringify(expected);\n }\n });\n });\n\n /**\n * We are in __DEV__ by default.\n */\n var testDev = function(message, testFunc) {\n it(message, testFunc);\n };\n\n var testProd = function(message, testFunc) {\n // Temporarily enter production mode\n window.true = false;\n it(message, testFunc);\n window.true = true;\n };\n\n var testDevAndProd = function(message, testFunc) {\n testDev(message + ':DEV', testFunc);\n testProd(message + ':PROD', testFunc);\n };\n\n testDev('should be running in DEV', function() {\n expect(window.true).toBe(true);\n });\n\n testDev('should require initial map to be an object', function() {\n expect(function() {\n new ImmutableObject([1,2,3]);\n }).toThrow();\n\n expect(function() {\n new ImmutableObject('asdf');\n }).toThrow();\n\n expect(function() {\n new ImmutableObject({oldField: 'asdf', fieldTwo: null});\n }).not.toThrow();\n });\n\n testDev('should not exceed maximum call stack size with nodes', function() {\n var node = document.createElement('div');\n var object = new ImmutableObject({node: node});\n expect(object.node).toBe(node);\n });\n\n testDevAndProd('should not throw when not mutating directly', function() {\n var io = new ImmutableObject({oldField: 'asdf'});\n expect(function() {\n ImmutableObject.set(io, {newField: null}); // not a mutation!\n }).not.toThrow();\n });\n\n testDev('should prevent shallow field addition when strict', function() {\n if (window.callPhantom) return;\n expect(function() {\n var io = new ImmutableObject({oldField: 'asdf'});\n io.newField = 'this will not work';\n }).toThrow();\n });\n\n testDev('should prevent shallow field mutation when strict', function() {\n if (window.callPhantom) return;\n expect(function() {\n var io = new ImmutableObject({oldField: 'asdf'});\n io.oldField = 'this will not work!';\n }).toThrow();\n });\n\n testDev('should prevent deep field addition when strict', function() {\n if (window.callPhantom) return;\n expect(function() {\n var io =\n new ImmutableObject({shallowField: {deepField: {oldField: null}}});\n io.shallowField.deepField.oldField = 'this will not work!';\n }).toThrow();\n });\n\n testDev('should prevent deep field mutation when strict', function() {\n if (window.callPhantom) return;\n expect(function() {\n var io =\n new ImmutableObject({shallowField: {deepField: {oldField: null}}});\n io.shallowField.deepField.newField = 'this will not work!';\n }).toThrow();\n });\n\n testDevAndProd(\n 'should create object with same structure when set with {}',\n function() {\n var beforeIO =\n new ImmutableObject({shallowField: {deepField: {oldField: null}}});\n var afterIO = ImmutableObject.set(beforeIO, {});\n expect(afterIO).toBeSeriallyEqualTo(beforeIO);\n expect(afterIO).not.toBe(beforeIO);\n }\n );\n\n testDevAndProd(\n 'should create distinct object with shallow field insertion',\n function() {\n var beforeStructure = {\n oldShallowField: {\n deepField: {\n oldField: null\n }\n }\n };\n\n var delta = {\n newShallowField: 'newShallowFieldHere'\n };\n\n var expectedAfterStructure = {\n oldShallowField: {\n deepField: {\n oldField: null\n }\n },\n newShallowField: 'newShallowFieldHere'\n };\n\n var beforeIO = new ImmutableObject(beforeStructure);\n var afterIO = ImmutableObject.set(beforeIO, delta);\n expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);\n expect(afterIO).not.toBe(beforeIO);\n }\n );\n\n testDevAndProd(\n 'should create distinct object with shallow field mutation',\n function() {\n var beforeStructure = {\n oldShallowField: {\n deepField: {\n oldField: null\n }\n }\n };\n\n var delta = {\n oldShallowField: 'this will clobber the old field'\n };\n\n var expectedAfterStructure = {\n oldShallowField: 'this will clobber the old field'\n };\n\n var beforeIO = new ImmutableObject(beforeStructure);\n var afterIO = ImmutableObject.set(beforeIO, delta);\n expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);\n expect(afterIO).not.toBe(beforeIO);\n }\n );\n\n message = 'should create distinct object with deep field insertion';\n testDevAndProd(message, function() {\n var beforeStructure = {\n oldShallowField: {\n deepField: {\n oldField: null\n }\n }\n };\n\n var delta = {\n oldShallowField: {newDeepField: 'hello'}\n };\n\n // ImmutableObject does not yet support deep merging with\n // ImmutableObject.set().\n var expectedAfterStructure = {\n oldShallowField: {newDeepField: 'hello'}\n };\n\n var beforeIO = new ImmutableObject(beforeStructure);\n var afterIO = ImmutableObject.set(beforeIO, delta);\n expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);\n expect(afterIO).not.toBe(beforeIO);\n });\n\n message =\n 'should tolerate arrays at deeper levels and prevent mutation on them';\n testDevAndProd(message, function() {\n if (window.callPhantom) {\n // PhantomJS has a bug with Object.freeze and Arrays.\n // https://github.com/ariya/phantomjs/issues/10817\n return;\n }\n var beforeStructure = {\n shallowField: [1,'second field',3]\n };\n var io = new ImmutableObject(beforeStructure);\n expect(function() {\n io.newField = 'nope!';\n }).toThrow();\n expect(function() {\n io.shallowField[0] = 'nope!';\n }).toThrow();\n expect(io.shallowField[1]).toEqual('second field');\n });\n\n message = 'should provide a setField interface as sugar for set()';\n testDevAndProd(message, function() {\n var beforeIO = new ImmutableObject({initialField: null});\n var afterIO =\n ImmutableObject.setField(beforeIO, 'anotherField', 'anotherValue');\n expect(afterIO).toBeSeriallyEqualTo({\n initialField: null,\n anotherField: 'anotherValue'\n });\n expect(afterIO).not.toBe(beforeIO);\n });\n\n message = 'should recursively create distinct objects when deep copying';\n testDevAndProd(message, function() {\n var beforeIO = new ImmutableObject({\n a: {b: 'b', c: {}, d: 'd', e: new ImmutableObject({f: 'f'}) }\n });\n var afterIO = ImmutableObject.setDeep(beforeIO, {\n a: {b: {}, c: 'C', e: {f: 'F', g: 'G'}, h: 'H'}\n });\n expect(afterIO).toBeSeriallyEqualTo({\n a: {b: {}, c: 'C', d: 'd', e: {f: 'F', g: 'G'}, h: 'H'}\n });\n expect(afterIO).not.toBe(beforeIO);\n expect(afterIO.a).not.toBe(beforeIO.a);\n expect(afterIO.a.e).not.toBe(beforeIO.a.e);\n });\n\n testDevAndProd('should deep copy member immutability', function() {\n var beforeIO = new ImmutableObject({\n a: {b: new ImmutableObject({c: 'c'}), e: {f: 'f'}}\n });\n var afterIO = ImmutableObject.setDeep(beforeIO, {\n a: {b: {d: 'D'}, e: new ImmutableObject({g: 'G'})}\n });\n expect(afterIO).toBeSeriallyEqualTo({\n a: {b: {c: 'c', d: 'D'}, e: {f: 'f', g: 'G'}}\n });\n expect(afterIO instanceof ImmutableObject).toBe(true);\n expect(afterIO.a.b instanceof ImmutableObject).toBe(true);\n expect(afterIO.a.e instanceof ImmutableObject).toBe(true);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/ImmutableObject-test\", module);\n", +"utils/__tests__/OrderedMap-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar OrderedMap;\n\n/**\n * Shared, reusable objects.\n */\nvar hasEmptyStringKey = {\n 'thisKeyIsFine': {data: []},\n '': {thisShouldCauseAFailure: []},\n 'thisKeyIsAlsoFine': {data: []}\n};\n\n/**\n * Used as map/forEach callback.\n */\nvar duplicate = function(itm, key, count) {\n return {\n uniqueID: itm.uniqueID,\n val: itm.val + key + count + this.justToTestScope\n };\n};\n\n// Should not be allowed - because then null/'null' become impossible to\n// distinguish. Every key MUST be a string period!\nvar hasNullAndUndefStringKey = [\n {uniqueID: 'undefined', val: 'thisIsUndefined'},\n {uniqueID: 'null', val: 'thisIsNull'}\n];\nvar hasNullKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: null, data: []}\n];\n\nvar hasObjectKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: {}, data: []}\n];\n\nvar hasArrayKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: [], data: []}\n];\n\n// This should be allowed\nvar hasNullStringKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: 'null', data: []}\n];\n\nvar hasUndefinedKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: undefined, data: []}\n];\n\nvar hasUndefinedStringKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: 'undefined', data: []}\n];\n\nvar hasPositiveNumericKey = [\n {uniqueID: 'notANumber', data: []},\n {uniqueID: '5', data: []},\n {uniqueID: 'notAnotherNumber',data: []}\n];\n\nvar hasZeroStringKey = [\n {uniqueID: 'greg', data: 'grego'},\n {uniqueID: '0', data: '0o'},\n {uniqueID: 'tom', data: 'tomo'}\n];\n\nvar hasZeroNumberKey = [\n {uniqueID: 'greg', data: 'grego'},\n {uniqueID: 0, data: '0o'},\n {uniqueID: 'tom', data: 'tomo'}\n];\n\nvar hasAllNumericStringKeys = [\n {uniqueID: '0', name: 'Gregory'},\n {uniqueID: '2', name: 'James'},\n {uniqueID: '1', name: 'Tom'}\n];\n\nvar hasAllNumericKeys = [\n {uniqueID: 0, name: 'Gregory'},\n {uniqueID: 2, name: 'James'},\n {uniqueID: 1, name: 'Tom'}\n];\n\nvar hasAllValidKeys = [\n {uniqueID: 'keyOne', value: 'valueOne'},\n {uniqueID: 'keyTwo', value: 'valueTwo'}\n];\n\nvar hasDuplicateKeys = [\n {uniqueID: 'keyOne', value: 'valueOne'},\n {uniqueID: 'keyTwo', value: 'valueTwo'},\n {uniqueID: 'keyOne', value: 'valueThree'}\n];\n\nvar idEntities = [\n {uniqueID: 'greg', name: 'Gregory'},\n {uniqueID: 'james', name: 'James'},\n {uniqueID: 'tom', name: 'Tom'}\n];\n\nvar hasEmptyKey = [\n {uniqueID: 'greg', name: 'Gregory'},\n {uniqueID: '', name: 'James'},\n {uniqueID: 'tom', name: 'Tom'}\n];\n\nvar extractUniqueID = function(entity) {\n return entity.uniqueID;\n};\n\ndescribe('OrderedMap', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n OrderedMap = require(\"../../OrderedMap\");\n });\n\n it('should create according to simple object with keys', function() {\n OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);\n // Iterate over and ensure key order.\n });\n\n it('should create from array when providing an identity CB', function() {\n expect(function() {\n OrderedMap.fromArray(idEntities, extractUniqueID);\n }).not.toThrow();\n });\n\n it('should throw if constructing from Array without identity CB', function() {\n OrderedMap.fromArray(idEntities, extractUniqueID);\n // Iterate and ensure key order\n });\n\n it('should not throw when fromArray extracts a numeric key', function() {\n expect(function() {\n OrderedMap.fromArray(hasPositiveNumericKey, extractUniqueID);\n }).not.toThrow();\n\n });\n\n it('should throw when any key is the empty string', function() {\n expect(function() {\n OrderedMap.fromArray(hasEmptyKey, extractUniqueID);\n }).toThrow();\n });\n\n it('should not throw when a key is the string \"undefined\" or \"null\"',\n function() {\n var om = OrderedMap.fromArray(hasNullAndUndefStringKey, extractUniqueID);\n expect(om.length).toBe(2);\n expect(om.indexOfKey('undefined')).toBe(0);\n expect(om.indexOfKey('null')).toBe(1);\n expect(om.keyAfter('undefined')).toBe('null');\n expect(om.keyAfter('null')).toBe(undefined);\n expect(om.keyBefore('undefined')).toBe(undefined);\n expect(om.has('undefined')).toBe(true);\n expect(om.has('null')).toBe(true);\n expect(om.get('undefined').val).toBe('thisIsUndefined');\n expect(om.get('null').val).toBe('thisIsNull');\n });\n\n\n /**\n * Numeric keys are cast to strings.\n */\n it('should not throw when a key is the number zero', function() {\n var om = OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID);\n expect(om.length).toBe(3);\n expect(om.indexOfKey('0')).toBe(1);\n expect(om.indexOfKey(0)).toBe(1);\n });\n\n it('should throw when any key is falsey', function() {\n expect(function() {\n OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasNullKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasUndefinedKey, extractUniqueID);\n }).toThrow();\n });\n\n it('should not throw on string keys \"undefined/null\"', function() {\n expect(function() {\n OrderedMap.fromArray(hasNullStringKey, extractUniqueID);\n }).not.toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasUndefinedStringKey, extractUniqueID);\n }).not.toThrow();\n });\n\n it('should throw on extracting keys that are not strings/nums', function() {\n expect(function() {\n OrderedMap.fromArray(hasObjectKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasArrayKey, extractUniqueID);\n }).toThrow();\n });\n\n it('should throw if instantiating with duplicate key', function() {\n expect(function() {\n OrderedMap.fromArray(hasDuplicateKeys, extractUniqueID);\n }).toThrow();\n });\n\n it('should not throw when a key is the string \"0\"', function() {\n var verifyOM = function(om) {\n expect(om.length).toBe(3);\n expect(om.indexOfKey('greg')).toBe(0);\n expect(om.indexOfKey('0')).toBe(1);\n expect(om.indexOfKey(0)).toBe(1); // Casts on writes and reads.\n expect(om.indexOfKey('tom')).toBe(2);\n expect(om.keyAfter('greg')).toBe('0');\n expect(om.keyAfter('0')).toBe('tom');\n expect(om.keyAfter(0)).toBe('tom');\n expect(om.keyAfter('tom')).toBe(undefined);\n expect(om.keyBefore('greg')).toBe(undefined);\n expect(om.keyBefore(0)).toBe('greg');\n expect(om.keyBefore('0')).toBe('greg');\n expect(om.keyBefore('tom')).toBe('0');\n expect(om.has('undefined')).toBe(false);\n expect(om.has(0)).toBe(true);\n expect(om.has('0')).toBe(true);\n };\n var om = OrderedMap.fromArray(hasZeroStringKey, extractUniqueID);\n verifyOM(om);\n om = OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID);\n verifyOM(om);\n });\n\n it('should throw when getting invalid public key', function() {\n var om = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);\n expect(function() {\n om.has(undefined);\n }).toThrow();\n expect(function() {\n om.get(undefined);\n }).toThrow();\n expect(function() {\n om.has(null);\n }).toThrow();\n expect(function() {\n om.get(null);\n }).toThrow();\n expect(function() {\n om.has('');\n }).toThrow();\n expect(function() {\n om.get('');\n }).toThrow();\n });\n\n it('should throw when any key is falsey', function() {\n expect(function() {\n OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasNullKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasUndefinedKey, extractUniqueID);\n }).toThrow();\n });\n\n\n it('should throw when fromArray is passed crazy args', function() {\n // Test passing another OrderedMap (when it expects a plain object.)\n // This is probably not what you meant to do! We should error.\n var validOM = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);\n expect(function() {\n OrderedMap.fromArray({uniqueID: 'asdf'}, extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray(validOM, extractUniqueID);\n }).toThrow();\n });\n\n it('should throw when fromArray is passed crazy things', function() {\n expect(function() {\n OrderedMap.fromArray(null, extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray('stringgg', extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray(undefined, extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray(new Date(), extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray({}, extractUniqueID);\n }).toThrow();\n\n // Test failure without extractor\n expect(function() {\n OrderedMap.fromArray(idEntities);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray(idEntities, extractUniqueID);\n }).not.toThrow();\n });\n\n // Testing methods that accept other `OrderedMap`s.\n it('should throw when from/merge is passed an non-OrderedMap.', function() {\n // Test passing an array to construction.\n expect(function() {\n OrderedMap.from(idEntities, extractUniqueID);\n }).toThrow();\n\n // Test passing an array to merge.\n expect(function() {\n OrderedMap.fromArray(idEntities, extractUniqueID)\n .merge(idEntities, extractUniqueID);\n }).toThrow();\n\n\n // Test passing a plain object to merge.\n expect(function() {\n OrderedMap.fromArray(\n idEntities,\n extractUniqueID\n ).merge({blah: 'willFail'});\n }).toThrow();\n });\n\n it('should throw when accessing key before/after of non-key', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'first'},\n {uniqueID: 'two'}], extractUniqueID\n );\n expect(function() {\n om.keyBefore('dog');\n }).toThrow();\n expect(function() {\n om.keyAfter('cat');\n }).toThrow();\n expect(function() {\n om.keyAfter(null);\n }).toThrow();\n expect(function() {\n om.keyAfter(undefined);\n }).toThrow();\n });\n\n it('should throw passing invalid/not-present-keys to before/after',\n function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'},\n {uniqueID: 'three', val: 'third'},\n {uniqueID: 'four', val: 'fourth'}\n ], extractUniqueID);\n\n expect(function() {\n om.keyBefore('');\n }).toThrow();\n expect(function() {\n om.keyBefore(null);\n }).toThrow();\n expect(function() {\n om.keyBefore(undefined);\n }).toThrow();\n expect(function() {\n om.keyBefore('notInTheOrderedMap!');\n }).toThrow();\n\n expect(function() {\n om.keyAfter('');\n }).toThrow();\n expect(function() {\n om.keyAfter(null);\n }).toThrow();\n expect(function() {\n om.keyAfter(undefined);\n }).toThrow();\n expect(function() {\n om.keyAfter('notInTheOrderedMap!');\n }).toThrow();\n\n expect(function() {\n om.nthKeyAfter('', 1);\n }).toThrow();\n expect(function() {\n om.nthKeyAfter(null, 1);\n }).toThrow();\n expect(function() {\n om.nthKeyAfter(undefined, 1);\n }).toThrow();\n expect(function() {\n om.nthKeyAfter('notInTheOrderedMap!', 1);\n }).toThrow();\n\n expect(function() {\n om.nthKeyBefore('', 1);\n }).toThrow();\n expect(function() {\n om.nthKeyBefore(null, 1);\n }).toThrow();\n expect(function() {\n om.nthKeyBefore(undefined, 1);\n }).toThrow();\n expect(function() {\n om.nthKeyBefore('notInTheOrderedMap!', 1);\n }).toThrow();\n });\n\n it('should correctly determine the nth key after before', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'},\n {uniqueID: 'three', val: 'third'},\n {uniqueID: 'four', val: 'fourth'}\n ], extractUniqueID);\n expect(om.keyBefore('one')).toBe(undefined); // first key\n expect(om.keyBefore('two')).toBe('one');\n expect(om.keyBefore('three')).toBe('two');\n expect(om.keyBefore('four')).toBe('three');\n\n expect(om.keyAfter('one')).toBe('two'); // first key\n expect(om.keyAfter('two')).toBe('three');\n expect(om.keyAfter('three')).toBe('four');\n expect(om.keyAfter('four')).toBe(undefined);\n\n expect(om.nthKeyBefore('one', 0)).toBe('one'); // first key\n expect(om.nthKeyBefore('one', 1)).toBe(undefined);\n expect(om.nthKeyBefore('one', 2)).toBe(undefined);\n expect(om.nthKeyBefore('two', 0)).toBe('two');\n expect(om.nthKeyBefore('two', 1)).toBe('one');\n expect(om.nthKeyBefore('four', 0)).toBe('four');\n expect(om.nthKeyBefore('four', 1)).toBe('three');\n\n expect(om.nthKeyAfter('one', 0)).toBe('one');\n expect(om.nthKeyAfter('one', 1)).toBe('two');\n expect(om.nthKeyAfter('one', 2)).toBe('three');\n expect(om.nthKeyAfter('two', 0)).toBe('two');\n expect(om.nthKeyAfter('two', 1)).toBe('three');\n expect(om.nthKeyAfter('four', 0)).toBe('four');\n expect(om.nthKeyAfter('four', 1)).toBe(undefined);\n });\n\n it('should compute key indices correctly', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'}\n ], extractUniqueID);\n expect(om.keyAtIndex(0)).toBe('one');\n expect(om.keyAtIndex(1)).toBe('two');\n expect(om.keyAtIndex(2)).toBe(undefined);\n expect(om.indexOfKey('one')).toBe(0);\n expect(om.indexOfKey('two')).toBe(1);\n expect(om.indexOfKey('nope')).toBe(undefined);\n expect(function() {\n om.indexOfKey(null);\n }).toThrow();\n expect(function() {\n om.indexOfKey(undefined);\n }).toThrow();\n expect(function() {\n om.indexOfKey(''); // Empty key is not allowed\n }).toThrow();\n });\n\n it('should compute indices on array that extracted numeric ids', function() {\n var om = OrderedMap.fromArray(hasZeroStringKey, extractUniqueID);\n expect(om.keyAtIndex(0)).toBe('greg');\n expect(om.keyAtIndex(1)).toBe('0');\n expect(om.keyAtIndex(2)).toBe('tom');\n expect(om.indexOfKey('greg')).toBe(0);\n expect(om.indexOfKey('0')).toBe(1);\n expect(om.indexOfKey('tom')).toBe(2);\n\n\n var verifyNumericKeys = function(om) {\n expect(om.keyAtIndex(0)).toBe('0');\n expect(om.keyAtIndex(1)).toBe('2');\n expect(om.keyAtIndex(2)).toBe('1');\n expect(om.indexOfKey('0')).toBe(0);\n expect(om.indexOfKey('2')).toBe(1); // Proove these are not ordered by\n expect(om.indexOfKey('1')).toBe(2); // their keys\n };\n var omStringNumberKeys =\n OrderedMap.fromArray(hasAllNumericStringKeys, extractUniqueID);\n verifyNumericKeys(omStringNumberKeys);\n var omNumericKeys =\n OrderedMap.fromArray(hasAllNumericKeys, extractUniqueID);\n verifyNumericKeys(omNumericKeys);\n });\n\n it('should compute indices on mutually exclusive merge', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'}\n ], extractUniqueID);\n var om2 = OrderedMap.fromArray([\n {uniqueID: 'three', val: 'third'}\n ], extractUniqueID);\n var res = om.merge(om2);\n\n expect(res.length).toBe(3);\n\n expect(res.keyAtIndex(0)).toBe('one');\n expect(res.keyAtIndex(1)).toBe('two');\n expect(res.keyAtIndex(2)).toBe('three');\n expect(res.keyAtIndex(3)).toBe(undefined);\n\n expect(res.indexOfKey('one')).toBe(0);\n expect(res.indexOfKey('two')).toBe(1);\n expect(res.indexOfKey('three')).toBe(2);\n expect(res.indexOfKey('dog')).toBe(undefined);\n\n expect(res.has('one')).toBe(true);\n expect(res.has('two')).toBe(true);\n expect(res.has('three')).toBe(true);\n expect(res.has('dog')).toBe(false);\n\n expect(res.get('one').val).toBe('first');\n expect(res.get('two').val).toBe('second');\n expect(res.get('three').val).toBe('third');\n expect(res.get('dog')).toBe(undefined);\n });\n\n it('should compute indices on intersected merge', function() {\n var oneTwo = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'secondOM1'}\n ], extractUniqueID);\n\n var testOneTwoMergedWithTwoThree = function(res) {\n expect(res.length).toBe(3);\n expect(res.keyAtIndex(0)).toBe('one');\n expect(res.keyAtIndex(1)).toBe('two');\n expect(res.keyAtIndex(2)).toBe('three');\n expect(res.keyAtIndex(3)).toBe(undefined);\n expect(res.indexOfKey('one')).toBe(0);\n expect(res.indexOfKey('two')).toBe(1);\n expect(res.indexOfKey('three')).toBe(2);\n expect(res.indexOfKey('dog')).toBe(undefined);\n expect(res.has('one')).toBe(true);\n expect(res.has('two')).toBe(true);\n expect(res.has('three')).toBe(true);\n expect(res.has('dog')).toBe(false);\n expect(res.get('one').val).toBe('first');\n expect(res.get('two').val).toBe('secondOM2');\n expect(res.get('three').val).toBe('third');\n expect(res.get('dog')).toBe(undefined);\n };\n\n var result =\n oneTwo.merge(OrderedMap.fromArray([\n {uniqueID: 'two', val: 'secondOM2'},\n {uniqueID: 'three', val: 'third'}\n ], extractUniqueID));\n testOneTwoMergedWithTwoThree(result);\n\n // Everything should be exactly as before, since the ordering of `two` was\n // already determined by `om`.\n result = oneTwo.merge(\n OrderedMap.fromArray([\n {uniqueID: 'three', val: 'third'},\n {uniqueID: 'two', val:'secondOM2'}\n ], extractUniqueID)\n );\n testOneTwoMergedWithTwoThree(result);\n\n\n var testTwoThreeMergedWithOneTwo = function(res) {\n expect(res.length).toBe(3);\n expect(res.keyAtIndex(0)).toBe('two');\n expect(res.keyAtIndex(1)).toBe('three');\n expect(res.keyAtIndex(2)).toBe('one');\n expect(res.keyAtIndex(3)).toBe(undefined);\n expect(res.indexOfKey('two')).toBe(0);\n expect(res.indexOfKey('three')).toBe(1);\n expect(res.indexOfKey('one')).toBe(2);\n expect(res.indexOfKey('cat')).toBe(undefined);\n expect(res.has('two')).toBe(true);\n expect(res.has('three')).toBe(true);\n expect(res.has('one')).toBe(true);\n expect(res.has('dog')).toBe(false);\n expect(res.get('one').val).toBe('first');\n expect(res.get('two').val).toBe('secondOM1');\n expect(res.get('three').val).toBe('third');\n expect(res.get('dog')).toBe(undefined);\n };\n result = OrderedMap.fromArray([\n {uniqueID: 'two', val: 'secondOM2'},\n {uniqueID: 'three', val: 'third'}\n ], extractUniqueID).merge(oneTwo);\n testTwoThreeMergedWithOneTwo(result);\n\n });\n\n it('should merge mutually exclusive keys to the end.', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'}\n ], extractUniqueID);\n var om2 = OrderedMap.fromArray([\n {uniqueID: 'three', val: 'first'},\n {uniqueID: 'four', val: 'second'}\n ], extractUniqueID);\n var res = om.merge(om2);\n expect(res.length).toBe(4);\n\n });\n\n it('should map correctly', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ], extractUniqueID);\n var scope = {justToTestScope: 'justTestingScope'};\n var verifyResult = function(omResult) {\n expect(omResult.length).toBe(3);\n expect(omResult.keyAtIndex(0)).toBe('x');\n expect(omResult.keyAtIndex(1)).toBe('y');\n expect(omResult.keyAtIndex(2)).toBe('z');\n expect(omResult.get('x').val).toBe('xxx0justTestingScope');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n expect(omResult.get('z').val).toBe('zzz2justTestingScope');\n };\n var resultOM = om.map(function(itm, key, count) {\n return {\n uniqueID: itm.uniqueID,\n val: itm.val + key + count + this.justToTestScope\n };\n }, scope);\n verifyResult(resultOM);\n\n var resArray = [];\n om.forEach(function(itm, key, count) {\n resArray.push({\n uniqueID: itm.uniqueID,\n val: itm.val + key + count + this.justToTestScope\n });\n }, scope);\n resultOM = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyResult(resultOM);\n });\n\n it('should filter correctly', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ], extractUniqueID);\n var scope = {justToTestScope: 'justTestingScope'};\n\n var filteringCallback = function(item, key, indexInOriginal) {\n expect(this).toBe(scope);\n expect(key === 'x' || key === 'y' || key === 'z').toBe(true);\n if (key === 'x') {\n expect(item.val).toBe('xx');\n expect(indexInOriginal).toBe(0);\n return false;\n } else if (key === 'y') {\n expect(item.val).toBe('yy');\n expect(indexInOriginal).toBe(1);\n return true;\n } else {\n expect(item.val).toBe('zz');\n expect(indexInOriginal).toBe(2);\n return true;\n }\n };\n\n var verifyResult = function(omResult) {\n expect(omResult.length).toBe(2);\n expect(omResult.keyAtIndex(0)).toBe('y');\n expect(omResult.keyAtIndex(1)).toBe('z');\n expect(omResult.has('x')).toBe(false);\n expect(omResult.has('z')).toBe(true);\n expect(omResult.get('z').val).toBe('zz');\n expect(omResult.has('y')).toBe(true);\n expect(omResult.get('y').val).toBe('yy');\n };\n\n var resultOM = om.filter(filteringCallback, scope);\n verifyResult(resultOM);\n });\n\n it('should throw when providing invalid ranges to ranging', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ], extractUniqueID);\n var scope = {justToTestScope: 'justTestingScope'};\n\n expect(function() {\n om.mapRange(duplicate, 0, 3, scope);\n }).not.toThrow();\n expect(function() {\n om.filterRange(duplicate, 0, 3, scope);\n }).not.toThrow();\n expect(function() {\n om.forEachRange(duplicate, 0, 3, scope);\n }).not.toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'x' , 3, scope);\n }).toThrow(\n 'Invariant Violation: mapKeyRange must be given keys ' +\n 'that are present.'\n );\n expect(function() {\n om.forEachKeyRange(duplicate, 'x', 3, scope);\n }).toThrow(\n 'Invariant Violation: forEachKeyRange must be given keys ' +\n 'that are present.'\n );\n\n expect(function() {\n om.mapRange(duplicate, 0, 4, scope);\n }).toThrow();\n expect(function() {\n om.filterRange(duplicate, 0, 4, scope);\n }).toThrow();\n expect(function() {\n om.forEachRange(duplicate, 0, 4, scope);\n }).toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'x', null, scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'x', null, scope);\n }).toThrow();\n\n expect(function() {\n om.mapRange(duplicate, -1, 1, scope);\n }).toThrow();\n expect(function() {\n om.filterRange(duplicate, -1, 1, scope);\n }).toThrow();\n expect(function() {\n om.forEachRange(duplicate, -1, 1, scope);\n }).toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, null, 'y', scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, null, 'y', scope);\n }).toThrow();\n\n expect(function() {\n om.mapRange(duplicate, 0, 0, scope);\n }).not.toThrow();\n expect(function() {\n om.filterRange(duplicate, 0, 0, scope);\n }).not.toThrow();\n expect(function() {\n om.forEachRange(duplicate, 0, 0, scope);\n }).not.toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'x', 'x', scope);\n }).not.toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'x', 'x', scope);\n }).not.toThrow();\n\n expect(function() {\n om.mapRange(duplicate, 0, -1, scope);\n }).toThrow();\n expect(function() {\n om.filterRange(duplicate, 0, -1, scope);\n }).toThrow();\n expect(function() {\n om.forEachRange(duplicate, 0, -1, scope);\n }).toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'x', null, scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'x', null, scope);\n }).toThrow();\n\n expect(function() {\n om.mapRange(duplicate, 2, 1, scope);\n }).not.toThrow();\n expect(function() {\n om.filterRange(duplicate, 2, 1, scope);\n }).not.toThrow();\n expect(function() {\n om.forEachRange(duplicate, 2, 1, scope);\n }).not.toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'z', 'z', scope);\n }).not.toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'z', 'z', scope);\n }).not.toThrow();\n\n expect(function() {\n om.mapRange(duplicate, 2, 2, scope);\n }).toThrow();\n expect(function() {\n om.filterRange(duplicate, 2, 2, scope);\n }).toThrow();\n expect(function() {\n om.forEachRange(duplicate, 2, 2, scope);\n }).toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'z', null, scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'z', null, scope);\n }).toThrow();\n\n // Provide keys in reverse order - should throw.\n expect(function() {\n om.mapKeyRange(duplicate, 'y', 'x', scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'y', 'x', scope);\n }).toThrow();\n });\n\n // TEST length zero map, or keyrange start===end\n\n it('should map range correctly', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ], extractUniqueID);\n var scope = {justToTestScope: 'justTestingScope'};\n var verifyThreeItems = function(omResult) {\n expect(omResult.length).toBe(3);\n expect(omResult.keyAtIndex(0)).toBe('x');\n expect(omResult.keyAtIndex(1)).toBe('y');\n expect(omResult.keyAtIndex(2)).toBe('z');\n expect(omResult.get('x').val).toBe('xxx0justTestingScope');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n expect(omResult.get('z').val).toBe('zzz2justTestingScope');\n };\n var verifyFirstTwoItems = function(omResult) {\n expect(omResult.length).toBe(2);\n expect(omResult.keyAtIndex(0)).toBe('x');\n expect(omResult.keyAtIndex(1)).toBe('y');\n expect(omResult.get('x').val).toBe('xxx0justTestingScope');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n };\n\n var verifyLastTwoItems = function(omResult) {\n expect(omResult.length).toBe(2);\n expect(omResult.keyAtIndex(0)).toBe('y');\n expect(omResult.keyAtIndex(1)).toBe('z');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n expect(omResult.get('z').val).toBe('zzz2justTestingScope');\n };\n\n var verifyMiddleItem = function(omResult) {\n expect(omResult.length).toBe(1);\n expect(omResult.keyAtIndex(0)).toBe('y');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n };\n\n var verifyEmpty = function(omResult) {\n expect(omResult.length).toBe(0);\n };\n\n var omResultThree = om.mapRange(duplicate, 0, 3, scope);\n verifyThreeItems(omResultThree);\n var resArray = [];\n var pushToResArray = function(itm, key, count) {\n resArray.push({\n uniqueID: itm.uniqueID,\n val: itm.val + key + count + this.justToTestScope\n });\n };\n\n om.forEachRange(pushToResArray, 0, 3, scope);\n omResultThree = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyThreeItems(omResultThree);\n\n var omResultFirstTwo = om.mapRange(duplicate, 0, 2, scope);\n verifyFirstTwoItems(omResultFirstTwo);\n resArray = [];\n om.forEachRange(pushToResArray, 0, 2, scope);\n omResultFirstTwo = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyFirstTwoItems(omResultFirstTwo);\n\n var omResultLastTwo = om.mapRange(duplicate, 1, 2, scope);\n verifyLastTwoItems(omResultLastTwo);\n resArray = [];\n om.forEachRange(pushToResArray, 1, 2, scope);\n omResultLastTwo = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyLastTwoItems(omResultLastTwo);\n\n var omResultMiddle = om.mapRange(duplicate, 1, 1, scope);\n verifyMiddleItem(omResultMiddle);\n resArray = [];\n om.forEachRange(pushToResArray, 1, 1, scope);\n omResultMiddle = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyMiddleItem(omResultMiddle);\n\n var omResultNone = om.mapRange(duplicate, 1, 0, scope);\n verifyEmpty(omResultNone);\n });\n\n it('should extract the original array correctly', function() {\n var sourceArray = [\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ];\n var om = OrderedMap.fromArray(sourceArray, extractUniqueID);\n expect(om.toArray()).toEqual(sourceArray);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/OrderedMap-test\", module);\n", +"utils/__tests__/ReactChildren-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n * @jsx React.DOM\n */\n\n\"use strict\";\n\ndescribe('ReactChildren', function() {\n var ReactChildren;\n var React;\n\n beforeEach(function() {\n ReactChildren = require(\"../../ReactChildren\");\n React = require(\"../../React\");\n });\n\n\n it('should support identity for simple', function() {\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return kid;\n });\n\n var simpleKid = React.DOM.span( {key:\"simple\"} );\n\n // First pass children into a component to fully simulate what happens when\n // using structures that arrive from transforms.\n\n var instance = React.DOM.div(null, simpleKid);\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n callback.reset();\n var mappedChildren = ReactChildren.map(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n expect(mappedChildren[Object.keys(mappedChildren)[0]]).toBe(simpleKid);\n });\n\n it('should treat single arrayless child as being in array', function() {\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return kid;\n });\n\n var simpleKid = React.DOM.span(null );\n var instance = React.DOM.div(null, simpleKid);\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n callback.reset();\n var mappedChildren = ReactChildren.map(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n expect(mappedChildren[Object.keys(mappedChildren)[0]]).toBe(simpleKid);\n });\n\n it('should treat single child in array as expected', function() {\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return kid;\n });\n\n var simpleKid = React.DOM.span(null );\n var instance = React.DOM.div(null, [simpleKid]);\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n callback.reset();\n var mappedChildren = ReactChildren.map(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n expect(mappedChildren[Object.keys(mappedChildren)[0]]).toBe(simpleKid);\n });\n\n it('should pass key to returned component', function() {\n var mapFn = function (kid, index) {\n return React.DOM.div(null, kid);\n };\n\n var simpleKid = React.DOM.span( {key:\"simple\"} );\n\n var instance = React.DOM.div(null, simpleKid);\n var mappedChildren = ReactChildren.map(instance.props.children, mapFn);\n\n var mappedKeys = Object.keys(mappedChildren);\n expect(mappedKeys.length).toBe(1);\n expect(mappedChildren[mappedKeys[0]]).not.toBe(simpleKid);\n expect(mappedChildren[mappedKeys[0]].props.children).toBe(simpleKid);\n expect(mappedKeys[0]).toBe('{simple}');\n });\n\n it('should invoke callback with the right context', function() {\n var lastContext;\n var callback = function (kid, index) {\n lastContext = this;\n return this;\n };\n\n var scopeTester = {};\n\n var simpleKid = React.DOM.span( {key:\"simple\"} );\n var instance = React.DOM.div(null, simpleKid);\n ReactChildren.forEach(instance.props.children, callback, scopeTester);\n expect(lastContext).toBe(scopeTester);\n\n var mappedChildren =\n ReactChildren.map(instance.props.children, callback, scopeTester);\n\n var mappedKeys = Object.keys(mappedChildren);\n expect(mappedKeys.length).toBe(1);\n expect(mappedChildren[mappedKeys[0]]).toBe(scopeTester);\n });\n\n it('should be called for each child', function() {\n var zero = React.DOM.div( {key:\"keyZero\"} );\n var one = null;\n var two = React.DOM.div( {key:\"keyTwo\"} );\n var three = null;\n var four = React.DOM.div( {key:\"keyFour\"} );\n\n var zeroMapped = React.DOM.div( {key:\"giraffe\"} ); // Key should be overridden\n var oneMapped = null; // Key should be added even if we don't supply it!\n var twoMapped = React.DOM.div(null ); // Key should be added even if not supplied!\n var threeMapped = React.DOM.span(null ); // Map from null to something.\n var fourMapped = React.DOM.div( {key:\"keyFour\"} );\n\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return index === 0 ? zeroMapped :\n index === 1 ? oneMapped :\n index === 2 ? twoMapped :\n index === 3 ? threeMapped : fourMapped;\n });\n\n var instance = (\n React.DOM.div(null, \n zero,\n one,\n two,\n three,\n four\n )\n );\n\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(zero, 0);\n expect(callback).toHaveBeenCalledWith(one, 1);\n expect(callback).toHaveBeenCalledWith(two, 2);\n expect(callback).toHaveBeenCalledWith(three, 3);\n expect(callback).toHaveBeenCalledWith(four, 4);\n callback.reset();\n\n var mappedChildren =\n ReactChildren.map(instance.props.children, callback);\n var mappedKeys = Object.keys(mappedChildren);\n expect(callback.calls.length).toBe(5);\n expect(mappedKeys.length).toBe(5);\n // Keys default to indices.\n expect(mappedKeys).toEqual(\n ['{keyZero}', '[1]', '{keyTwo}', '[3]', '{keyFour}']\n );\n\n expect(callback).toHaveBeenCalledWith(zero, 0);\n expect(mappedChildren[mappedKeys[0]]).toBe(zeroMapped);\n\n expect(callback).toHaveBeenCalledWith(one, 1);\n expect(mappedChildren[mappedKeys[1]]).toBe(oneMapped);\n\n expect(callback).toHaveBeenCalledWith(two, 2);\n expect(mappedChildren[mappedKeys[2]]).toBe(twoMapped);\n\n expect(callback).toHaveBeenCalledWith(three, 3);\n expect(mappedChildren[mappedKeys[3]]).toBe(threeMapped);\n\n expect(callback).toHaveBeenCalledWith(four, 4);\n expect(mappedChildren[mappedKeys[4]]).toBe(fourMapped);\n });\n\n\n it('should be called for each child in nested structure', function() {\n var zero = React.DOM.div( {key:\"keyZero\"} );\n var one = null;\n var two = React.DOM.div( {key:\"keyTwo\"} );\n var three = null;\n var four = React.DOM.div( {key:\"keyFour\"} );\n var five = React.DOM.div( {key:\"keyFiveCompletelyIgnored\"} );\n // five is placed into a JS object with a key that takes precedence over the\n // component key attribute.\n // Precedence is as follows:\n // 1. JavaScript Object key if in a JavaScript object:\n // 2. If grouped in an Array, the `key` attribute.\n // 3. The array index if in a JavaScript Array.\n\n var zeroMapped = React.DOM.div( {key:\"giraffe\"} ); // Key should be overridden\n var oneMapped = null; // Key should be added even if we don't supply it!\n var twoMapped = React.DOM.div(null ); // Key should be added even if not supplied!\n var threeMapped = React.DOM.span(null ); // Map from null to something.\n var fourMapped = React.DOM.div( {key:\"keyFour\"} );\n var fiveMapped = React.DOM.div(null );\n\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return index === 0 ? zeroMapped :\n index === 1 ? oneMapped :\n index === 2 ? twoMapped :\n index === 3 ? threeMapped :\n index === 4 ? fourMapped : fiveMapped;\n });\n\n var instance = (\n React.DOM.div(null, \n [{\n firstHalfKey: [zero, one, two],\n secondHalfKey: [three, four],\n keyFive: five\n }]\n )\n );\n\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(zero, 0);\n expect(callback).toHaveBeenCalledWith(one, 1);\n expect(callback).toHaveBeenCalledWith(two, 2);\n expect(callback).toHaveBeenCalledWith(three, 3);\n expect(callback).toHaveBeenCalledWith(four, 4);\n expect(callback).toHaveBeenCalledWith(five, 5);\n callback.reset();\n\n var mappedChildren = ReactChildren.map(instance.props.children, callback);\n var mappedKeys = Object.keys(mappedChildren);\n expect(callback.calls.length).toBe(6);\n expect(mappedKeys.length).toBe(6);\n // Keys default to indices.\n expect(mappedKeys).toEqual([\n '[0]{firstHalfKey}{keyZero}',\n '[0]{firstHalfKey}[1]',\n '[0]{firstHalfKey}{keyTwo}',\n '[0]{secondHalfKey}[0]',\n '[0]{secondHalfKey}{keyFour}',\n '[0]{keyFive}'\n ]);\n\n expect(callback).toHaveBeenCalledWith(zero, 0);\n expect(mappedChildren[mappedKeys[0]]).toBe(zeroMapped);\n\n expect(callback).toHaveBeenCalledWith(one, 1);\n expect(mappedChildren[mappedKeys[1]]).toBe(oneMapped);\n\n expect(callback).toHaveBeenCalledWith(two, 2);\n expect(mappedChildren[mappedKeys[2]]).toBe(twoMapped);\n\n expect(callback).toHaveBeenCalledWith(three, 3);\n expect(mappedChildren[mappedKeys[3]]).toBe(threeMapped);\n\n expect(callback).toHaveBeenCalledWith(four, 4);\n expect(mappedChildren[mappedKeys[4]]).toBe(fourMapped);\n\n expect(callback).toHaveBeenCalledWith(five, 5);\n expect(mappedChildren[mappedKeys[5]]).toBe(fiveMapped);\n });\n\n it('should retain key across two mappings', function() {\n var zeroForceKey = React.DOM.div( {key:\"keyZero\"} );\n var oneForceKey = React.DOM.div( {key:\"keyOne\"} );\n\n // Key should be overridden\n var zeroForceKeyMapped = React.DOM.div( {key:\"giraffe\"} );\n // Key should be added even if we don't supply it!\n var oneForceKeyMapped = React.DOM.div(null );\n\n var mapFn = function(kid, index) {\n return index === 0 ? zeroForceKeyMapped : oneForceKeyMapped;\n };\n\n var forcedKeys = (\n React.DOM.div(null, \n zeroForceKey,\n oneForceKey\n )\n );\n\n var expectedForcedKeys = ['{keyZero}', '{keyOne}'];\n var mappedChildrenForcedKeys =\n ReactChildren.map(forcedKeys.props.children, mapFn);\n var mappedForcedKeys = Object.keys(mappedChildrenForcedKeys);\n expect(mappedForcedKeys).toEqual(expectedForcedKeys);\n\n var expectedRemappedForcedKeys = ['{{keyZero}}', '{{keyOne}}'];\n var remappedChildrenForcedKeys =\n ReactChildren.map(mappedChildrenForcedKeys, mapFn);\n expect(\n Object.keys(remappedChildrenForcedKeys)\n ).toEqual(expectedRemappedForcedKeys);\n\n });\n\n it('should not throw if key provided is a dupe with array key', function() {\n var zero = React.DOM.div(null );\n var one = React.DOM.div( {key:\"0\"} );\n\n var mapFn = function() {\n return null;\n };\n\n var instance = (\n React.DOM.div(null, \n zero,\n one\n )\n );\n\n expect(function() {\n ReactChildren.map(instance.props.children, mapFn);\n }).not.toThrow();\n });\n\n it('should throw if key provided is a dupe with explicit key', function() {\n var zero = React.DOM.div( {key:\"something\"});\n var one = React.DOM.div( {key:\"something\"} );\n\n var mapFn = function() {return null;};\n var instance = (\n React.DOM.div(null, zero,one)\n );\n\n expect(function() {\n ReactChildren.map(instance.props.children, mapFn);\n }).toThrow();\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/ReactChildren-test\", module);\n", +"utils/__tests__/Transaction-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar Transaction;\nvar mixInto;\n\nvar INIT_ERRORED = 'initErrored'; // Just a dummy value to check for.\ndescribe('Transaction', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n Transaction = require(\"../../Transaction\");\n mixInto = require(\"../../mixInto\");\n });\n\n /**\n * We should not invoke closers for inits that failed. We should pass init\n * return values to closers when those inits are successful. We should not\n * invoke the actual method when any of the initializers fail.\n */\n it('should invoke closers with/only-with init returns', function() {\n var throwInInit = function() {\n throw new Error('close[0] should receive Transaction.OBSERVED_ERROR');\n };\n\n var performSideEffect;\n var dontPerformThis = function() {\n performSideEffect = 'This should never be set to this';\n };\n\n /**\n * New test Transaction subclass.\n */\n var TestTransaction = function() {\n this.reinitializeTransaction();\n this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else\n this.secondCloseParam = INIT_ERRORED; // WILL be set to something else\n this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else\n };\n mixInto(TestTransaction, Transaction.Mixin);\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n initialize: throwInInit,\n close: function(initResult) {\n this.firstCloseParam = initResult;\n }\n },\n {\n initialize: function() { return 'asdf'; },\n close: function(initResult) {\n this.secondCloseParam = initResult;\n }\n },\n {\n initialize: throwInInit,\n close: function(initResult) {\n this.lastCloseParam = initResult;\n }\n }\n ];\n };\n\n var transaction = new TestTransaction();\n\n expect(function() {\n transaction.perform(dontPerformThis);\n }).toThrow();\n\n expect(performSideEffect).toBe(undefined);\n expect(transaction.firstCloseParam).toBe(INIT_ERRORED);\n expect(transaction.secondCloseParam).toBe('asdf');\n expect(transaction.lastCloseParam).toBe(INIT_ERRORED);\n expect(transaction.isInTransaction()).toBe(false);\n });\n\n it('should invoke closers and wrapped method when inits success', function() {\n\n var performSideEffect;\n /**\n * New test Transaction subclass.\n */\n var TestTransaction = function() {\n this.reinitializeTransaction();\n this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else\n this.secondCloseParam = INIT_ERRORED; // WILL be set to something else\n this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else\n };\n mixInto(TestTransaction, Transaction.Mixin);\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n initialize: function() {\n return 'firstResult';\n },\n close: function(initResult) {\n this.firstCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'secondResult';\n },\n close: function(initResult) {\n this.secondCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'thirdResult';\n },\n close: function(initResult) {\n this.lastCloseParam = initResult;\n }\n }\n ];\n };\n\n var transaction = new TestTransaction();\n\n transaction.perform(function() {\n performSideEffect = 'SIDE_EFFECT';\n });\n\n expect(performSideEffect).toBe('SIDE_EFFECT');\n expect(transaction.firstCloseParam).toBe('firstResult');\n expect(transaction.secondCloseParam).toBe('secondResult');\n expect(transaction.lastCloseParam).toBe('thirdResult');\n expect(transaction.isInTransaction()).toBe(false);\n });\n\n /**\n * When the operation throws, the transaction should throw, but all of the\n * error-free closers should execute gracefully without issue. If a closer\n * throws an error, the transaction should prefer to throw the error\n * encountered earlier in the operation.\n */\n it('should throw when wrapped operation throws', function() {\n\n var performSideEffect;\n /**\n * New test Transaction subclass.\n */\n var TestTransaction = function() {\n this.reinitializeTransaction();\n this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else\n this.secondCloseParam = INIT_ERRORED; // WILL be set to something else\n this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else\n };\n mixInto(TestTransaction, Transaction.Mixin);\n // Now, none of the close/inits throw, but the operation we wrap will throw.\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n initialize: function() {\n return 'firstResult';\n },\n close: function(initResult) {\n this.firstCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'secondResult';\n },\n close: function(initResult) {\n this.secondCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'thirdResult';\n },\n close: function(initResult) {\n this.lastCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'fourthResult';\n },\n close: function(initResult) {\n throw new Error('The transaction should throw a TypeError.');\n }\n }\n ];\n };\n\n var transaction = new TestTransaction();\n\n expect(function() {\n var isTypeError = false;\n try {\n transaction.perform(function() {\n throw new TypeError(\"Thrown in main wrapped operation\");\n });\n } catch (err) {\n isTypeError = (err instanceof TypeError);\n }\n return isTypeError;\n }()).toBe(true);\n\n expect(performSideEffect).toBe(undefined);\n expect(transaction.firstCloseParam).toBe('firstResult');\n expect(transaction.secondCloseParam).toBe('secondResult');\n expect(transaction.lastCloseParam).toBe('thirdResult');\n expect(transaction.isInTransaction()).toBe(false);\n });\n\n it('should throw errors in transaction close', function() {\n var TestTransaction = function() {\n this.reinitializeTransaction();\n };\n mixInto(TestTransaction, Transaction.Mixin);\n var exceptionMsg = 'This exception should throw.';\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n close: function(initResult) {\n throw new Error(exceptionMsg);\n }\n }\n ];\n };\n\n var transaction = new TestTransaction();\n expect(function() {\n transaction.perform(function() {});\n }).toThrow(exceptionMsg);\n });\n\n it('should allow nesting of transactions', function() {\n var performSideEffect;\n var nestedPerformSideEffect;\n /**\n * New test Transaction subclass.\n */\n var TestTransaction = function() {\n this.reinitializeTransaction();\n this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else\n this.secondCloseParam = INIT_ERRORED; // WILL be set to something else\n this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else\n };\n mixInto(TestTransaction, Transaction.Mixin);\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n initialize: function() {\n return 'firstResult';\n },\n close: function(initResult) {\n this.firstCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n this.nestedTransaction = new NestedTransaction();\n },\n close: function() {\n // Test performing a transaction in another transaction's close()\n this.nestedTransaction.perform(function() {\n nestedPerformSideEffect = 'NESTED_SIDE_EFFECT';\n });\n }\n }\n ];\n };\n\n var NestedTransaction = function() {\n this.reinitializeTransaction();\n };\n mixInto(NestedTransaction, Transaction.Mixin);\n NestedTransaction.prototype.getTransactionWrappers = function() {\n return [{\n initialize: function() {\n this.hasInitializedNested = true;\n },\n close: function() {\n this.hasClosedNested = true;\n }\n }];\n };\n\n var transaction = new TestTransaction();\n\n transaction.perform(function() {\n performSideEffect = 'SIDE_EFFECT';\n });\n\n expect(performSideEffect).toBe('SIDE_EFFECT');\n expect(nestedPerformSideEffect).toBe('NESTED_SIDE_EFFECT');\n expect(transaction.firstCloseParam).toBe('firstResult');\n expect(transaction.isInTransaction()).toBe(false);\n expect(transaction.nestedTransaction.hasClosedNested).toBe(true);\n expect(transaction.nestedTransaction.hasInitializedNested).toBe(true);\n expect(transaction.nestedTransaction.isInTransaction()).toBe(false);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/Transaction-test\", module);\n", +"utils/__tests__/escapeTextForBrowser-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\ndescribe('escapeTextForBrowser', function() {\n\n var escapeTextForBrowser = require(\"../../escapeTextForBrowser\");\n\n it('should escape boolean to string', function() {\n expect(escapeTextForBrowser(true)).toBe('true');\n expect(escapeTextForBrowser(false)).toBe('false');\n });\n\n it('should escape object to string', function() {\n var escaped = escapeTextForBrowser({\n toString: function() {\n return 'ponys';\n }\n });\n\n expect(escaped).toBe('ponys');\n });\n\n it('should escape number to string', function() {\n expect(escapeTextForBrowser(42)).toBe('42');\n });\n\n it('should escape string', function() {\n var escaped = escapeTextForBrowser('');\n expect(escaped).not.toContain('<');\n expect(escaped).not.toContain('>');\n expect(escaped).not.toContain('\\'');\n expect(escaped).not.toContain('/');\n expect(escaped).not.toContain('\\\"');\n\n escaped = escapeTextForBrowser('&');\n expect(escaped).toBe('&');\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/escapeTextForBrowser-test\", module);\n", +"utils/__tests__/joinClasses-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\").dontMock('joinClasses');\n\nvar joinClasses = require(\"../../joinClasses\");\n\ndescribe('joinClasses', function() {\n\n it('should return a single className', function() {\n expect(joinClasses('aaa')).toEqual('aaa');\n });\n\n it('should join two classes together', function() {\n var aaa = 'aaa';\n var bbb = 'bbb';\n expect(joinClasses(aaa, bbb)).toEqual('aaa bbb');\n });\n\n it('should join many classes together', function() {\n var aaa = 'aaa';\n var bbb = 'bbb';\n var ccc = 'ccc';\n var ddd = 'ddd';\n var eee = 'eee';\n expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa bbb ccc ddd eee');\n });\n\n it('should omit undefined and empty classes', function() {\n var aaa = 'aaa';\n var bbb;\n var ccc = null;\n var ddd = '';\n var eee = 'eee';\n expect(joinClasses(bbb)).toEqual('');\n expect(joinClasses(bbb, bbb, bbb)).toEqual('');\n expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa eee');\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/joinClasses-test\", module);\n", +"utils/__tests__/keyMirror-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\").dontMock('keyMirror');\n\nvar keyMirror = require(\"../../keyMirror\");\n\ndescribe('keyMirror', function() {\n it('should create an object with values matching keys provided', function() {\n var mirror = keyMirror({\n foo: null,\n bar: true,\n \"baz\": { some: \"object\" },\n qux: undefined\n });\n expect('foo' in mirror).toBe(true);\n expect(mirror.foo).toBe('foo');\n expect('bar' in mirror).toBe(true);\n expect(mirror.bar).toBe('bar');\n expect('baz' in mirror).toBe(true);\n expect(mirror.baz).toBe('baz');\n expect('qux' in mirror).toBe(true);\n expect(mirror.qux).toBe('qux');\n });\n\n it('should not use properties from prototypes', function() {\n function Klass() {\n this.useMeToo = true;\n }\n Klass.prototype.doNotUse = true;\n var instance = new Klass();\n instance.useMe = true;\n\n var mirror = keyMirror(instance);\n\n expect('doNotUse' in mirror).toBe(false);\n expect('useMe' in mirror).toBe(true);\n expect('useMeToo' in mirror).toBe(true);\n });\n\n it('should throw when a non-object argument is used', function() {\n [null, undefined, 0, 7, ['uno'], true, \"string\"].forEach(function(testVal) {\n expect(keyMirror.bind(null, testVal)).toThrow();\n });\n });\n\n it('should work when \"constructor\" is a key', function() {\n var obj = { constructor: true };\n expect(keyMirror.bind(null, obj)).not.toThrow();\n var mirror = keyMirror(obj);\n expect('constructor' in mirror).toBe(true);\n });\n});\n\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/keyMirror-test\", module);\n", +"utils/__tests__/memoizeStringOnly-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\ndescribe('memoizeStringOnly', function() {\n var memoizeStringOnly;\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n memoizeStringOnly = require(\"../../memoizeStringOnly\");\n });\n\n it('should be transparent to callers', function() {\n var callback = function(string) {\n return string;\n };\n var memoized = memoizeStringOnly(callback);\n\n expect(memoized('foo'), callback('foo'));\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/memoizeStringOnly-test\", module);\n", +"utils/__tests__/onlyChild-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n * @jsx React.DOM\n */\n\n\"use strict\";\n\ndescribe('onlyChild', function() {\n\n var React;\n var onlyChild;\n var WrapComponent;\n\n beforeEach(function() {\n React = require(\"../../React\");\n onlyChild = require(\"../../onlyChild\");\n WrapComponent = React.createClass({\n render: function() {\n return (\n React.DOM.div(null, \n onlyChild(this.props.children, this.props.mapFn, this)\n )\n );\n }\n });\n });\n\n it('should fail when passed two children', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n React.DOM.div(null ),\n React.DOM.span(null )\n );\n onlyChild(instance.props.children);\n }).toThrow();\n });\n\n it('should fail when passed nully values', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n null\n );\n onlyChild(instance.props.children);\n }).toThrow();\n\n expect(function() {\n var instance =\n WrapComponent(null, \n undefined\n );\n onlyChild(instance.props.children);\n }).toThrow();\n });\n\n it('should fail when key/value objects', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n {oneThing: React.DOM.span(null )}\n );\n onlyChild(instance.props.children);\n }).toThrow();\n });\n\n\n it('should not fail when passed interpolated single child', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n React.DOM.span(null )\n );\n onlyChild(instance.props.children);\n }).not.toThrow();\n });\n\n\n it('should return the only child', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n React.DOM.span(null )\n );\n onlyChild(instance.props.children);\n }).not.toThrow();\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/onlyChild-test\", module);\n", +"utils/__tests__/mergeFuncs-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\")\n .dontMock('mergeHelpers')\n .dontMock('merge')\n .dontMock('mergeDeep')\n .dontMock('mergeInto')\n .dontMock('mergeDeepInto');\n\nvar mergeHelpers;\nvar merge;\nvar mergeInto;\nvar mergeDeep;\nvar mergeDeepInto;\n\nvar isTerminal;\nvar MAX_MERGE_DEPTH;\n\n/**\n * Simple helper to traverse an object, calling the callback (cb) on every\n * nonTerminal node it finds. It stops once it reaches the maximum depth,\n * because we know that the merge functions shouldn't merge past that depth\n * anyways. If you don't \"stop\" once reaching the MAX_MERGE_DEPTH, there won't\n * be a practical way to traverse circular structures.\n */\nvar traverseUntilLeaves = function(obj, cb, depth) {\n if ((depth || 0) >= MAX_MERGE_DEPTH) {\n return;\n }\n var key;\n if (!isTerminal(obj) && !Array.isArray(obj)) {\n cb(obj);\n for (key in obj) {\n if (!obj.hasOwnProperty(key)) {\n continue;\n }\n traverseUntilLeaves(obj[key], cb, (depth || 0) + 1);\n }\n }\n};\n\n/*\n * Checks that the structure of two merged objects are identical. Checks\n * MAX_LEVEL because we don't want to block other unit tests if I have an\n * infinite loop.\n */\nvar MAX_LEVEL = 50;\nvar structureEquals = function(one, two, levelParam) {\n var level = levelParam || 0;\n var oneKey;\n var twoKey;\n if (level > MAX_LEVEL) {\n throw new Error('structure equals computation explored too many levels');\n }\n if (isTerminal(one) && isTerminal(two)) {\n return one === two;\n } else if (!isTerminal(one) && !isTerminal(two)) {\n var allInOneAreInTwo = true;\n for (oneKey in one) {\n if (!one.hasOwnProperty(oneKey)) {\n continue;\n }\n if (!structureEquals(one[oneKey], two[oneKey], level + 1)) {\n allInOneAreInTwo = false;\n }\n }\n var allInTwoAreInOne = true;\n for (twoKey in two) {\n if (!two.hasOwnProperty(twoKey)) {\n continue;\n }\n if (!structureEquals(two[twoKey], one[twoKey], level + 1)) {\n allInTwoAreInOne = false;\n }\n }\n // Sure, the computations overlap a bit.\n return allInOneAreInTwo && allInTwoAreInOne;\n } else {\n return false;\n }\n};\n\n\nvar makeCircular = function() {\n var obj = {};\n obj.self = obj;\n return obj;\n};\n\n\n\n/**\n * Not a symmetric function. Checks if there are any node references\n * (nonTerminal [non-string, non-null, etc]) that exist in inThis. See\n * sharesOnlyTerminalMemory.\n */\nvar hasNoNodeReferencesIn = function(obj, inThis) {\n traverseUntilLeaves(obj, function(nonTerm) {\n traverseUntilLeaves(inThis, function(inThisNonTerm) {\n if (inThisNonTerm === nonTerm) {\n return false;\n }\n });\n });\n return true;\n};\n\n/**\n * Checks that two objects share no memory references with each other (except\n * possibly at the terminal nodes (such as strings etc)). This is used to test\n * isolation of memory. When certain merge operations occur we need to ensure\n * that we did not leak references across objects.\n */\nvar sharesOnlyTerminalMemory = function(a, b) {\n return hasNoNodeReferencesIn(a, b) && hasNoNodeReferencesIn(b, a);\n};\n\n/**\n * Tests all of the merging functions. You provide it data that describes what\n * a deep merge looks like and what a shallow merge looks like. It will make\n * sure that various input/output contracts are adhered to, in addition to\n * ensuring that various guarantees about side-effects are upheld.\n * The test data must provide functions createOne/createTwo as a means to\n * create test data for objects one/two respsectively - each time these\n * functions must return pristine copies so that we can test for side effects\n * correctly.\n */\nvar testAllMerges = function(testData) {\n var createOne = testData.createOne;\n var createTwo = testData.createTwo;\n var one;\n var two;\n\n /*\n * Test merge()\n */\n one = createOne();\n two = createTwo();\n if (testData.mergeShouldThrow) {\n expect(function() {\n merge(one, two);\n }).toThrow();\n } else {\n var mergeRes = merge(one, two);\n if (testData.shallowResultShouldBe) {\n expect(structureEquals(\n mergeRes,\n testData.shallowResultShouldBe)\n ).toBe(true);\n }\n // Ensure the result is not the exact same object memory reference.\n expect(mergeRes === one).toBe(false);\n }\n\n /*\n * Test mergeInto()\n */\n one = createOne();\n two = createTwo();\n if (testData.mergeIntoShouldThrow) {\n expect(function() {\n mergeInto(one, two);\n }).toThrow();\n } else {\n var mergeIntoRes = mergeInto(one, two);\n if (testData.shallowResultShouldBe) {\n expect(structureEquals(\n one,\n testData.shallowResultShouldBe)\n ).toBe(true);\n }\n /*\n * Ensure it's the exact same object reference\n * TODO: We should ensure that for every object path p in one points to\n * the original object reference in one before the mutation.\n */\n expect(mergeIntoRes === undefined).toBe(true);\n }\n\n /*\n * Test mergeDeep()\n */\n one = createOne();\n two = createTwo();\n if (testData.mergeDeepShouldThrow) {\n expect(function() {\n mergeDeep(one, two, testData.arrayStrategy);\n }).toThrow();\n } else {\n var mergeDeepRes = mergeDeep(one, two, testData.arrayStrategy);\n if (testData.deepResultShouldBe) {\n expect(structureEquals(\n mergeDeepRes,\n testData.deepResultShouldBe)\n ).toBe(true);\n }\n expect(sharesOnlyTerminalMemory(mergeDeepRes, one)).toBe(true);\n expect(sharesOnlyTerminalMemory(mergeDeepRes, two)).toBe(true);\n }\n\n /*\n * Test mergeDeepInto()\n */\n one = createOne();\n two = createTwo();\n if (testData.mergeDeepIntoShouldThrow) {\n expect(function() {\n mergeDeepInto(one, two, testData.arrayStrategy);\n }).toThrow();\n } else {\n var mergeDeepIntoRes = mergeDeepInto(one, two, testData.arrayStrategy);\n expect(mergeDeepIntoRes).toBe(undefined);\n if (testData.deepResultShouldBe) {\n expect(structureEquals(\n one,\n testData.deepResultShouldBe)\n ).toBe(true);\n }\n expect(mergeDeepIntoRes === undefined).toBe(true);\n expect(sharesOnlyTerminalMemory(one, two)).toBe(true);\n }\n\n};\n\n/**\n * ReactTextWithEntities is not a React component, but rather a helper function\n * that returns an array. You can use that array as a helper function when\n * constructing a structure.\n */\ndescribe('mergeFuncs', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n mergeHelpers = require(\"../../mergeHelpers\");\n merge = require(\"../../merge\");\n mergeInto = require(\"../../mergeInto\");\n mergeDeep = require(\"../../mergeDeep\");\n mergeDeepInto = require(\"../../mergeDeepInto\");\n isTerminal = mergeHelpers.isTerminal;\n MAX_MERGE_DEPTH = mergeHelpers.MAX_MERGE_DEPTH;\n });\n\n var twoLevelsDeep = function() {\n return {\n shallowObject: {\n deepObject: {\n a: 'a',\n b: 'b'\n },\n deepObject2: {\n one: 'one',\n two: 'two'\n }\n }\n };\n };\n\n it('should not throw if first argument is circular', function() {\n testAllMerges({\n createOne: makeCircular,\n createTwo: function() { return {thisOneIsNotCircular: true}; },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: false\n });\n });\n\n it('should throw if second argument is circular', function() {\n testAllMerges({\n createOne: function() { return {thisOneIsNotCircular: true}; },\n createTwo: makeCircular,\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n });\n\n it('should throw if something deep is circular in second param', function() {\n testAllMerges({\n createOne: function() { return {thisOneIsNotCircular: true}; },\n createTwo: function() {\n return {\n deeper: {\n deeper: makeCircular()\n }\n };\n },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n });\n\n it('should throw if something deep is circular in first param', function() {\n testAllMerges({\n createOne: function() {\n return {\n deeper: {\n deeper: makeCircular()\n }\n };\n },\n createTwo: function() { return {thisOneIsNotCircular: true}; },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: false\n });\n });\n\n\n it('should throw exceptions on invalid data/params', function() {\n testAllMerges({\n createOne: function() { return []; },\n createTwo: function() { return {}; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {}; },\n createTwo: function() { return []; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return []; },\n createTwo: function() { return {hasDeepStructure: 'yes'}; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {hasDeepStructure: 'yes'}; },\n createTwo: function() { return []; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {hasDeepStructure: 'yes'}; },\n createTwo: function() { return []; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n /*\n * mergeInto functions do not accept an empty first parameter. There would\n * be nothing to mutate!\n */\n testAllMerges({\n createOne: function() { return null; },\n createTwo: function() { return {field: 'yes'}; },\n mergeIntoShouldThrow: true,\n mergeDeepIntoShouldThrow: true,\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n testAllMerges({\n createOne: function() { return undefined; },\n createTwo: function() { return {field: 'yes'}; },\n mergeIntoShouldThrow: true,\n mergeDeepIntoShouldThrow: true,\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n // Every merge function accepts an empty second parameter.\n testAllMerges({\n createOne: function() { return {field: 'yes'}; },\n createTwo: function() { return null; },\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n testAllMerges({\n createOne: function() { return null; },\n createTwo: function() { return null; },\n deepResultShouldBe: {},\n shallowResultShouldBe: {},\n mergeIntoShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {field: 'yes'}; },\n createTwo: function() { return undefined; },\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n testAllMerges({\n createOne: function() { return 0; },\n createTwo: function() { return {field: 'yes'}; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n /*\n * The fact that the second param is empty shouldn't change that we still\n * error on arrays.\n */\n testAllMerges({\n createOne: function() { return []; },\n createTwo: function() { return undefined; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {field: 'yes'}; },\n createTwo: function() { return null; },\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n });\n\n\n it('should merge very deep objects correctly.',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n shouldBeClobberedByNull: {\n color: 'blue'\n },\n shouldGetTwoFieldsWhenDeepMerge: {\n firstField: { color: 'red' }\n },\n shouldRemainUndefined: undefined,\n shouldRemainFour: 4,\n shouldRemainZero: 0,\n shouldBeClobberedByObj: 0\n };\n },\n createTwo: function() {\n return {\n shouldBeClobberedByNull: null,\n shouldGetTwoFieldsWhenDeepMerge: {\n secondField: { color: 'black' }\n },\n shouldBeClobberedByObj: { thisObj: true }\n };\n },\n shallowResultShouldBe: {\n shouldBeClobberedByNull: null,\n // only gets one field when merged shallowly\n shouldGetTwoFieldsWhenDeepMerge: {\n secondField: { color: 'black' }\n },\n shouldRemainUndefined: undefined,\n shouldRemainFour: 4,\n shouldRemainZero: 0,\n shouldBeClobberedByObj: { thisObj: true }\n },\n deepResultShouldBe: {\n shouldRemainUndefined: undefined,\n shouldRemainFour: 4,\n shouldRemainZero: 0,\n shouldBeClobberedByNull: null,\n shouldGetTwoFieldsWhenDeepMerge: {\n firstField: { color: 'red' },\n secondField: { color: 'black' }\n },\n shouldBeClobberedByObj: { thisObj: true }\n }\n });\n }\n );\n\n it(\n 'should not throw with one non-colliding arrays with no arrayStrategy',\n function() {\n testAllMerges({\n createOne: function() { return { hasDeepStructure: 'yes' }; },\n createTwo: function() { return { hasArrayDeeper: [] }; },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false,\n shallowResultShouldBe: {\n hasDeepStructure: 'yes',\n hasArrayDeeper: []\n },\n deepResultShouldBe: {\n hasDeepStructure: 'yes',\n hasArrayDeeper: []\n }\n });\n }\n );\n\n it(\n 'should not throw with two non-colliding arrays with no arrayStrategy',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n arrayOne: [1]\n };\n },\n createTwo: function() {\n return {\n arrayTwo: [2]\n };\n },\n arrayStrategy: mergeHelpers.ArrayStrategies.Clobber,\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n });\n }\n ),\n\n it('should throw if no arrayStrategy supplied on Array merges', function() {\n testAllMerges({\n createOne: function() {\n return {\n arrayOne: [1]\n };\n },\n createTwo: function() {\n return {\n arrayOne: [9]\n };\n },\n shallowResultShouldBe: {\n arrayOne: [9]\n },\n // Doesn't throw on the shallow versions.\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n }),\n\n it('should not throw if never forced to merge two Arrays', function() {\n testAllMerges({\n createOne: function() {\n return {\n arrayOne: [1]\n };\n },\n createTwo: function() {\n return {\n arrayTwo: [9] // <-- See, never forced to merge with arrayOne\n };\n },\n shallowResultShouldBe: {\n arrayOne: [1],\n arrayTwo: [9]\n },\n // Doesn't throw on the shallow versions.\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n });\n }),\n\n it(\n 'should correctly deep merge Arrays with arrayStrategy clobber',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n deep: {\n array: [1],\n nonArray: {\n hi: 'hi'\n }\n }\n };\n },\n createTwo: function() {\n return {\n deep: {\n array: [10,11, {deepFieldInArray: 'yes'}],\n nonArray: {\n bye: 'bye'\n }\n }\n };\n },\n shallowResultShouldBe: {\n deep: {\n array: [10,11, {deepFieldInArray: 'yes'}],\n nonArray: {\n bye: 'bye'\n }\n }\n },\n deepResultShouldBe: {\n deep: {\n array: [10,11, {deepFieldInArray: 'yes'}],\n nonArray: {\n hi: 'hi',\n bye: 'bye'\n }\n }\n },\n arrayStrategy: mergeHelpers.ArrayStrategies.Clobber,\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n });\n }\n ),\n\n\n it(\n 'should correctly deep merge Arrays with arrayStrategy indexByIndex',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n deep: {\n array: [{\n atIndexZero: {\n indexZeroGreeting: 'You Are At Index Zero',\n indexZeroStatus: false\n }\n }]\n }\n };\n },\n createTwo: function() {\n return {\n deep: {\n array: [{\n atIndexZero: {\n indexZeroStatus: true,\n newFieldAtIndexZero: 'newField'\n }\n },\n {\n atIndexOne: {\n nothingOriginallyAtThisIndex: true\n }\n }]\n }\n };\n },\n shallowResultShouldBe: {\n deep: {\n array: [{\n atIndexZero: {\n indexZeroStatus: true,\n newFieldAtIndexZero: 'newField'\n }\n },\n {\n atIndexOne: {\n nothingOriginallyAtThisIndex: true\n }\n }]\n }\n },\n deepResultShouldBe: {\n deep: {\n array: [{\n atIndexZero: {\n indexZeroGreeting: 'You Are At Index Zero', // <-- See!?\n indexZeroStatus: true,\n newFieldAtIndexZero: 'newField'\n }\n },\n {\n atIndexOne: {\n nothingOriginallyAtThisIndex: true\n }\n }]\n }\n },\n arrayStrategy: mergeHelpers.ArrayStrategies.IndexByIndex,\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n }\n );\n }),\n\n it('should merge deep data correctly', function() {\n var mergeData = {\n shallowObject: {\n deepObject: {\n c: 'c',\n d: 'd'\n },\n deepObject2: {\n three: 'three',\n four: 'four'\n }\n }\n };\n var deepResult = {\n shallowObject: {\n deepObject: {\n a: 'a',\n b: 'b',\n c: 'c',\n d: 'd'\n },\n deepObject2: {\n one: 'one',\n two: 'two',\n three: 'three',\n four: 'four'\n }\n }\n };\n var shallowResult = mergeData; // The same\n\n testAllMerges({\n createOne: function() { return twoLevelsDeep(); },\n createTwo: function() { return mergeData; },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false,\n deepResultShouldBe: deepResult,\n shallowResultShouldBe: shallowResult\n });\n });\n\n it('should fill in complementing regions of data trees', function() {\n var mergeData = {\n shallowObject: {\n newDepth: {\n hello: 'goodbye'\n }\n }\n };\n var deepResult = {\n shallowObject: {\n deepObject: {\n a: 'a',\n b: 'b'\n },\n deepObject2: {\n one: 'one',\n two: 'two'\n },\n // This is added!\n newDepth: {\n hello: 'goodbye'\n }\n }\n };\n var shallowResult = mergeData; // The same\n\n testAllMerges({\n createOne: function() { return twoLevelsDeep(); },\n createTwo: function() { return mergeData; },\n // The deep merge of the two\n deepResultShouldBe: deepResult,\n shallowResultShouldBe: shallowResult\n });\n });\n\n /**\n * Arrays and Objects wipe out terminals (and vice versa).\n */\n it('should clobber terminals with objects/arrays vice versa', function() {\n var makeOne = function() {\n return {\n thisFieldDoesNothing: {},\n deep: {\n // Objects\n thisShouldSwitchFromObjectToTerminal: {hello: 'goodbye'},\n thisShouldSwitchFromTerminalToObject: 'yes',\n\n // Arrays\n thisShouldSwitchFromArrayToTerminal: ['goodbye'],\n thisShouldSwitchFromTerminalToArray: 'yes'\n }\n };\n };\n var makeTwo = function() {\n return {\n deep: {\n // Objects\n thisShouldSwitchFromObjectToTerminal: 'terminal',\n thisShouldSwitchFromTerminalToObject: {nowItsAnObject: 'yay'},\n\n // Arrays\n thisShouldSwitchFromArrayToTerminal: 'terminal',\n thisShouldSwitchFromTerminalToArray: ['yay']\n }\n };\n };\n var deepResult = {\n thisFieldDoesNothing: {\n\n },\n deep: {\n // Objects\n thisShouldSwitchFromObjectToTerminal: 'terminal',\n thisShouldSwitchFromTerminalToObject: {nowItsAnObject: 'yay'},\n\n // Arrays\n thisShouldSwitchFromArrayToTerminal: 'terminal',\n thisShouldSwitchFromTerminalToArray: ['yay']\n }\n };\n\n testAllMerges({\n createOne: makeOne,\n createTwo: makeTwo,\n deepResultShouldBe: deepResult, // The deep merge of the two\n shallowResultShouldBe: deepResult // The same this time.\n });\n });\n\n /**\n * Arrays wipe out Objects and Objects wipe out Arrays.\n */\n it('should clobber terminals with objects/arrays vice versa', function() {\n var makeOne = function() {\n return {\n thisFieldDoesNothing: {},\n deep: {\n thisShouldSwitchFromObjectToArray: {hello: 'goodbye'},\n thisShouldSwitchFromArrayToObject: [1,2,3]\n }\n };\n };\n var makeTwo = function() {\n return {\n deep: {\n thisShouldSwitchFromObjectToArray: [7,8,9],\n thisShouldSwitchFromArrayToObject: {iUsedToBeAnArray:true}\n }\n };\n };\n var deepResult = {\n thisFieldDoesNothing: {},\n deep: {\n thisShouldSwitchFromObjectToArray: [7,8,9],\n thisShouldSwitchFromArrayToObject: {iUsedToBeAnArray:true}\n }\n };\n\n testAllMerges({\n createOne: makeOne,\n createTwo: makeTwo,\n deepResultShouldBe: deepResult, // The deep merge of the two\n shallowResultShouldBe: deepResult // The same this time.\n });\n });\n\n it(\n 'should not clobber terminals/objects/arrays that are not over-written',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n deep: {\n terminal: 'I am a terminal',\n object: {iAmAnObject: true},\n array: [1,2,3]\n }\n };\n },\n createTwo: function() {\n return {\n deep: {\n completelyDifferentField: 'no collision here!'\n }\n };\n },\n shallowResultShouldBe: {\n deep: {\n completelyDifferentField: 'no collision here!'\n }\n },\n deepResultShouldBe: {\n deep: {\n completelyDifferentField: 'no collision here!',\n terminal: 'I am a terminal',\n object: {iAmAnObject: true},\n array: [1,2,3]\n }\n },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n }\n );\n }),\n\n it('should correctly clobber terminals with cloned arrays', function() {\n testAllMerges({\n createOne: function() {\n return {\n deep: {\n changesFromTermToArray: 'I am a terminal'\n }\n };\n },\n createTwo: function() {\n return {\n deep: {\n changesFromTermToArray: ['I', 'am', 'an', 'array']\n }\n };\n },\n shallowResultShouldBe: {\n deep: {\n changesFromTermToArray: ['I', 'am', 'an', 'array']\n }\n },\n deepResultShouldBe: {\n deep: {\n changesFromTermToArray: ['I', 'am', 'an', 'array']\n }\n },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n });\n }),\n\n it('should detect terminals correctly in merge* functions', function() {\n var boolResFalse = isTerminal(false);\n expect(boolResFalse).toBe(true);\n\n var boolResTrue = isTerminal(true);\n expect(boolResTrue).toBe(true);\n\n var numRes = isTerminal(123);\n expect(numRes).toBe(true);\n\n var zeroRes = isTerminal(0);\n expect(zeroRes).toBe(true);\n\n var stringRes = isTerminal('i am a string');\n expect(stringRes).toBe(true);\n\n var objLiteralRes = isTerminal({somethingHere: true});\n expect(objLiteralRes).toBe(false);\n\n var undefRes = isTerminal(undefined);\n expect(undefRes).toBe(true);\n\n var nullRes = isTerminal(null);\n expect(nullRes).toBe(true);\n\n var arrRes = isTerminal([]);\n expect(arrRes).toBe(false);\n });\n});\n\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/mergeFuncs-test\", module);\n", +"utils/__tests__/sliceChildren-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n * @jsx React.DOM\n */\n\n\"use strict\";\n\ndescribe('sliceChildren', function() {\n\n var React;\n var ReactTestUtils;\n\n var sliceChildren;\n var reactComponentExpect;\n\n var Partial;\n\n beforeEach(function() {\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n\n sliceChildren = require(\"../../sliceChildren\");\n reactComponentExpect = require(\"../../reactComponentExpect\");\n\n Partial = React.createClass({\n render: function() {\n return (\n React.DOM.div(null, \n sliceChildren(\n this.props.children,\n this.props.start,\n this.props.end\n )\n )\n );\n }\n });\n });\n\n function renderAndSlice(set, start, end) {\n var instance = Partial( {start:start, end:end}, set);\n ReactTestUtils.renderIntoDocument(instance);\n var rendered = reactComponentExpect(instance)\n .expectRenderedChild()\n .instance();\n return rendered.props.children;\n }\n\n it('should render the whole set if start zero is supplied', function() {\n var fullSet = [\n React.DOM.div( {key:\"A\"} ),\n React.DOM.div( {key:\"B\"} ),\n React.DOM.div( {key:\"C\"} )\n ];\n var children = renderAndSlice(fullSet, 0);\n expect(children).toEqual({\n '{A}': fullSet[0],\n '{B}': fullSet[1],\n '{C}': fullSet[2]\n });\n });\n\n it('should render the remaining set if no end index is supplied', function() {\n var fullSet = [\n React.DOM.div( {key:\"A\"} ),\n React.DOM.div( {key:\"B\"} ),\n React.DOM.div( {key:\"C\"} )\n ];\n var children = renderAndSlice(fullSet, 1);\n expect(children).toEqual({\n '{B}': fullSet[1],\n '{C}': fullSet[2]\n });\n });\n\n it('should exclude everything at or after the end index', function() {\n var fullSet = [\n React.DOM.div( {key:\"A\"} ),\n React.DOM.div( {key:\"B\"} ),\n React.DOM.div( {key:\"C\"} ),\n React.DOM.div( {key:\"D\"} )\n ];\n var children = renderAndSlice(fullSet, 1, 2);\n expect(children).toEqual({\n '{B}': fullSet[1]\n });\n });\n\n it('should allow static children to be sliced', function() {\n var a = React.DOM.div(null );\n var b = React.DOM.div(null );\n var c = React.DOM.div(null );\n\n var instance = Partial( {start:1, end:2}, a,b,c);\n ReactTestUtils.renderIntoDocument(instance);\n var rendered = reactComponentExpect(instance)\n .expectRenderedChild()\n .instance();\n\n expect(rendered.props.children).toEqual({\n '[1]': b\n });\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/sliceChildren-test\", module);\n", +"utils/__tests__/traverseAllChildren-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n * @jsx React.DOM\n */\n\n\"use strict\";\n\ndescribe('traverseAllChildren', function() {\n var traverseAllChildren;\n var React;\n beforeEach(function() {\n traverseAllChildren = require(\"../../traverseAllChildren\");\n React = require(\"../../React\");\n });\n\n\n it('should support identity for simple', function() {\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var simpleKid = React.DOM.span( {key:\"simple\"} );\n\n // Jasmine doesn't provide a way to test that the fn was invoked with scope.\n var instance = React.DOM.div(null, simpleKid);\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n simpleKid,\n '{simple}',\n 0\n );\n expect(traverseContext.length).toEqual(1);\n });\n\n it('should treat single arrayless child as being in array', function() {\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var simpleKid = React.DOM.span(null );\n var instance = React.DOM.div(null, simpleKid);\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n simpleKid,\n '[0]',\n 0\n );\n expect(traverseContext.length).toEqual(1);\n });\n\n it('should treat single child in array as expected', function() {\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var simpleKid = React.DOM.span(null );\n var instance = React.DOM.div(null, [simpleKid]);\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n simpleKid,\n '[0]',\n 0\n );\n expect(traverseContext.length).toEqual(1);\n });\n\n it('should be called for each child', function() {\n var zero = React.DOM.div( {key:\"keyZero\"} );\n var one = null;\n var two = React.DOM.div( {key:\"keyTwo\"} );\n var three = null;\n var four = React.DOM.div( {key:\"keyFour\"} );\n\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var instance = (\n React.DOM.div(null, \n zero,\n one,\n two,\n three,\n four\n )\n );\n\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n zero,\n '{keyZero}',\n 0\n );\n expect(traverseFn).toHaveBeenCalledWith(traverseContext, one, '[1]', 1);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n two,\n '{keyTwo}',\n 2\n );\n expect(traverseFn).toHaveBeenCalledWith(traverseContext, three, '[3]', 3);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n four,\n '{keyFour}',\n 4\n );\n });\n\n // Todo: test that nums/strings are converted to ReactComponents.\n\n it('should be called for each child in nested structure', function() {\n var zero = React.DOM.div( {key:\"keyZero\"} );\n var one = null;\n var two = React.DOM.div( {key:\"keyTwo\"} );\n var three = null;\n var four = React.DOM.div( {key:\"keyFour\"} );\n var five = React.DOM.div( {key:\"keyFiveCompletelyIgnored\"} );\n // Name precedence is as follows:\n // 1. JavaScript Object key if in a JavaScript object:\n // 2. If grouped in an Array, the `key` attribute.\n // 3. The array index if in a JavaScript Array.\n\n\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var instance = (\n React.DOM.div(null, \n [{\n firstHalfKey: [zero, one, two],\n secondHalfKey: [three, four],\n keyFive: five\n }]\n )\n );\n\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn.calls.length).toBe(6);\n expect(traverseContext.length).toEqual(6);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n zero,\n '[0]{firstHalfKey}{keyZero}',\n 0\n );\n\n expect(traverseFn)\n .toHaveBeenCalledWith(traverseContext, one, '[0]{firstHalfKey}[1]', 1);\n\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n two,\n '[0]{firstHalfKey}{keyTwo}',\n 2\n );\n\n expect(traverseFn)\n .toHaveBeenCalledWith(traverseContext, three, '[0]{secondHalfKey}[0]', 3);\n\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n four,\n '[0]{secondHalfKey}{keyFour}',\n 4\n );\n\n expect(traverseFn)\n .toHaveBeenCalledWith(traverseContext, five, '[0]{keyFive}', 5);\n });\n\n it('should retain key across two mappings', function() {\n var zeroForceKey = React.DOM.div( {key:\"keyZero\"} );\n var oneForceKey = React.DOM.div( {key:\"keyOne\"} );\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var forcedKeys = (\n React.DOM.div(null, \n zeroForceKey,\n oneForceKey\n )\n );\n\n traverseAllChildren(forcedKeys.props.children, traverseFn, traverseContext);\n expect(traverseContext.length).toEqual(2);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n zeroForceKey,\n '{keyZero}',\n 0\n );\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n oneForceKey,\n '{keyOne}',\n 1\n );\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/traverseAllChildren-test\", module);\n", +"vendor/error/__tests__/erx-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Copyright 2004-present Facebook. All Rights Reserved.\n *\n * @emails catchen@fb.com\n * @emails javascript@lists.facebook.com\n */\n\nrequire(\"../../../mock-modules\")\n .dontMock('erx')\n .dontMock('ex');\n\ndescribe('erx', function() {\n var erx = require(\"../../../erx\");\n var ex = require(\"../../../ex\");\n\n it('should always reverse ex if placeholder and argument match', function() {\n expect(erx(ex('zero argument'))).toEqual(['zero argument']);\n expect(erx(ex('one argument: %s', 'one')))\n .toEqual(['one argument: %s', 'one']);\n expect(erx(ex('two arguments: %s, %s', 'one', 2)))\n .toEqual(['two arguments: %s, %s', 'one', '2']);\n expect(erx(ex('three arguments: %s, %s, %s', 'one', 2, { value: 3 })))\n .toEqual(['three arguments: %s, %s, %s', 'one', '2', '[object Object]']);\n });\n\n it('should be idempotent', function() {\n var messageWithParams = erx(ex('one argument: %s', 'one'));\n expect(messageWithParams).toEqual(erx(messageWithParams));\n });\n\n it('should treat plain text as it was ex-ed with no argument', function() {\n expect(erx('plain text')).toEqual(['plain text']);\n });\n\n it('should work when text was appended/prepended to ex-ed text', function() {\n expect(erx('prepended text|' + ex('zero argument') + '|appended text'))\n .toEqual(['prepended text|zero argument|appended text']);\n expect(erx(\n 'prepended text|' +\n ex('one argument: %s', 'one') +\n '|appended text'\n )).toEqual(['prepended text|one argument: %s|appended text', 'one']);\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"vendor/error/__tests__/erx-test\", module);\n", +"vendor/error/__tests__/ex-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Copyright 2004-present Facebook. All Rights Reserved.\n *\n * @emails catchen@fb.com\n * @emails javascript@lists.facebook.com\n */\n\nrequire(\"../../../mock-modules\")\n .dontMock('ex');\n\ndescribe('ex', function() {\n var ex = require(\"../../../ex\");\n\n it('should convert whatever arguments into one string', function() {\n expect(typeof ex('zero argument')).toEqual('string');\n expect(typeof ex('one argument: %s', 'one')).toEqual('string');\n expect(typeof ex('two arguments: %s, %s', 'one', 2))\n .toEqual('string');\n expect(typeof ex('three arguments: %s, %s, %s', 'one', 2, { value: 3 }))\n .toEqual('string');\n });\n\n it('should handle placeholder and argument number mismatch', function() {\n expect(typeof ex('zero placeholder and one argument', 'one'))\n .toEqual('string');\n expect(typeof ex('one placeholder and zero argument: %s'))\n .toEqual('string');\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"vendor/error/__tests__/ex-test\", module);\n", +"test/phantomjs-shims":"(function() {\n\nvar Ap = Array.prototype;\nvar slice = Ap.slice;\nvar Fp = Function.prototype;\n\nif (!Fp.bind) {\n // PhantomJS doesn't support Function.prototype.bind natively, so\n // polyfill it whenever this module is required.\n Fp.bind = function(context) {\n var func = this;\n var args = slice.call(arguments, 1);\n\n function bound() {\n var invokedAsConstructor = func.prototype && (this instanceof func);\n return func.apply(\n // Ignore the context parameter when invoking the bound function\n // as a constructor. Note that this includes not only constructor\n // invocations using the new keyword but also calls to base class\n // constructors such as BaseClass.call(this, ...) or super(...).\n !invokedAsConstructor && context || this,\n args.concat(slice.call(arguments))\n );\n }\n\n // The bound function must share the .prototype of the unbound\n // function so that any object created by one constructor will count\n // as an instance of both constructors.\n bound.prototype = func.prototype;\n\n return bound;\n };\n}\n\n})();\n\nrequire(\"../mock-modules\").register(\"test/phantomjs-shims\", module);\n", +"ReactTestUtils":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactTestUtils\n */\n\nvar EventConstants = require(\"./EventConstants\");\nvar React = require(\"./React\");\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactTextComponent = require(\"./ReactTextComponent\");\nvar ReactMount = require(\"./ReactMount\");\n\nvar mergeInto = require(\"./mergeInto\");\n\nvar topLevelTypes = EventConstants.topLevelTypes;\n\nfunction Event(suffix) {}\n\n/**\n * @class ReactTestUtils\n */\n\n/**\n * Todo: Support the entire DOM.scry query syntax. For now, these simple\n * utilities will suffice for testing purposes.\n * @lends ReactTestUtils\n */\nvar ReactTestUtils = {\n renderIntoDocument: function(instance) {\n var div = document.createElement('div');\n document.documentElement.appendChild(div);\n return React.renderComponent(instance, div);\n },\n\n isComponentOfType: function(inst, type) {\n return !!(\n inst &&\n ReactComponent.isValidComponent(inst) &&\n inst.constructor === type.componentConstructor\n );\n },\n\n isDOMComponent: function(inst) {\n return !!(inst &&\n ReactComponent.isValidComponent(inst) &&\n !!inst.tagName);\n },\n\n isCompositeComponent: function(inst) {\n return !!(\n inst &&\n ReactComponent.isValidComponent(inst) &&\n typeof inst.render === 'function' &&\n typeof inst.setState === 'function' &&\n typeof inst.updateComponent === 'function'\n );\n },\n\n isCompositeComponentWithType: function(inst, type) {\n return !!(ReactTestUtils.isCompositeComponent(inst) &&\n (inst.constructor === type.componentConstructor ||\n inst.constructor === type));\n },\n\n isTextComponent: function(inst) {\n return inst instanceof ReactTextComponent;\n },\n\n findAllInRenderedTree: function(inst, test) {\n if (!inst) {\n return [];\n }\n var ret = test(inst) ? [inst] : [];\n if (ReactTestUtils.isDOMComponent(inst)) {\n var renderedChildren = inst._renderedChildren;\n var key;\n for (key in renderedChildren) {\n if (!renderedChildren.hasOwnProperty(key)) {\n continue;\n }\n ret = ret.concat(\n ReactTestUtils.findAllInRenderedTree(renderedChildren[key], test)\n );\n }\n } else if (ReactTestUtils.isCompositeComponent(inst)) {\n ret = ret.concat(\n ReactTestUtils.findAllInRenderedTree(inst._renderedComponent, test)\n );\n }\n return ret;\n },\n\n /**\n * Finds all instance of components in the rendered tree that are DOM\n * components with the class name matching `className`.\n * @return an array of all the matches.\n */\n scryRenderedDOMComponentsWithClass: function(root, className) {\n return ReactTestUtils.findAllInRenderedTree(root, function(inst) {\n var instClassName = inst.props.className;\n return ReactTestUtils.isDOMComponent(inst) && (\n instClassName &&\n (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1\n );\n });\n },\n\n /**\n * Like scryRenderedDOMComponentsWithClass but expects there to be one result,\n * and returns that one result, or throws exception if there is any other\n * number of matches besides one.\n * @return {!ReactDOMComponent} The one match.\n */\n findRenderedDOMComponentWithClass: function(root, className) {\n var all =\n ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className);\n if (all.length !== 1) {\n throw new Error('Did not find exactly one match for class:' + className);\n }\n return all[0];\n },\n\n\n /**\n * Finds all instance of components in the rendered tree that are DOM\n * components with the tag name matching `tagName`.\n * @return an array of all the matches.\n */\n scryRenderedDOMComponentsWithTag: function(root, tagName) {\n return ReactTestUtils.findAllInRenderedTree(root, function(inst) {\n return ReactTestUtils.isDOMComponent(inst) &&\n inst.tagName === tagName.toUpperCase();\n });\n },\n\n /**\n * Like scryRenderedDOMComponentsWithTag but expects there to be one result,\n * and returns that one result, or throws exception if there is any other\n * number of matches besides one.\n * @return {!ReactDOMComponent} The one match.\n */\n findRenderedDOMComponentWithTag: function(root, tagName) {\n var all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName);\n if (all.length !== 1) {\n throw new Error('Did not find exactly one match for tag:' + tagName);\n }\n return all[0];\n },\n\n\n /**\n * Finds all instances of components with type equal to `componentType`.\n * @return an array of all the matches.\n */\n scryRenderedComponentsWithType: function(root, componentType) {\n return ReactTestUtils.findAllInRenderedTree(root, function(inst) {\n return ReactTestUtils.isCompositeComponentWithType(inst, componentType);\n });\n },\n\n /**\n * Same as `scryRenderedComponentsWithType` but expects there to be one result\n * and returns that one result, or throws exception if there is any other\n * number of matches besides one.\n * @return {!ReactComponent} The one match.\n */\n findRenderedComponentWithType: function(root, componentType) {\n var all = ReactTestUtils.scryRenderedComponentsWithType(\n root,\n componentType\n );\n if (all.length !== 1) {\n throw new Error(\n 'Did not find exactly one match for componentType:' + componentType\n );\n }\n return all[0];\n },\n\n /**\n * Simulates a top level event being dispatched from a raw event that occured\n * on and `Element` node.\n * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`\n * @param {!Element} node The dom to simulate an event occurring on.\n * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent.\n */\n simulateEventOnNode: function(topLevelType, node, fakeNativeEvent) {\n var virtualHandler =\n ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(\n topLevelType\n );\n fakeNativeEvent.target = node;\n virtualHandler(fakeNativeEvent);\n },\n\n /**\n * Simulates a top level event being dispatched from a raw event that occured\n * on the `ReactDOMComponent` `comp`.\n * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`.\n * @param comp {!ReactDOMComponent}\n * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent.\n */\n simulateEventOnDOMComponent: function(topLevelType, comp, fakeNativeEvent) {\n var reactRootID = comp._rootNodeID || comp._rootDomId;\n if (!reactRootID) {\n throw new Error('Simulating event on non-rendered component');\n }\n var virtualHandler =\n ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(\n topLevelType\n );\n var node = ReactMount.getNode(reactRootID);\n fakeNativeEvent.target = node;\n /* jsdom is returning nodes without id's - fixing that issue here. */\n ReactMount.setID(node, reactRootID);\n virtualHandler(fakeNativeEvent);\n },\n\n nativeTouchData: function(x, y) {\n return {\n touches: [\n {pageX: x, pageY: y}\n ]\n };\n },\n\n Simulate: null // Will populate\n};\n\n/**\n * Exports:\n *\n * - `ReactTestUtils.Simulate.click(Element/ReactDOMComponent)`\n * - `ReactTestUtils.Simulate.mouseMove(Element/ReactDOMComponent)`\n * - `ReactTestUtils.Simulate.mouseIn/ReactDOMComponent)`\n * - `ReactTestUtils.Simulate.mouseOut(Element/ReactDOMComponent)`\n * - ... (All keys from `EventConstants.topLevelTypes`)\n *\n * Note: Top level event types are a subset of the entire set of handler types\n * (which include a broader set of \"synthetic\" events). For example, onDragDone\n * is a synthetic event. You certainly may write test cases for these event\n * types, but it doesn't make sense to simulate them at this low of a level. In\n * this case, the way you test an `onDragDone` event is by simulating a series\n * of `mouseMove`/ `mouseDown`/`mouseUp` events - Then, a synthetic event of\n * type `onDragDone` will be constructed and dispached through your system\n * automatically.\n */\n\nfunction makeSimulator(eventType) {\n return function(domComponentOrNode, nativeEventData) {\n var fakeNativeEvent = new Event(eventType);\n mergeInto(fakeNativeEvent, nativeEventData);\n if (ReactTestUtils.isDOMComponent(domComponentOrNode)) {\n ReactTestUtils.simulateEventOnDOMComponent(\n eventType,\n domComponentOrNode,\n fakeNativeEvent\n );\n } else if (!!domComponentOrNode.tagName) {\n // Will allow on actual dom nodes.\n ReactTestUtils.simulateEventOnNode(\n eventType,\n domComponentOrNode,\n fakeNativeEvent\n );\n }\n };\n}\n\nReactTestUtils.Simulate = {};\nvar eventType;\nfor (eventType in topLevelTypes) {\n // Event type is stored as 'topClick' - we transform that to 'click'\n var convenienceName = eventType.indexOf('top') === 0 ?\n eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType;\n /**\n * @param {!Element || ReactDOMComponent} domComponentOrNode\n * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent.\n */\n ReactTestUtils.Simulate[convenienceName] = makeSimulator(eventType);\n}\n\nmodule.exports = ReactTestUtils;\n\nrequire(\"./mock-modules\").register(\"ReactTestUtils\", module);\n", +"reactComponentExpect":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule reactComponentExpect\n * @nolint\n */\n\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactTestUtils = require(\"./ReactTestUtils\");\n\nvar mergeInto = require(\"./mergeInto\");\n\nfunction reactComponentExpect(instance) {\n if (instance instanceof reactComponentExpect) {\n return instance;\n }\n\n if (!(this instanceof reactComponentExpect)) {\n return new reactComponentExpect(instance);\n }\n\n this._instance = instance;\n this.toBeValidReactComponent();\n}\n\nmergeInto(reactComponentExpect.prototype, {\n // Getters -------------------------------------------------------------------\n\n /**\n * @instance: Retrieves the backing instance.\n */\n instance: function() {\n return this._instance;\n },\n\n /**\n * There are two types of components in the world.\n * - A component created via React.createClass() - Has a single child\n * subComponent - the return value from the .render() function. This\n * function @subComponent expects that this._instance is component created\n * with React.createClass().\n * - A primitive DOM component - which has many renderedChildren, each of\n * which may have a name that is unique with respect to its siblings. This\n * method will fail if this._instance is a primitive component.\n *\n * TL;DR: An instance may have a subComponent (this._renderedComponent) or\n * renderedChildren, but never both. Neither will actually show up until you\n * render the component (simply instantiating is not enough).\n */\n expectRenderedChild: function() {\n this.toBeCompositeComponent();\n return new reactComponentExpect(this.instance()._renderedComponent);\n },\n\n /**\n * The nth child of a DOMish component instance that is not falsy.\n */\n expectRenderedChildAt: function(childIndex) {\n // Currently only dom components have arrays of children, but that will\n // change soon.\n this.toBeDOMComponent();\n var renderedChildren = this.instance()._renderedChildren || {};\n var nonEmptyCount = 0;\n var name;\n for (name in renderedChildren) {\n if (!renderedChildren.hasOwnProperty(name)) {\n continue;\n }\n if (renderedChildren[name]) {\n if (nonEmptyCount === childIndex) {\n return new reactComponentExpect(renderedChildren[name]);\n }\n nonEmptyCount++;\n }\n }\n throw new Error('Child:' + childIndex + ' is not found');\n },\n\n toBeDOMComponentWithChildCount: function(n) {\n this.toBeDOMComponent();\n expect(this.instance()._renderedChildren).toBeTruthy();\n var len = Object.keys(this.instance()._renderedChildren).length;\n expect(len).toBe(n);\n return this;\n },\n\n toBeDOMComponentWithNoChildren: function() {\n this.toBeDOMComponent();\n expect(this.instance()._renderedChildren).toBeFalsy();\n return this;\n },\n\n // Matchers ------------------------------------------------------------------\n\n toBeComponentOfType: function(convenienceConstructor) {\n expect(ReactTestUtils.isComponentOfType(\n this.instance(),\n convenienceConstructor\n )).toBe(true);\n return this;\n },\n\n /**\n * A component that is created with React.createClass. Just duck typing\n * here.\n */\n toBeCompositeComponent: function() {\n this.toBeValidReactComponent();\n expect(ReactTestUtils.isCompositeComponent(this.instance())).toBe(true);\n return this;\n },\n\n toBeCompositeComponentWithType: function(convenienceConstructor) {\n expect(ReactTestUtils.isCompositeComponentWithType(\n this.instance(),\n convenienceConstructor\n )).toBe(true);\n return this;\n },\n\n toBeTextComponent: function() {\n expect(ReactTestUtils.isTextComponent(this.instance())).toBe(true);\n return this;\n },\n\n /**\n * Falsy values are valid components - the vanished component that is.\n */\n toBeValidReactComponent: function() {\n expect(ReactComponent.isValidComponent(this.instance())).toBe(true);\n return this;\n },\n\n toBePresent: function() {\n expect(this.instance()).toBeTruthy();\n return this;\n },\n\n /**\n * A terminal type of component representing some virtual dom node. Just duck\n * typing here.\n */\n toBeDOMComponent: function() {\n expect(ReactTestUtils.isDOMComponent(this.instance())).toBe(true);\n return this;\n },\n\n /**\n * @deprecated\n * @see toBeComponentOfType\n */\n toBeDOMComponentWithTag: function(tag) {\n this.toBeDOMComponent();\n expect(this.instance().tagName).toBe(tag.toUpperCase());\n return this;\n },\n\n /**\n * Check that internal state values are equal to a state of expected values.\n */\n scalarStateEqual: function(stateNameToExpectedValue) {\n expect(this.instance()).toBeTruthy();\n for (var stateName in stateNameToExpectedValue) {\n if (!stateNameToExpectedValue.hasOwnProperty(stateName)) {\n continue;\n }\n expect(this.instance().state[stateName])\n .toEqual(stateNameToExpectedValue[stateName]);\n }\n return this;\n },\n\n /**\n * Check a set of props are equal to a set of expected values - only works\n * with scalars.\n */\n scalarPropsEqual: function(propNameToExpectedValue) {\n expect(this.instance()).toBeTruthy();\n for (var propName in propNameToExpectedValue) {\n if (!propNameToExpectedValue.hasOwnProperty(propName)) {\n continue;\n }\n expect(this.instance().props[propName])\n .toEqual(propNameToExpectedValue[propName]);\n }\n return this;\n }\n});\n\nmodule.exports = reactComponentExpect;\n\nrequire(\"./mock-modules\").register(\"reactComponentExpect\", module);\n", +"mocks":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule mocks\n */\n\nfunction isA(typeName, value) {\n return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';\n}\n\nfunction getType(ref) {\n if (isA('RegExp', ref)) {\n return 'regexp';\n }\n\n if (isA('Array', ref)) {\n return 'array';\n }\n\n if (isA('Function', ref)) {\n return 'function';\n }\n\n if (isA('Object', ref)) {\n return 'object';\n }\n\n // consider number and string fields to be constants that we want to\n // pick up as they are\n if (isA('Number', ref) || isA('String', ref)) {\n return 'constant';\n }\n\n return null;\n}\n\nfunction makeComponent(metadata) {\n switch (metadata.type) {\n case 'object':\n return {};\n\n case 'array':\n return [];\n\n case 'regexp':\n return new RegExp();\n\n case 'constant':\n return metadata.value;\n\n case 'function':\n var defaultReturnValue;\n var specificReturnValues = [];\n var mockImpl;\n var isReturnValueLastSet = false;\n var calls = [];\n var instances = [];\n var prototype =\n (metadata.members && metadata.members.prototype &&\n metadata.members.prototype.members) || {};\n\n var f = function() {\n global.dirtyMocks.push(f);\n\n instances.push(this);\n calls.push(Array.prototype.slice.call(arguments));\n if (this instanceof arguments.callee) {\n // This is probably being called as a constructor\n for (var slot in prototype) {\n // Copy prototype methods to the instance to make\n // it easier to interact with mock instance call and\n // return values\n if (prototype[slot].type == 'function') {\n var protoImpl = this[slot];\n this[slot] = generateFromMetadata(prototype[slot]);\n this[slot]._protoImpl = protoImpl;\n }\n }\n\n // Run the mock constructor implementation\n mockImpl && mockImpl.apply(this, arguments);\n return;\n }\n\n var returnValue;\n // If return value is last set, either specific or default, i.e.\n // mockReturnValue()/mockDefaultReturnValue() is called and no\n // mockImplementation() is called after that.\n // use the set return value.\n if (isReturnValueLastSet) {\n returnValue = specificReturnValues.shift();\n if (returnValue === undefined) {\n returnValue = defaultReturnValue;\n }\n }\n\n // If mockImplementation() is last set, or specific return values\n // are used up, use the mock implementation.\n if (mockImpl && returnValue === undefined) {\n return mockImpl.apply(this, arguments);\n }\n\n // Otherwise use prototype implementation\n if (returnValue === undefined && arguments.callee._protoImpl) {\n return arguments.callee._protoImpl.apply(this, arguments);\n }\n\n return returnValue;\n };\n\n f._isMockFunction = true;\n\n f.mock = {\n calls : calls,\n instances : instances\n };\n\n f.mockClear = function() {\n calls.length = 0;\n instances.length = 0;\n };\n\n f.mockReturnValue = function(value) {\n // next function call will return this value or default return value\n isReturnValueLastSet = true;\n specificReturnValues.push(value);\n return f;\n };\n\n f.mockDefaultReturnValue = function(value) {\n // next function call will return specified return value or this one\n isReturnValueLastSet = true;\n defaultReturnValue = value;\n return f;\n };\n\n f.mockImplementation = function(fn) {\n // next function call will use mock implementation return value\n isReturnValueLastSet = false;\n mockImpl = fn;\n return f;\n };\n\n f.mockReturnThis = function() {\n return f.mockImplementation(function() {\n return this;\n });\n };\n\n f._getMockImplementation = function() {\n return mockImpl;\n };\n\n if (metadata.mockImpl) {\n f.mockImplementation(metadata.mockImpl);\n }\n\n return f;\n }\n\n throw new Error('Unrecognized type ' + metadata.type);\n}\n\nfunction generateFromMetadata(_metadata) {\n var callbacks = [];\n var refs = {};\n\n function generateMock(metadata) {\n var mock = makeComponent(metadata);\n if (metadata.ref_id != null) {\n refs[metadata.ref_id] = mock;\n }\n\n function getRefCallback(slot, ref) {\n return function() {\n mock[slot] = refs[ref];\n };\n }\n\n for (var slot in metadata.members) {\n var slotMetadata = metadata.members[slot];\n if (slotMetadata.ref != null) {\n callbacks.push(getRefCallback(slot, slotMetadata.ref));\n } else {\n mock[slot] = generateMock(slotMetadata);\n }\n }\n\n return mock;\n }\n\n var mock = generateMock(_metadata);\n callbacks.forEach(function(setter) {\n setter();\n });\n\n return mock;\n}\n\n\nfunction _getMetadata(component, _refs) {\n var refs = _refs || [];\n\n // This is a potential performance drain, since the whole list is scanned\n // for every component\n var ref = refs.indexOf(component);\n if (ref > -1) {\n return {ref: ref};\n }\n\n var type = getType(component);\n if (!type) {\n return null;\n }\n\n var metadata = {type : type};\n if (type == 'constant') {\n metadata.value = component;\n return metadata;\n } else if (type == 'function') {\n if (component._isMockFunction) {\n metadata.mockImpl = component._getMockImplementation();\n }\n }\n\n metadata.ref_id = refs.length;\n refs.push(component);\n\n var members = null;\n\n function addMember(slot, data) {\n if (!data) {\n return;\n }\n if (!members) {\n members = {};\n }\n members[slot] = data;\n }\n\n // Leave arrays alone\n if (type != 'array') {\n for (var slot in component) {\n if (slot.charAt(0) == '_' ||\n (type == 'function' && component._isMockFunction &&\n slot.match(/^mock/))) {\n continue;\n }\n\n if (component.hasOwnProperty(slot) ||\n (type == 'object' && component[slot] != Object.prototype[slot])) {\n addMember(slot, _getMetadata(component[slot], refs));\n }\n }\n\n // If component is native code function, prototype might be undefined\n if (type == 'function' && component.prototype) {\n var prototype = _getMetadata(component.prototype, refs);\n if (prototype && prototype.members) {\n addMember('prototype', prototype);\n }\n }\n }\n\n if (members) {\n metadata.members = members;\n }\n\n return metadata;\n}\n\nfunction removeUnusedRefs(metadata) {\n function visit(md, f) {\n f(md);\n if (md.members) {\n for (var slot in md.members) {\n visit(md.members[slot], f);\n }\n }\n }\n\n var usedRefs = {};\n visit(metadata, function(md) {\n if (md.ref != null) {\n usedRefs[md.ref] = true;\n }\n });\n\n visit(metadata, function(md) {\n if (!usedRefs[md.ref_id]) {\n delete md.ref_id;\n }\n });\n}\n\nvar global = Function(\"return this\")();\nglobal.dirtyMocks = global.dirtyMocks || [];\n\nmodule.exports = {\n /**\n * Invokes the .mockClear method of all function mocks that have been\n * called since the last time clear was called.\n */\n clear: function() {\n var old = global.dirtyMocks;\n global.dirtyMocks = [];\n old.forEach(function(mock) {\n mock.mockClear();\n });\n },\n\n /**\n * Generates a mock based on the given metadata. Mocks treat functions\n * specially, and all mock functions have additional members, described in the\n * documentation for getMockFunction in this module.\n *\n * One important note: function prototoypes are handled specially by this\n * mocking framework. For functions with prototypes, when called as a\n * constructor, the mock will install mocked function members on the instance.\n * This allows different instances of the same constructor to have different\n * values for its mocks member and its return values.\n *\n * @param metadata Metadata for the mock in the schema returned by the\n * getMetadata method of this module.\n *\n */\n generateFromMetadata: generateFromMetadata,\n\n /**\n * Inspects the argument and returns its schema in the following recursive\n * format:\n * {\n * type: ...\n * members : {}\n * }\n *\n * Where type is one of 'array', 'object', 'function', or 'ref', and members\n * is an optional dictionary where the keys are member names and the values\n * are metadata objects. Function prototypes are defined simply by defining\n * metadata for the member.prototype of the function. The type of a function\n * prototype should always be \"object\". For instance, a simple class might be\n * defined like this:\n *\n * {\n * type: 'function',\n * members: {\n * staticMethod: {type: 'function'},\n * prototype: {\n * type: 'object',\n * members: {\n * instanceMethod: {type: 'function'}\n * }\n * }\n * }\n * }\n *\n * Metadata may also contain references to other objects defined within the\n * same metadata object. The metadata for the referent must be marked with\n * 'ref_id' key and an arbitrary value. The referer must be marked with a\n * 'ref' key that has the same value as object with ref_id that it refers to.\n * For instance, this metadata blob:\n * {\n * type: 'object',\n * ref_id: 1,\n * members: {\n * self: {ref: 1}\n * }\n * }\n *\n * defines an object with a slot named 'self' that refers back to the object.\n *\n * @param component The component for which to retrieve metadata.\n */\n getMetadata: function(component) {\n var metadata = _getMetadata(component);\n // to make it easier to work with mock metadata, only preserve references\n // that are actually used\n removeUnusedRefs(metadata);\n return metadata;\n },\n\n /**\n * Generates a stand-alone function with members that help drive unit tests or\n * confirm expectations. Specifically, functions returned by this method have\n * the following members:\n *\n * .mock:\n * An object with two members, \"calls\", and \"instances\", which are both\n * lists. The items in the \"calls\" list are the arguments with which the\n * function was called. The \"instances\" list stores the value of 'this' for\n * each call to the function. This is useful for retrieving instances from a\n * constructor.\n *\n * .mockReturnValue(value)\n * Pushes the given value onto a FIFO queue of return values for the\n * function.\n *\n * .mockDefaultReturnValue(value)\n * Sets the default return value for the function.\n *\n * .mockImplementation(function)\n * Sets a mock implementation for the function.\n *\n * .mockReturnThis()\n * Syntactic sugar for .mockImplementation(function() {return this;})\n *\n * In case both mockImplementation() and\n * mockReturnValue()/mockDefaultReturnValue() are called. The priority of\n * which to use is based on what is the last call:\n * - if the last call is mockRetrunValue() or mockDefaultReturnValue(),\n * use the specific return specific return value or default return value.\n * If specific return values are used up or no default return value is set,\n * fall back to try mockImplementation();\n * - if the last call is mockImplementation(), run the given implementation\n * and return the result.\n */\n getMockFunction: function() {\n return makeComponent({type: 'function'});\n }\n};\n", +"mock-modules":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule mock-modules\n */\n\nvar mocks = require(\"./mocks\");\nvar exportsRegistry = {};\nvar hasOwn = exportsRegistry.hasOwnProperty;\nvar explicitMockMap = {};\n\nfunction getMock(exports) {\n try {\n return mocks.generateFromMetadata(mocks.getMetadata(exports));\n } catch (err) {\n console.warn(err);\n return exports;\n }\n}\n\n// This function should be called at the bottom of any module that might\n// need to be mocked, after the final value of module.exports is known.\nexports.register = function(id, module) {\n exportsRegistry[id] = {\n module: module,\n actual: module.exports,\n mocked: null // Filled in lazily later.\n };\n\n // If doMock or doNotMock was called earlier, before the module was\n // registered, then the choice should have been recorded in\n // explicitMockMap. Now that the module is registered, we can finally\n // fulfill the request.\n if (hasOwn.call(explicitMockMap, id)) {\n if (explicitMockMap[id]) {\n doMock(id);\n } else {\n doNotMock(id);\n }\n }\n\n return exports;\n};\n\nfunction resetEntry(id) {\n if (hasOwn.call(exportsRegistry, id)) {\n delete exportsRegistry[id].module.exports;\n delete exportsRegistry[id];\n }\n}\n\nexports.dumpCache = function() {\n require(\"./mocks\").clear();\n\n // Deleting module.exports will cause the module to be lazily\n // reevaluated the next time it is required.\n for (var id in exportsRegistry) {\n resetEntry(id);\n }\n\n return exports;\n};\n\n// Call this function to ensure that require(id) returns the actual\n// exports object created by the module.\nfunction doNotMock(id) {\n explicitMockMap[id] = false;\n\n var entry = exportsRegistry[id];\n if (entry && entry.module && entry.actual) {\n entry.module.exports = entry.actual;\n }\n\n return exports;\n}\n\n// Call this function to ensure that require(id) returns a mock exports\n// object based on the actual exports object created by the module.\nfunction doMock(id) {\n explicitMockMap[id] = true;\n\n var entry = exportsRegistry[id];\n if (entry && entry.module && entry.actual) {\n // Because mocking can be expensive, create the mock exports object on\n // demand, the first time doMock is called.\n entry.mocked || (entry.mocked = getMock(entry.actual));\n entry.module.exports = entry.mocked;\n }\n\n return exports;\n}\n\nvar global = Function(\"return this\")();\nrequire(\"./test/mock-timers\").installMockTimers(global);\n\n// Exported names are different for backwards compatibility.\nexports.dontMock = doNotMock;\nexports.mock = doMock;\n", +"test/mock-timers":"var mocks = require(\"../mocks\");\n\nvar timers = {};\n// Keep a fake timestamp\n// move on the time when runTimersToTime() is called\nvar now = 0;\n\n// add a timer of type either 'timeout' or 'interval'\nfunction _setTimer(type, callback, delay) {\n var token = null;\n do {\n token = Math.floor(Math.random() * 4294967296) + 1;\n } while (timers[token]);\n timers[token] = {\n type: type,\n callback: callback,\n // Add some random msecs to the delay to mimic code execution time.\n time: now + delay + Math.floor(Math.random() * 5),\n interval: (type == 'interval' ? delay : 0)\n };\n return token;\n}\n\n// clear a timer of type either 'timeout' or 'interval'\nfunction _clearTimer(type, token) {\n if (timers[token] && timers[token].type == type) {\n delete timers[token];\n }\n}\n\nfunction _setTimeout(callback, delay) {\n return _setTimer('timeout', callback, delay);\n}\n\nfunction _setInterval(callback, delay) {\n return _setTimer('interval', callback, delay);\n}\n\nfunction _clearTimeout(token) {\n _clearTimer('timeout', token);\n}\n\nfunction _clearInterval(token) {\n _clearTimer('interval', token);\n}\n\n// Run timer of given token\nfunction _runTimer(token) {\n // Skip non-existing token\n if (timers[token]) {\n if (timers[token].type == 'timeout') {\n // for 'timeout', run callback and delete the timer\n var callback = timers[token].callback;\n delete timers[token];\n callback();\n } else if (timers[token].type == 'interval') {\n // for 'interval', run callback and set the next invoke time\n // Add some random msecs to the delay to mimic code execution time.\n timers[token].time =\n now + timers[token].interval + Math.floor(Math.random() * 5);\n timers[token].callback();\n }\n }\n}\n\nfunction _runTimersOnce() {\n // Invoke all timers once regardsless of the delay\n for (var token in timers) {\n _runTimer(token);\n }\n}\n\nfunction _runTimersToTime(delay) {\n var toRunToken = _getNextTimerToken();\n if (!toRunToken) {\n return;\n }\n\n var minTime = timers[toRunToken].time;\n if (now + delay < minTime) {\n // Termination when there's no more timers to invoke\n now += delay;\n } else {\n // Recursively invoke the next to-run timer\n delay -= (minTime - now);\n now = minTime;\n _runTimer(toRunToken);\n _runTimersToTime(delay);\n }\n}\n\nfunction _runTimersRepeatedly() {\n // Only run a generous 1000 timers and then bail, since we may have entered\n // a loop if we have more than that.\n var max_timers = 1000;\n\n var token;\n for (var ii = 0; ii < max_timers; ii++) {\n token = _getNextTimerToken();\n\n if (!token) {\n break;\n }\n\n _runTimer(token);\n }\n\n if (ii === max_timers) {\n throw new Error(\"More timers still exist after \" + max_timers + \" timers!\");\n }\n}\n\nfunction _clearTimers() {\n for (var token in timers) {\n delete timers[token];\n }\n}\n\nfunction _getNextTimerToken() {\n var nextTimerToken = null;\n var minTime = 31536000000; // One year\n // Find the next to invoke timer\n for (var token in timers) {\n if (timers[token].time < minTime) {\n nextTimerToken = token;\n minTime = timers[token].time;\n }\n }\n return nextTimerToken;\n}\n\nvar mockTimers = {\n setTimeout: _setTimeout,\n clearTimeout: _clearTimeout,\n setInterval: _setInterval,\n clearInterval: _clearInterval,\n\n /**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Iteratively run callbacks in time order during the time from now to\n * now + delay.\n * If one callback register another timer which should be run during now to\n * now + delay, the new timer will also be run in the right order.\n *\n * @param delay\n */\n runTimersToTime: _runTimersToTime,\n\n /**\n * Run all registered timer once. Newly registered timers will not be run.\n */\n runTimersOnce: _runTimersOnce,\n\n /**\n * Iteratively run callbacks until there are no timers left to call. Will\n * stop after a maximum number of iterations to avoid infinite loop.\n *\n * @param maximum iterations (optional)\n */\n runTimersRepeatedly: _runTimersRepeatedly,\n\n /**\n * Clear all timers\n */\n clearTimers: _clearTimers,\n\n /**\n * Get the number of remaining timers\n */\n getTimersCount: function() {\n return Object.keys(timers).length;\n }\n};\n\nmodule.exports.installMockTimers = function(window) {\n window._originalTimeouts = {\n setTimeout: window.setTimeout,\n clearTimeout: window.clearTimeout,\n setInterval: window.setInterval,\n clearInterval: window.clearInterval\n };\n window.setTimeout =\n mocks.getMockFunction().mockImplementation(mockTimers.setTimeout);\n window.clearTimeout =\n mocks.getMockFunction().mockImplementation(mockTimers.clearTimeout);\n window.setInterval =\n mocks.getMockFunction().mockImplementation(mockTimers.setInterval);\n window.clearInterval =\n mocks.getMockFunction().mockImplementation(mockTimers.clearInterval);\n window.mockRunTimersOnce =\n mocks.getMockFunction().mockImplementation(mockTimers.runTimersOnce);\n window.mockRunTimersToTime =\n mocks.getMockFunction().mockImplementation(mockTimers.runTimersToTime);\n window.mockRunTimersRepeatedly =\n mocks.getMockFunction().mockImplementation(mockTimers.runTimersRepeatedly);\n window.mockClearTimers =\n mocks.getMockFunction().mockImplementation(mockTimers.clearTimers);\n window.mockGetTimersCount =\n mocks.getMockFunction().mockImplementation(mockTimers.getTimersCount);\n};\n\nmodule.exports.uninstallMockTimers = function(window) {\n window.setTimeout = window._originalTimeouts.setTimeout;\n window.clearTimeout = window._originalTimeouts.clearTimeout;\n window.setInterval = window._originalTimeouts.setInterval;\n window.clearInterval = window._originalTimeouts.clearInterval;\n window._originalTimeouts = undefined;\n window.mockRunTimersOnce = undefined;\n window.mockRunTimersToTime = undefined;\n window.mockRunTimersRepeatedly = undefined;\n window.mockClearTimers = undefined;\n window.mockGetTimersCount = undefined;\n};\n\nrequire(\"../mock-modules\").register(\"test/mock-timers\", module);\n", +"LinkedStateMixin":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule LinkedStateMixin\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar ReactLink = require(\"./ReactLink\");\nvar ReactStateSetters = require(\"./ReactStateSetters\");\n\n/**\n * A simple mixin around ReactLink.forState().\n */\nvar LinkedStateMixin = {\n /**\n * Create a ReactLink that's linked to part of this component's state. The\n * ReactLink will have the current value of this.state[key] and will call\n * setState() when a change is requested.\n *\n * @param {string} key state key to update. Note: you may want to use keyOf()\n * if you're using Google Closure Compiler advanced mode.\n * @return {ReactLink} ReactLink instance linking to the state.\n */\n linkState: function(key) {\n return new ReactLink(\n this.state[key],\n ReactStateSetters.createStateKeySetter(this, key)\n );\n }\n};\n\nmodule.exports = LinkedStateMixin;\n\nrequire(\"./mock-modules\").register(\"LinkedStateMixin\", module);\n", +"React":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule React\n */\n\n\"use strict\";\n\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactCompositeComponent = require(\"./ReactCompositeComponent\");\nvar ReactCurrentOwner = require(\"./ReactCurrentOwner\");\nvar ReactDOM = require(\"./ReactDOM\");\nvar ReactDOMComponent = require(\"./ReactDOMComponent\");\nvar ReactDefaultInjection = require(\"./ReactDefaultInjection\");\nvar ReactInstanceHandles = require(\"./ReactInstanceHandles\");\nvar ReactMount = require(\"./ReactMount\");\nvar ReactMultiChild = require(\"./ReactMultiChild\");\nvar ReactPerf = require(\"./ReactPerf\");\nvar ReactPropTypes = require(\"./ReactPropTypes\");\nvar ReactServerRendering = require(\"./ReactServerRendering\");\nvar ReactTextComponent = require(\"./ReactTextComponent\");\n\nReactDefaultInjection.inject();\n\nvar React = {\n DOM: ReactDOM,\n PropTypes: ReactPropTypes,\n initializeTouchEvents: function(shouldUseTouch) {\n ReactMount.useTouchEvents = shouldUseTouch;\n },\n createClass: ReactCompositeComponent.createClass,\n constructAndRenderComponent: ReactMount.constructAndRenderComponent,\n constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID,\n renderComponent: ReactPerf.measure(\n 'React',\n 'renderComponent',\n ReactMount.renderComponent\n ),\n renderComponentToString: ReactServerRendering.renderComponentToString,\n unmountComponentAtNode: ReactMount.unmountComponentAtNode,\n unmountAndReleaseReactRootNode: ReactMount.unmountAndReleaseReactRootNode,\n isValidClass: ReactCompositeComponent.isValidClass,\n isValidComponent: ReactComponent.isValidComponent,\n __internals: {\n Component: ReactComponent,\n CurrentOwner: ReactCurrentOwner,\n DOMComponent: ReactDOMComponent,\n InstanceHandles: ReactInstanceHandles,\n Mount: ReactMount,\n MultiChild: ReactMultiChild,\n TextComponent: ReactTextComponent\n }\n};\n\n// Version exists only in the open-source version of React, not in Facebook's\n// internal version.\nReact.version = '0.6.0-alpha';\n\nmodule.exports = React;\n\nrequire(\"./mock-modules\").register(\"React\", module);\n", +"ReactLink":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactLink\n * @typechecks static-only\n */\n\n\"use strict\";\n\n/**\n * ReactLink encapsulates a common pattern in which a component wants to modify\n * a prop received from its parent. ReactLink allows the parent to pass down a\n * value coupled with a callback that, when invoked, expresses an intent to\n * modify that value. For example:\n *\n * React.createClass({\n * getInitialState: function() {\n * return {value: ''};\n * },\n * render: function() {\n * var valueLink = new ReactLink(this.state.value, this._handleValueChange);\n * return ;\n * },\n * this._handleValueChange: function(newValue) {\n * this.setState({value: newValue});\n * }\n * });\n *\n * We have provided some sugary mixins to make the creation and\n * consumption of ReactLink easier; see LinkedValueMixin and LinkedStateMixin.\n */\n\n/**\n * @param {*} value current value of the link\n * @param {function} requestChange callback to request a change\n */\nfunction ReactLink(value, requestChange) {\n this.value = value;\n this.requestChange = requestChange;\n}\n\nmodule.exports = ReactLink;\n\nrequire(\"./mock-modules\").register(\"ReactLink\", module);\n", +"ReactTransitionGroup":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactTransitionGroup\n */\n\n\"use strict\";\n\nvar React = require(\"./React\");\nvar ReactTransitionableChild = require(\"./ReactTransitionableChild\");\nvar ReactTransitionKeySet = require(\"./ReactTransitionKeySet\");\n\nvar invariant = require(\"./invariant\");\n\nvar ReactTransitionGroupMixin = {\n componentWillMount: function() {\n // _transitionGroupCurrentKeys stores the union of previous *and* next keys.\n // If this were a component we'd store it as state, however, since this must\n // be a mixin, we need to keep the result of the union of keys in each\n // call to animateChildren() which happens in render(), so we can't\n // call setState() in there.\n this._transitionGroupCurrentKeys = {};\n },\n\n /**\n * Render some children in a transitionable way.\n */\n renderTransitionableChildren: function(sourceChildren) {\n invariant(\n this.getTransitionConfig,\n 'renderTransitionableChildren(): You must provide a ' +\n 'getTransitionConfig() method.'\n );\n\n var children = {};\n var childMapping = ReactTransitionKeySet.getChildMapping(sourceChildren);\n var transitionConfig = this.getTransitionConfig();\n var currentKeys = ReactTransitionKeySet.mergeKeySets(\n this._transitionGroupCurrentKeys,\n ReactTransitionKeySet.getKeySet(sourceChildren)\n );\n\n for (var key in currentKeys) {\n // Here is how we keep the nodes in the DOM. ReactTransitionableChild\n // knows how to hold onto its child if it changes to undefined. Here, we\n // may look up an old key in the new children, and it may switch to\n // undefined. React's reconciler will keep the ReactTransitionableChild\n // instance alive such that we can animate it.\n if (childMapping[key] || transitionConfig.leave) {\n children[key] = ReactTransitionableChild({\n name: transitionConfig.name,\n enter: transitionConfig.enter,\n onDoneLeaving: this._handleDoneLeaving.bind(this, key)\n }, childMapping[key]);\n }\n }\n\n this._transitionGroupCurrentKeys = currentKeys;\n\n return children;\n },\n\n _handleDoneLeaving: function(key) {\n // When the leave animation finishes, we should blow away the actual DOM\n // node.\n delete this._transitionGroupCurrentKeys[key];\n this.forceUpdate();\n }\n};\n\nvar ReactTransitionGroup = React.createClass({\n mixins: [ReactTransitionGroupMixin],\n\n getDefaultProps: function() {\n return {\n transitionEnter: true,\n transitionLeave: true,\n component: React.DOM.span\n };\n },\n\n getTransitionConfig: function() {\n return {\n name: this.props.transitionName,\n enter: this.props.transitionEnter,\n leave: this.props.transitionLeave\n };\n },\n\n render: function() {\n return this.transferPropsTo(\n this.props.component(\n {\n transitionName: null,\n transitionEnter: null,\n transitionLeave: null,\n component: null\n },\n this.renderTransitionableChildren(this.props.children)\n )\n );\n }\n});\n\nmodule.exports = ReactTransitionGroup;\n\nrequire(\"./mock-modules\").register(\"ReactTransitionGroup\", module);\n", +"ReactTransitionKeySet":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @typechecks static-only\n * @providesModule ReactTransitionKeySet\n */\n\n\"use strict\";\n\nvar ReactChildren = require(\"./ReactChildren\");\n\nvar MERGE_KEY_SETS_TAIL_SENTINEL = {};\n\nvar ReactTransitionKeySet = {\n /**\n * Given `this.props.children`, return an object mapping key to child. Just\n * simple syntactic sugar around ReactChildren.map().\n *\n * @param {*} children `this.props.children`\n * @return {object} Mapping of key to child\n */\n getChildMapping: function(children) {\n return ReactChildren.map(children, function(child) {\n return child;\n });\n },\n\n /**\n * Simple syntactic sugar to get an object with keys of all of `children`.\n * Does not have references to the children themselves.\n *\n * @param {*} children `this.props.children`\n * @return {object} Mapping of key to the value \"true\"\n */\n getKeySet: function(children) {\n return ReactChildren.map(children, function() {\n return true;\n });\n },\n\n /**\n * When you're adding or removing children some may be added or removed in the\n * same render pass. We want ot show *both* since we want to simultaneously\n * animate elements in and out. This function takes a previous set of keys\n * and a new set of keys and merges them with its best guess of the correct\n * ordering. In the future we may expose some of the utilities in\n * ReactMultiChild to make this easy, but for now React itself does not\n * directly have this concept of the union of prevChildren and nextChildren\n * so we implement it here.\n *\n * @param {object} prev prev child keys as returned from\n * `ReactTransitionKeySet.getKeySet()`.\n * @param {object} next next child keys as returned from\n * `ReactTransitionKeySet.getKeySet()`.\n * @return {object} a key set that contains all keys in `prev` and all keys\n * in `next` in a reasonable order.\n */\n mergeKeySets: function(prev, next) {\n var keySet = {};\n var prevKeys = Object.keys(prev).concat([MERGE_KEY_SETS_TAIL_SENTINEL]);\n var nextKeys = Object.keys(next).concat([MERGE_KEY_SETS_TAIL_SENTINEL]);\n var i;\n for (i = 0; i < prevKeys.length - 1; i++) {\n var prevKey = prevKeys[i];\n if (next[prevKey]) {\n continue;\n }\n\n // This key is not in the new set. Place it in our\n // best guess where it should go. We do this by searching\n // for a key after the current one in prevKeys that is\n // still in nextKeys, and inserting right before it.\n // I know this is O(n^2), but this is not a particularly\n // hot code path.\n var insertPos = -1;\n\n for (var j = i + 1; j < prevKeys.length; j++) {\n insertPos = nextKeys.indexOf(prevKeys[j]);\n if (insertPos >= 0) {\n break;\n }\n }\n\n // Insert before insertPos\n nextKeys.splice(insertPos, 0, prevKey);\n }\n\n for (i = 0; i < nextKeys.length - 1; i++) {\n keySet[nextKeys[i]] = true;\n }\n\n return keySet;\n }\n};\n\nmodule.exports = ReactTransitionKeySet;\n\nrequire(\"./mock-modules\").register(\"ReactTransitionKeySet\", module);\n", +"ReactTransitionableChild":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactTransitionableChild\n */\n\n\"use strict\";\n\nvar React = require(\"./React\");\nvar CSSCore = require(\"./CSSCore\");\nvar ReactTransitionEvents = require(\"./ReactTransitionEvents\");\n\n// We don't remove the element from the DOM until we receive an animationend or\n// transitionend event. If the user screws up and forgets to add an animation\n// their node will be stuck in the DOM forever, so we detect if an animation\n// does not start and if it doesn't, we just call the end listener immediately.\nvar TICK = 17;\nvar NO_EVENT_TIMEOUT = 5000;\n\nvar noEventListener = null;\n\nif (true) {\n noEventListener = function() {\n console.warn(\n 'transition(): tried to perform an animation without ' +\n 'an animationend or transitionend event after timeout (' +\n NO_EVENT_TIMEOUT + 'ms). You should either disable this ' +\n 'transition in JS or add a CSS animation/transition.'\n );\n };\n}\n\n/**\n * This component is simply responsible for watching when its single child\n * changes to undefined and animating the old child out. It does this by\n * recording its old child in savedChildren when it detects this event is about\n * to occur.\n */\nvar ReactTransitionableChild = React.createClass({\n /**\n * Perform an actual DOM transition. This takes care of a few things:\n * - Adding the second CSS class to trigger the transition\n * - Listening for the finish event\n * - Cleaning up the css (unless noReset is true)\n */\n transition: function(animationType, noReset, finishCallback) {\n var node = this.getDOMNode();\n var className = this.props.name + '-' + animationType;\n var activeClassName = className + '-active';\n var noEventTimeout = null;\n\n var endListener = function() {\n if (true) {\n clearTimeout(noEventTimeout);\n }\n\n // If this gets invoked after the component is unmounted it's OK.\n if (!noReset) {\n // Usually this means you're about to remove the node if you want to\n // leave it in its animated state.\n CSSCore.removeClass(node, className);\n CSSCore.removeClass(node, activeClassName);\n }\n\n ReactTransitionEvents.removeEndEventListener(node, endListener);\n\n // Usually this optional callback is used for informing an owner of\n // a leave animation and telling it to remove the child.\n finishCallback && finishCallback();\n };\n\n ReactTransitionEvents.addEndEventListener(node, endListener);\n\n CSSCore.addClass(node, className);\n\n // Need to do this to actually trigger a transition.\n this.queueClass(activeClassName);\n\n if (true) {\n noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT);\n }\n },\n\n queueClass: function(className) {\n this.classNameQueue.push(className);\n\n if (this.props.runNextTick) {\n this.props.runNextTick(this.flushClassNameQueue);\n return;\n }\n\n if (!this.timeout) {\n this.timeout = setTimeout(this.flushClassNameQueue, TICK);\n }\n },\n\n flushClassNameQueue: function() {\n if (this.isMounted()) {\n this.classNameQueue.forEach(\n CSSCore.addClass.bind(CSSCore, this.getDOMNode())\n );\n }\n this.classNameQueue.length = 0;\n this.timeout = null;\n },\n\n componentWillMount: function() {\n this.classNameQueue = [];\n },\n\n componentWillUnmount: function() {\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n },\n\n componentWillReceiveProps: function(nextProps) {\n if (!nextProps.children && this.props.children) {\n this.savedChildren = this.props.children;\n }\n },\n\n componentDidMount: function(node) {\n if (this.props.enter) {\n this.transition('enter');\n }\n },\n\n componentDidUpdate: function(prevProps, prevState, node) {\n if (prevProps.children && !this.props.children) {\n this.transition('leave', true, this.props.onDoneLeaving);\n }\n },\n\n render: function() {\n return this.props.children || this.savedChildren;\n }\n});\n\nmodule.exports = ReactTransitionableChild;\n\nrequire(\"./mock-modules\").register(\"ReactTransitionableChild\", module);\n", +"ReactDoNotBindDeprecated":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDoNotBindDeprecated\n */\n\n\"use strict\";\n\nvar ReactDoNotBindDeprecated = {\n /**\n * Marks the method for not being automatically bound on component mounting. A\n * couple of reasons you might want to use this:\n *\n * - Automatically supporting the previous behavior in components that were\n * built with previous versions of React.\n * - Tuning performance, by avoiding binding on initial render for methods\n * that are always invoked while being preceded by `this.`. Such binds are\n * unnecessary.\n *\n * React.createClass({\n * handleClick: ReactDoNotBindDeprecated.doNotBind(function() {\n * alert(this.setState); // undefined!\n * }),\n * render: function() {\n * return Jump;\n * }\n * });\n *\n * @param {function} method Method to avoid automatically binding.\n * @public\n */\n doNotBind: function(method) {\n method.__reactDontBind = true; // Mutating\n return method;\n }\n};\n\nmodule.exports = ReactDoNotBindDeprecated;\n\nrequire(\"./mock-modules\").register(\"ReactDoNotBindDeprecated\", module);\n", +"ReactComponent":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactComponent\n */\n\n\"use strict\";\n\nvar ReactComponentEnvironment = require(\"./ReactComponentEnvironment\");\nvar ReactCurrentOwner = require(\"./ReactCurrentOwner\");\nvar ReactOwner = require(\"./ReactOwner\");\nvar ReactUpdates = require(\"./ReactUpdates\");\n\nvar invariant = require(\"./invariant\");\nvar keyMirror = require(\"./keyMirror\");\nvar merge = require(\"./merge\");\n\n/**\n * Every React component is in one of these life cycles.\n */\nvar ComponentLifeCycle = keyMirror({\n /**\n * Mounted components have a DOM node representation and are capable of\n * receiving new props.\n */\n MOUNTED: null,\n /**\n * Unmounted components are inactive and cannot receive new props.\n */\n UNMOUNTED: null\n});\n\n/**\n * Warn if there's no key explicitly set on dynamic arrays of children.\n * This allows us to keep track of children between updates.\n */\n\nvar ownerHasWarned = {};\n\n/**\n * Warn if the component doesn't have an explicit key assigned to it.\n * This component is in an array. The array could grow and shrink or be\n * reordered. All children, that hasn't already been validated, are required to\n * have a \"key\" property assigned to it.\n *\n * @internal\n * @param {ReactComponent} component Component that requires a key.\n */\nfunction validateExplicitKey(component) {\n if (component.__keyValidated__ || component.props.key != null) {\n return;\n }\n component.__keyValidated__ = true;\n\n // We can't provide friendly warnings for top level components.\n if (!ReactCurrentOwner.current) {\n return;\n }\n\n // Name of the component whose render method tried to pass children.\n var currentName = ReactCurrentOwner.current.constructor.displayName;\n if (ownerHasWarned.hasOwnProperty(currentName)) {\n return;\n }\n ownerHasWarned[currentName] = true;\n\n var message = 'Each child in an array should have a unique \"key\" prop. ' +\n 'Check the render method of ' + currentName + '.';\n if (!component.isOwnedBy(ReactCurrentOwner.current)) {\n // Name of the component that originally created this child.\n var childOwnerName =\n component.props.__owner__ &&\n component.props.__owner__.constructor.displayName;\n\n // Usually the current owner is the offender, but if it accepts\n // children as a property, it may be the creator of the child that's\n // responsible for assigning it a key.\n message += ' It was passed a child from ' + childOwnerName + '.';\n }\n\n console.warn(message);\n}\n\n/**\n * Ensure that every component either is passed in a static location or, if\n * if it's passed in an array, has an explicit key property defined.\n *\n * @internal\n * @param {*} component Statically passed child of any type.\n * @return {boolean}\n */\nfunction validateChildKeys(component) {\n if (Array.isArray(component)) {\n for (var i = 0; i < component.length; i++) {\n var child = component[i];\n if (ReactComponent.isValidComponent(child)) {\n validateExplicitKey(child);\n }\n }\n } else if (ReactComponent.isValidComponent(component)) {\n // This component was passed in a valid location.\n component.__keyValidated__ = true;\n }\n}\n\n/**\n * Components are the basic units of composition in React.\n *\n * Every component accepts a set of keyed input parameters known as \"props\" that\n * are initialized by the constructor. Once a component is mounted, the props\n * can be mutated using `setProps` or `replaceProps`.\n *\n * Every component is capable of the following operations:\n *\n * `mountComponent`\n * Initializes the component, renders markup, and registers event listeners.\n *\n * `receiveProps`\n * Updates the rendered DOM nodes given a new set of props.\n *\n * `unmountComponent`\n * Releases any resources allocated by this component.\n *\n * Components can also be \"owned\" by other components. Being owned by another\n * component means being constructed by that component. This is different from\n * being the child of a component, which means having a DOM representation that\n * is a child of the DOM representation of that component.\n *\n * @class ReactComponent\n */\nvar ReactComponent = {\n\n /**\n * @param {?object} object\n * @return {boolean} True if `object` is a valid component.\n * @final\n */\n isValidComponent: function(object) {\n return !!(\n object &&\n typeof object.mountComponentIntoNode === 'function' &&\n typeof object.receiveProps === 'function'\n );\n },\n\n /**\n * Generate a key string that identifies a component within a set.\n *\n * @param {*} component A component that could contain a manual key.\n * @param {number} index Index that is used if a manual key is not provided.\n * @return {string}\n * @internal\n */\n getKey: function(component, index) {\n if (component && component.props && component.props.key != null) {\n // Explicit key\n return '{' + component.props.key + '}';\n }\n // Implicit key determined by the index in the set\n return '[' + index + ']';\n },\n\n /**\n * @internal\n */\n LifeCycle: ComponentLifeCycle,\n\n /**\n * Injected module that provides ability to mutate individual properties.\n * Injected into the base class because many different subclasses need access\n * to this.\n *\n * @internal\n */\n DOMIDOperations: ReactComponentEnvironment.DOMIDOperations,\n\n /**\n * Optionally injectable environment dependent cleanup hook. (server vs.\n * browser etc). Example: A browser system caches DOM nodes based on component\n * ID and must remove that cache entry when this instance is unmounted.\n *\n * @private\n */\n unmountIDFromEnvironment: ReactComponentEnvironment.unmountIDFromEnvironment,\n\n /**\n * The \"image\" of a component tree, is the platform specific (typically\n * serialized) data that represents a tree of lower level UI building blocks.\n * On the web, this \"image\" is HTML markup which describes a construction of\n * low level `div` and `span` nodes. Other platforms may have different\n * encoding of this \"image\". This must be injected.\n *\n * @private\n */\n mountImageIntoNode: ReactComponentEnvironment.mountImageIntoNode,\n\n /**\n * React references `ReactReconcileTransaction` using this property in order\n * to allow dependency injection.\n *\n * @internal\n */\n ReactReconcileTransaction:\n ReactComponentEnvironment.ReactReconcileTransaction,\n\n /**\n * Base functionality for every ReactComponent constructor. Mixed into the\n * `ReactComponent` prototype, but exposed statically for easy access.\n *\n * @lends {ReactComponent.prototype}\n */\n Mixin: merge(ReactComponentEnvironment.Mixin, {\n\n /**\n * Checks whether or not this component is mounted.\n *\n * @return {boolean} True if mounted, false otherwise.\n * @final\n * @protected\n */\n isMounted: function() {\n return this._lifeCycleState === ComponentLifeCycle.MOUNTED;\n },\n\n /**\n * Sets a subset of the props.\n *\n * @param {object} partialProps Subset of the next props.\n * @param {?function} callback Called after props are updated.\n * @final\n * @public\n */\n setProps: function(partialProps, callback) {\n // Merge with `_pendingProps` if it exists, otherwise with existing props.\n this.replaceProps(\n merge(this._pendingProps || this.props, partialProps),\n callback\n );\n },\n\n /**\n * Replaces all of the props.\n *\n * @param {object} props New props.\n * @param {?function} callback Called after props are updated.\n * @final\n * @public\n */\n replaceProps: function(props, callback) {\n invariant(\n !this.props.__owner__,\n 'replaceProps(...): You called `setProps` or `replaceProps` on a ' +\n 'component with an owner. This is an anti-pattern since props will ' +\n 'get reactively updated when rendered. Instead, change the owner\\'s ' +\n '`render` method to pass the correct value as props to the component ' +\n 'where it is created.'\n );\n invariant(\n this.isMounted(),\n 'replaceProps(...): Can only update a mounted component.'\n );\n this._pendingProps = props;\n ReactUpdates.enqueueUpdate(this, callback);\n },\n\n /**\n * Base constructor for all React component.\n *\n * Subclasses that override this method should make sure to invoke\n * `ReactComponent.Mixin.construct.call(this, ...)`.\n *\n * @param {?object} initialProps\n * @param {*} children\n * @internal\n */\n construct: function(initialProps, children) {\n this.props = initialProps || {};\n // Record the component responsible for creating this component.\n this.props.__owner__ = ReactCurrentOwner.current;\n // All components start unmounted.\n this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;\n\n this._pendingProps = null;\n this._pendingCallbacks = null;\n\n // Children can be more than one argument\n var childrenLength = arguments.length - 1;\n if (childrenLength === 1) {\n if (true) {\n validateChildKeys(children);\n }\n this.props.children = children;\n } else if (childrenLength > 1) {\n var childArray = Array(childrenLength);\n for (var i = 0; i < childrenLength; i++) {\n if (true) {\n validateChildKeys(arguments[i + 1]);\n }\n childArray[i] = arguments[i + 1];\n }\n this.props.children = childArray;\n }\n },\n\n /**\n * Initializes the component, renders markup, and registers event listeners.\n *\n * NOTE: This does not insert any nodes into the DOM.\n *\n * Subclasses that override this method should make sure to invoke\n * `ReactComponent.Mixin.mountComponent.call(this, ...)`.\n *\n * @param {string} rootID DOM ID of the root node.\n * @param {ReactReconcileTransaction} transaction\n * @param {number} mountDepth number of components in the owner hierarchy.\n * @return {?string} Rendered markup to be inserted into the DOM.\n * @internal\n */\n mountComponent: function(rootID, transaction, mountDepth) {\n invariant(\n !this.isMounted(),\n 'mountComponent(%s, ...): Can only mount an unmounted component.',\n rootID\n );\n var props = this.props;\n if (props.ref != null) {\n ReactOwner.addComponentAsRefTo(this, props.ref, props.__owner__);\n }\n this._rootNodeID = rootID;\n this._lifeCycleState = ComponentLifeCycle.MOUNTED;\n this._mountDepth = mountDepth;\n // Effectively: return '';\n },\n\n /**\n * Releases any resources allocated by `mountComponent`.\n *\n * NOTE: This does not remove any nodes from the DOM.\n *\n * Subclasses that override this method should make sure to invoke\n * `ReactComponent.Mixin.unmountComponent.call(this)`.\n *\n * @internal\n */\n unmountComponent: function() {\n invariant(\n this.isMounted(),\n 'unmountComponent(): Can only unmount a mounted component.'\n );\n var props = this.props;\n if (props.ref != null) {\n ReactOwner.removeComponentAsRefFrom(this, props.ref, props.__owner__);\n }\n ReactComponent.unmountIDFromEnvironment(this._rootNodeID);\n this._rootNodeID = null;\n this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;\n },\n\n /**\n * Updates the rendered DOM nodes given a new set of props.\n *\n * Subclasses that override this method should make sure to invoke\n * `ReactComponent.Mixin.receiveProps.call(this, ...)`.\n *\n * @param {object} nextProps Next set of properties.\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n receiveProps: function(nextProps, transaction) {\n invariant(\n this.isMounted(),\n 'receiveProps(...): Can only update a mounted component.'\n );\n this._pendingProps = nextProps;\n this._performUpdateIfNecessary(transaction);\n },\n\n /**\n * Call `_performUpdateIfNecessary` within a new transaction.\n *\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n performUpdateIfNecessary: function() {\n var transaction = ReactComponent.ReactReconcileTransaction.getPooled();\n transaction.perform(this._performUpdateIfNecessary, this, transaction);\n ReactComponent.ReactReconcileTransaction.release(transaction);\n },\n\n /**\n * If `_pendingProps` is set, update the component.\n *\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n _performUpdateIfNecessary: function(transaction) {\n if (this._pendingProps == null) {\n return;\n }\n var prevProps = this.props;\n this.props = this._pendingProps;\n this._pendingProps = null;\n this.updateComponent(transaction, prevProps);\n },\n\n /**\n * Updates the component's currently mounted representation.\n *\n * @param {ReactReconcileTransaction} transaction\n * @param {object} prevProps\n * @internal\n */\n updateComponent: function(transaction, prevProps) {\n var props = this.props;\n // If either the owner or a `ref` has changed, make sure the newest owner\n // has stored a reference to `this`, and the previous owner (if different)\n // has forgotten the reference to `this`.\n if (props.__owner__ !== prevProps.__owner__ ||\n props.ref !== prevProps.ref) {\n if (prevProps.ref != null) {\n ReactOwner.removeComponentAsRefFrom(\n this, prevProps.ref, prevProps.__owner__\n );\n }\n // Correct, even if the owner is the same, and only the ref has changed.\n if (props.ref != null) {\n ReactOwner.addComponentAsRefTo(this, props.ref, props.__owner__);\n }\n }\n },\n\n /**\n * Mounts this component and inserts it into the DOM.\n *\n * @param {string} rootID DOM ID of the root node.\n * @param {DOMElement} container DOM element to mount into.\n * @param {boolean} shouldReuseMarkup If true, do not insert markup\n * @final\n * @internal\n * @see {ReactMount.renderComponent}\n */\n mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {\n var transaction = ReactComponent.ReactReconcileTransaction.getPooled();\n transaction.perform(\n this._mountComponentIntoNode,\n this,\n rootID,\n container,\n transaction,\n shouldReuseMarkup\n );\n ReactComponent.ReactReconcileTransaction.release(transaction);\n },\n\n /**\n * @param {string} rootID DOM ID of the root node.\n * @param {DOMElement} container DOM element to mount into.\n * @param {ReactReconcileTransaction} transaction\n * @param {boolean} shouldReuseMarkup If true, do not insert markup\n * @final\n * @private\n */\n _mountComponentIntoNode: function(\n rootID,\n container,\n transaction,\n shouldReuseMarkup) {\n var markup = this.mountComponent(rootID, transaction, 0);\n ReactComponent.mountImageIntoNode(markup, container, shouldReuseMarkup);\n },\n\n /**\n * Checks if this component is owned by the supplied `owner` component.\n *\n * @param {ReactComponent} owner Component to check.\n * @return {boolean} True if `owners` owns this component.\n * @final\n * @internal\n */\n isOwnedBy: function(owner) {\n return this.props.__owner__ === owner;\n },\n\n /**\n * Gets another component, that shares the same owner as this one, by ref.\n *\n * @param {string} ref of a sibling Component.\n * @return {?ReactComponent} the actual sibling Component.\n * @final\n * @internal\n */\n getSiblingByRef: function(ref) {\n var owner = this.props.__owner__;\n if (!owner || !owner.refs) {\n return null;\n }\n return owner.refs[ref];\n }\n })\n};\n\nmodule.exports = ReactComponent;\n\nrequire(\"./mock-modules\").register(\"ReactComponent\", module);\n", +"ReactCompositeComponent":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactCompositeComponent\n */\n\n\"use strict\";\n\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactCurrentOwner = require(\"./ReactCurrentOwner\");\nvar ReactOwner = require(\"./ReactOwner\");\nvar ReactPerf = require(\"./ReactPerf\");\nvar ReactPropTransferer = require(\"./ReactPropTransferer\");\nvar ReactUpdates = require(\"./ReactUpdates\");\n\nvar invariant = require(\"./invariant\");\nvar keyMirror = require(\"./keyMirror\");\nvar merge = require(\"./merge\");\nvar mixInto = require(\"./mixInto\");\nvar objMap = require(\"./objMap\");\n\n/**\n * Policies that describe methods in `ReactCompositeComponentInterface`.\n */\nvar SpecPolicy = keyMirror({\n /**\n * These methods may be defined only once by the class specification or mixin.\n */\n DEFINE_ONCE: null,\n /**\n * These methods may be defined by both the class specification and mixins.\n * Subsequent definitions will be chained. These methods must return void.\n */\n DEFINE_MANY: null,\n /**\n * These methods are overriding the base ReactCompositeComponent class.\n */\n OVERRIDE_BASE: null,\n /**\n * These methods are similar to DEFINE_MANY, except we assume they return\n * objects. We try to merge the keys of the return values of all the mixed in\n * functions. If there is a key conflict we throw.\n */\n DEFINE_MANY_MERGED: null\n});\n\n/**\n * Composite components are higher-level components that compose other composite\n * or native components.\n *\n * To create a new type of `ReactCompositeComponent`, pass a specification of\n * your new class to `React.createClass`. The only requirement of your class\n * specification is that you implement a `render` method.\n *\n * var MyComponent = React.createClass({\n * render: function() {\n * return
Hello World
;\n * }\n * });\n *\n * The class specification supports a specific protocol of methods that have\n * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for\n * more the comprehensive protocol. Any other properties and methods in the\n * class specification will available on the prototype.\n *\n * @interface ReactCompositeComponentInterface\n * @internal\n */\nvar ReactCompositeComponentInterface = {\n\n /**\n * An array of Mixin objects to include when defining your component.\n *\n * @type {array}\n * @optional\n */\n mixins: SpecPolicy.DEFINE_MANY,\n\n /**\n * Definition of prop types for this component.\n *\n * @type {object}\n * @optional\n */\n propTypes: SpecPolicy.DEFINE_ONCE,\n\n\n\n // ==== Definition methods ====\n\n /**\n * Invoked when the component is mounted. Values in the mapping will be set on\n * `this.props` if that prop is not specified (i.e. using an `in` check).\n *\n * This method is invoked before `getInitialState` and therefore cannot rely\n * on `this.state` or use `this.setState`.\n *\n * @return {object}\n * @optional\n */\n getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED,\n\n /**\n * Invoked once before the component is mounted. The return value will be used\n * as the initial value of `this.state`.\n *\n * getInitialState: function() {\n * return {\n * isOn: false,\n * fooBaz: new BazFoo()\n * }\n * }\n *\n * @return {object}\n * @optional\n */\n getInitialState: SpecPolicy.DEFINE_MANY_MERGED,\n\n /**\n * Uses props from `this.props` and state from `this.state` to render the\n * structure of the component.\n *\n * No guarantees are made about when or how often this method is invoked, so\n * it must not have side effects.\n *\n * render: function() {\n * var name = this.props.name;\n * return
Hello, {name}!
;\n * }\n *\n * @return {ReactComponent}\n * @nosideeffects\n * @required\n */\n render: SpecPolicy.DEFINE_ONCE,\n\n\n\n // ==== Delegate methods ====\n\n /**\n * Invoked when the component is initially created and about to be mounted.\n * This may have side effects, but any external subscriptions or data created\n * by this method must be cleaned up in `componentWillUnmount`.\n *\n * @optional\n */\n componentWillMount: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked when the component has been mounted and has a DOM representation.\n * However, there is no guarantee that the DOM node is in the document.\n *\n * Use this as an opportunity to operate on the DOM when the component has\n * been mounted (initialized and rendered) for the first time.\n *\n * @param {DOMElement} rootNode DOM element representing the component.\n * @optional\n */\n componentDidMount: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked before the component receives new props.\n *\n * Use this as an opportunity to react to a prop transition by updating the\n * state using `this.setState`. Current props are accessed via `this.props`.\n *\n * componentWillReceiveProps: function(nextProps) {\n * this.setState({\n * likesIncreasing: nextProps.likeCount > this.props.likeCount\n * });\n * }\n *\n * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop\n * transition may cause a state change, but the opposite is not true. If you\n * need it, you are probably looking for `componentWillUpdate`.\n *\n * @param {object} nextProps\n * @optional\n */\n componentWillReceiveProps: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked while deciding if the component should be updated as a result of\n * receiving new props and state.\n *\n * Use this as an opportunity to `return false` when you're certain that the\n * transition to the new props and state will not require a component update.\n *\n * shouldComponentUpdate: function(nextProps, nextState) {\n * return !equal(nextProps, this.props) || !equal(nextState, this.state);\n * }\n *\n * @param {object} nextProps\n * @param {?object} nextState\n * @return {boolean} True if the component should update.\n * @optional\n */\n shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,\n\n /**\n * Invoked when the component is about to update due to a transition from\n * `this.props` and `this.state` to `nextProps` and `nextState`.\n *\n * Use this as an opportunity to perform preparation before an update occurs.\n *\n * NOTE: You **cannot** use `this.setState()` in this method.\n *\n * @param {object} nextProps\n * @param {?object} nextState\n * @param {ReactReconcileTransaction} transaction\n * @optional\n */\n componentWillUpdate: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked when the component's DOM representation has been updated.\n *\n * Use this as an opportunity to operate on the DOM when the component has\n * been updated.\n *\n * @param {object} prevProps\n * @param {?object} prevState\n * @param {DOMElement} rootNode DOM element representing the component.\n * @optional\n */\n componentDidUpdate: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked when the component is about to be removed from its parent and have\n * its DOM representation destroyed.\n *\n * Use this as an opportunity to deallocate any external resources.\n *\n * NOTE: There is no `componentDidUnmount` since your component will have been\n * destroyed by that point.\n *\n * @optional\n */\n componentWillUnmount: SpecPolicy.DEFINE_MANY,\n\n\n\n // ==== Advanced methods ====\n\n /**\n * Updates the component's currently mounted DOM representation.\n *\n * By default, this implements React's rendering and reconciliation algorithm.\n * Sophisticated clients may wish to override this.\n *\n * @param {ReactReconcileTransaction} transaction\n * @internal\n * @overridable\n */\n updateComponent: SpecPolicy.OVERRIDE_BASE\n\n};\n\n/**\n * Mapping from class specification keys to special processing functions.\n *\n * Although these are declared in the specification when defining classes\n * using `React.createClass`, they will not be on the component's prototype.\n */\nvar RESERVED_SPEC_KEYS = {\n displayName: function(Constructor, displayName) {\n Constructor.displayName = displayName;\n },\n mixins: function(Constructor, mixins) {\n if (mixins) {\n for (var i = 0; i < mixins.length; i++) {\n mixSpecIntoComponent(Constructor, mixins[i]);\n }\n }\n },\n propTypes: function(Constructor, propTypes) {\n Constructor.propTypes = propTypes;\n }\n};\n\nfunction validateMethodOverride(proto, name) {\n var specPolicy = ReactCompositeComponentInterface[name];\n\n // Disallow overriding of base class methods unless explicitly allowed.\n if (ReactCompositeComponentMixin.hasOwnProperty(name)) {\n invariant(\n specPolicy === SpecPolicy.OVERRIDE_BASE,\n 'ReactCompositeComponentInterface: You are attempting to override ' +\n '`%s` from your class specification. Ensure that your method names ' +\n 'do not overlap with React methods.',\n name\n );\n }\n\n // Disallow defining methods more than once unless explicitly allowed.\n if (proto.hasOwnProperty(name)) {\n invariant(\n specPolicy === SpecPolicy.DEFINE_MANY ||\n specPolicy === SpecPolicy.DEFINE_MANY_MERGED,\n 'ReactCompositeComponentInterface: You are attempting to define ' +\n '`%s` on your component more than once. This conflict may be due ' +\n 'to a mixin.',\n name\n );\n }\n}\n\n\nfunction validateLifeCycleOnReplaceState(instance) {\n var compositeLifeCycleState = instance._compositeLifeCycleState;\n invariant(\n instance.isMounted() ||\n compositeLifeCycleState === CompositeLifeCycle.MOUNTING,\n 'replaceState(...): Can only update a mounted or mounting component.'\n );\n invariant(\n compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&\n compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,\n 'replaceState(...): Cannot update while unmounting component or during ' +\n 'an existing state transition (such as within `render`).'\n );\n}\n\n/**\n * Custom version of `mixInto` which handles policy validation and reserved\n * specification keys when building `ReactCompositeComponent` classses.\n */\nfunction mixSpecIntoComponent(Constructor, spec) {\n var proto = Constructor.prototype;\n for (var name in spec) {\n var property = spec[name];\n if (!spec.hasOwnProperty(name) || !property) {\n continue;\n }\n validateMethodOverride(proto, name);\n\n if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {\n RESERVED_SPEC_KEYS[name](Constructor, property);\n } else {\n // Setup methods on prototype:\n // The following member methods should not be automatically bound:\n // 1. Expected ReactCompositeComponent methods (in the \"interface\").\n // 2. Overridden methods (that were mixed in).\n var isCompositeComponentMethod = name in ReactCompositeComponentInterface;\n var isInherited = name in proto;\n var markedDontBind = property.__reactDontBind;\n var isFunction = typeof property === 'function';\n var shouldAutoBind =\n isFunction &&\n !isCompositeComponentMethod &&\n !isInherited &&\n !markedDontBind;\n\n if (shouldAutoBind) {\n if (!proto.__reactAutoBindMap) {\n proto.__reactAutoBindMap = {};\n }\n proto.__reactAutoBindMap[name] = property;\n proto[name] = property;\n } else {\n if (isInherited) {\n // For methods which are defined more than once, call the existing\n // methods before calling the new property.\n if (ReactCompositeComponentInterface[name] ===\n SpecPolicy.DEFINE_MANY_MERGED) {\n proto[name] = createMergedResultFunction(proto[name], property);\n } else {\n proto[name] = createChainedFunction(proto[name], property);\n }\n } else {\n proto[name] = property;\n }\n }\n }\n }\n}\n\n/**\n * Merge two objects, but throw if both contain the same key.\n *\n * @param {object} one The first object, which is mutated.\n * @param {object} two The second object\n * @return {object} one after it has been mutated to contain everything in two.\n */\nfunction mergeObjectsWithNoDuplicateKeys(one, two) {\n invariant(\n one && two && typeof one === 'object' && typeof two === 'object',\n 'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects'\n );\n\n objMap(two, function(value, key) {\n invariant(\n one[key] === undefined,\n 'mergeObjectsWithNoDuplicateKeys(): ' +\n 'Tried to merge two objects with the same key: %s',\n key\n );\n one[key] = value;\n });\n return one;\n}\n\n/**\n * Creates a function that invokes two functions and merges their return values.\n *\n * @param {function} one Function to invoke first.\n * @param {function} two Function to invoke second.\n * @return {function} Function that invokes the two argument functions.\n * @private\n */\nfunction createMergedResultFunction(one, two) {\n return function mergedResult() {\n return mergeObjectsWithNoDuplicateKeys(\n one.apply(this, arguments),\n two.apply(this, arguments)\n );\n };\n}\n\n/**\n * Creates a function that invokes two functions and ignores their return vales.\n *\n * @param {function} one Function to invoke first.\n * @param {function} two Function to invoke second.\n * @return {function} Function that invokes the two argument functions.\n * @private\n */\nfunction createChainedFunction(one, two) {\n return function chainedFunction() {\n one.apply(this, arguments);\n two.apply(this, arguments);\n };\n}\n\n/**\n * `ReactCompositeComponent` maintains an auxiliary life cycle state in\n * `this._compositeLifeCycleState` (which can be null).\n *\n * This is different from the life cycle state maintained by `ReactComponent` in\n * `this._lifeCycleState`. The following diagram shows how the states overlap in\n * time. There are times when the CompositeLifeCycle is null - at those times it\n * is only meaningful to look at ComponentLifeCycle alone.\n *\n * Top Row: ReactComponent.ComponentLifeCycle\n * Low Row: ReactComponent.CompositeLifeCycle\n *\n * +-------+------------------------------------------------------+--------+\n * | UN | MOUNTED | UN |\n * |MOUNTED| | MOUNTED|\n * +-------+------------------------------------------------------+--------+\n * | ^--------+ +------+ +------+ +------+ +--------^ |\n * | | | | | | | | | | | |\n * | 0--|MOUNTING|-0-|RECEIV|-0-|RECEIV|-0-|RECEIV|-0-| UN |--->0 |\n * | | | |PROPS | | PROPS| | STATE| |MOUNTING| |\n * | | | | | | | | | | | |\n * | | | | | | | | | | | |\n * | +--------+ +------+ +------+ +------+ +--------+ |\n * | | | |\n * +-------+------------------------------------------------------+--------+\n */\nvar CompositeLifeCycle = keyMirror({\n /**\n * Components in the process of being mounted respond to state changes\n * differently.\n */\n MOUNTING: null,\n /**\n * Components in the process of being unmounted are guarded against state\n * changes.\n */\n UNMOUNTING: null,\n /**\n * Components that are mounted and receiving new props respond to state\n * changes differently.\n */\n RECEIVING_PROPS: null,\n /**\n * Components that are mounted and receiving new state are guarded against\n * additional state changes.\n */\n RECEIVING_STATE: null\n});\n\n/**\n * @lends {ReactCompositeComponent.prototype}\n */\nvar ReactCompositeComponentMixin = {\n\n /**\n * Base constructor for all composite component.\n *\n * @param {?object} initialProps\n * @param {*} children\n * @final\n * @internal\n */\n construct: function(initialProps, children) {\n // Children can be either an array or more than one argument\n ReactComponent.Mixin.construct.apply(this, arguments);\n this.state = null;\n this._pendingState = null;\n this._compositeLifeCycleState = null;\n },\n\n /**\n * Checks whether or not this composite component is mounted.\n * @return {boolean} True if mounted, false otherwise.\n * @protected\n * @final\n */\n isMounted: function() {\n return ReactComponent.Mixin.isMounted.call(this) &&\n this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING;\n },\n\n /**\n * Initializes the component, renders markup, and registers event listeners.\n *\n * @param {string} rootID DOM ID of the root node.\n * @param {ReactReconcileTransaction} transaction\n * @param {number} mountDepth number of components in the owner hierarchy\n * @return {?string} Rendered markup to be inserted into the DOM.\n * @final\n * @internal\n */\n mountComponent: ReactPerf.measure(\n 'ReactCompositeComponent',\n 'mountComponent',\n function(rootID, transaction, mountDepth) {\n ReactComponent.Mixin.mountComponent.call(\n this,\n rootID,\n transaction,\n mountDepth\n );\n this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;\n\n this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null;\n this._processProps(this.props);\n\n if (this.__reactAutoBindMap) {\n this._bindAutoBindMethods();\n }\n\n this.state = this.getInitialState ? this.getInitialState() : null;\n this._pendingState = null;\n this._pendingForceUpdate = false;\n\n if (this.componentWillMount) {\n this.componentWillMount();\n // When mounting, calls to `setState` by `componentWillMount` will set\n // `this._pendingState` without triggering a re-render.\n if (this._pendingState) {\n this.state = this._pendingState;\n this._pendingState = null;\n }\n }\n\n this._renderedComponent = this._renderValidatedComponent();\n\n // Done with mounting, `setState` will now trigger UI changes.\n this._compositeLifeCycleState = null;\n var markup = this._renderedComponent.mountComponent(\n rootID,\n transaction,\n mountDepth + 1\n );\n if (this.componentDidMount) {\n transaction.getReactMountReady().enqueue(this, this.componentDidMount);\n }\n return markup;\n }\n ),\n\n /**\n * Releases any resources allocated by `mountComponent`.\n *\n * @final\n * @internal\n */\n unmountComponent: function() {\n this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING;\n if (this.componentWillUnmount) {\n this.componentWillUnmount();\n }\n this._compositeLifeCycleState = null;\n\n this._defaultProps = null;\n\n ReactComponent.Mixin.unmountComponent.call(this);\n this._renderedComponent.unmountComponent();\n this._renderedComponent = null;\n\n if (this.refs) {\n this.refs = null;\n }\n\n // Some existing components rely on this.props even after they've been\n // destroyed (in event handlers).\n // TODO: this.props = null;\n // TODO: this.state = null;\n },\n\n /**\n * Sets a subset of the state. Always use this or `replaceState` to mutate\n * state. You should treat `this.state` as immutable.\n *\n * There is no guarantee that `this.state` will be immediately updated, so\n * accessing `this.state` after calling this method may return the old value.\n *\n * There is no guarantee that calls to `setState` will run synchronously,\n * as they may eventually be batched together. You can provide an optional\n * callback that will be executed when the call to setState is actually\n * completed.\n *\n * @param {object} partialState Next partial state to be merged with state.\n * @param {?function} callback Called after state is updated.\n * @final\n * @protected\n */\n setState: function(partialState, callback) {\n // Merge with `_pendingState` if it exists, otherwise with existing state.\n this.replaceState(\n merge(this._pendingState || this.state, partialState),\n callback\n );\n },\n\n /**\n * Replaces all of the state. Always use this or `setState` to mutate state.\n * You should treat `this.state` as immutable.\n *\n * There is no guarantee that `this.state` will be immediately updated, so\n * accessing `this.state` after calling this method may return the old value.\n *\n * @param {object} completeState Next state.\n * @param {?function} callback Called after state is updated.\n * @final\n * @protected\n */\n replaceState: function(completeState, callback) {\n validateLifeCycleOnReplaceState(this);\n this._pendingState = completeState;\n ReactUpdates.enqueueUpdate(this, callback);\n },\n\n /**\n * Processes props by setting default values for unspecified props and\n * asserting that the props are valid.\n *\n * @param {object} props\n * @private\n */\n _processProps: function(props) {\n var propName;\n var defaultProps = this._defaultProps;\n for (propName in defaultProps) {\n if (typeof props[propName] === 'undefined') {\n props[propName] = defaultProps[propName];\n }\n }\n var propTypes = this.constructor.propTypes;\n if (propTypes) {\n var componentName = this.constructor.displayName;\n for (propName in propTypes) {\n var checkProp = propTypes[propName];\n if (checkProp) {\n checkProp(props, propName, componentName);\n }\n }\n }\n },\n\n performUpdateIfNecessary: function() {\n var compositeLifeCycleState = this._compositeLifeCycleState;\n // Do not trigger a state transition if we are in the middle of mounting or\n // receiving props because both of those will already be doing this.\n if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING ||\n compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) {\n return;\n }\n ReactComponent.Mixin.performUpdateIfNecessary.call(this);\n },\n\n /**\n * If any of `_pendingProps`, `_pendingState`, or `_pendingForceUpdate` is\n * set, update the component.\n *\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n _performUpdateIfNecessary: function(transaction) {\n if (this._pendingProps == null &&\n this._pendingState == null &&\n !this._pendingForceUpdate) {\n return;\n }\n\n var nextProps = this.props;\n if (this._pendingProps != null) {\n nextProps = this._pendingProps;\n this._processProps(nextProps);\n this._pendingProps = null;\n\n this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;\n if (this.componentWillReceiveProps) {\n this.componentWillReceiveProps(nextProps, transaction);\n }\n }\n\n this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE;\n\n var nextState = this._pendingState || this.state;\n this._pendingState = null;\n\n if (this._pendingForceUpdate ||\n !this.shouldComponentUpdate ||\n this.shouldComponentUpdate(nextProps, nextState)) {\n this._pendingForceUpdate = false;\n // Will set `this.props` and `this.state`.\n this._performComponentUpdate(nextProps, nextState, transaction);\n } else {\n // If it's determined that a component should not update, we still want\n // to set props and state.\n this.props = nextProps;\n this.state = nextState;\n }\n\n this._compositeLifeCycleState = null;\n },\n\n /**\n * Merges new props and state, notifies delegate methods of update and\n * performs update.\n *\n * @param {object} nextProps Next object to set as properties.\n * @param {?object} nextState Next object to set as state.\n * @param {ReactReconcileTransaction} transaction\n * @private\n */\n _performComponentUpdate: function(nextProps, nextState, transaction) {\n var prevProps = this.props;\n var prevState = this.state;\n\n if (this.componentWillUpdate) {\n this.componentWillUpdate(nextProps, nextState, transaction);\n }\n\n this.props = nextProps;\n this.state = nextState;\n\n this.updateComponent(transaction, prevProps, prevState);\n\n if (this.componentDidUpdate) {\n transaction.getReactMountReady().enqueue(\n this,\n this.componentDidUpdate.bind(this, prevProps, prevState)\n );\n }\n },\n\n /**\n * Updates the component's currently mounted DOM representation.\n *\n * By default, this implements React's rendering and reconciliation algorithm.\n * Sophisticated clients may wish to override this.\n *\n * @param {ReactReconcileTransaction} transaction\n * @param {object} prevProps\n * @param {?object} prevState\n * @internal\n * @overridable\n */\n updateComponent: ReactPerf.measure(\n 'ReactCompositeComponent',\n 'updateComponent',\n function(transaction, prevProps, prevState) {\n ReactComponent.Mixin.updateComponent.call(this, transaction, prevProps);\n var currentComponent = this._renderedComponent;\n var nextComponent = this._renderValidatedComponent();\n if (currentComponent.constructor === nextComponent.constructor) {\n currentComponent.receiveProps(nextComponent.props, transaction);\n } else {\n // These two IDs are actually the same! But nothing should rely on that.\n var thisID = this._rootNodeID;\n var currentComponentID = currentComponent._rootNodeID;\n currentComponent.unmountComponent();\n this._renderedComponent = nextComponent;\n var nextMarkup = nextComponent.mountComponent(\n thisID,\n transaction,\n this._mountDepth + 1\n );\n ReactComponent.DOMIDOperations.dangerouslyReplaceNodeWithMarkupByID(\n currentComponentID,\n nextMarkup\n );\n }\n }\n ),\n\n /**\n * Forces an update. This should only be invoked when it is known with\n * certainty that we are **not** in a DOM transaction.\n *\n * You may want to call this when you know that some deeper aspect of the\n * component's state has changed but `setState` was not called.\n *\n * This will not invoke `shouldUpdateComponent`, but it will invoke\n * `componentWillUpdate` and `componentDidUpdate`.\n *\n * @param {?function} callback Called after update is complete.\n * @final\n * @protected\n */\n forceUpdate: function(callback) {\n var compositeLifeCycleState = this._compositeLifeCycleState;\n invariant(\n this.isMounted() ||\n compositeLifeCycleState === CompositeLifeCycle.MOUNTING,\n 'forceUpdate(...): Can only force an update on mounted or mounting ' +\n 'components.'\n );\n invariant(\n compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&\n compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,\n 'forceUpdate(...): Cannot force an update while unmounting component ' +\n 'or during an existing state transition (such as within `render`).'\n );\n this._pendingForceUpdate = true;\n ReactUpdates.enqueueUpdate(this, callback);\n },\n\n /**\n * @private\n */\n _renderValidatedComponent: function() {\n var renderedComponent;\n ReactCurrentOwner.current = this;\n try {\n renderedComponent = this.render();\n } catch (error) {\n // IE8 requires `catch` in order to use `finally`.\n throw error;\n } finally {\n ReactCurrentOwner.current = null;\n }\n invariant(\n ReactComponent.isValidComponent(renderedComponent),\n '%s.render(): A valid ReactComponent must be returned.',\n this.constructor.displayName || 'ReactCompositeComponent'\n );\n return renderedComponent;\n },\n\n /**\n * @private\n */\n _bindAutoBindMethods: function() {\n for (var autoBindKey in this.__reactAutoBindMap) {\n if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {\n continue;\n }\n var method = this.__reactAutoBindMap[autoBindKey];\n this[autoBindKey] = this._bindAutoBindMethod(method);\n }\n },\n\n /**\n * Binds a method to the component.\n *\n * @param {function} method Method to be bound.\n * @private\n */\n _bindAutoBindMethod: function(method) {\n var component = this;\n var boundMethod = function() {\n return method.apply(component, arguments);\n };\n if (true) {\n boundMethod.__reactBoundContext = component;\n boundMethod.__reactBoundMethod = method;\n boundMethod.__reactBoundArguments = null;\n var componentName = component.constructor.displayName;\n var _bind = boundMethod.bind;\n boundMethod.bind = function(newThis) {\n // User is trying to bind() an autobound method; we effectively will\n // ignore the value of \"this\" that the user is trying to use, so\n // let's warn.\n if (newThis !== component && newThis !== null) {\n console.warn(\n 'bind(): React component methods may only be bound to the ' +\n 'component instance. See ' + componentName\n );\n } else if (arguments.length === 1) {\n console.warn(\n 'bind(): You are binding a component method to the component. ' +\n 'React does this for you automatically in a high-performance ' +\n 'way, so you can safely remove this call. See ' + componentName\n );\n return boundMethod;\n }\n var reboundMethod = _bind.apply(boundMethod, arguments);\n reboundMethod.__reactBoundContext = component;\n reboundMethod.__reactBoundMethod = method;\n reboundMethod.__reactBoundArguments =\n Array.prototype.slice.call(arguments, 1);\n return reboundMethod;\n };\n }\n return boundMethod;\n }\n};\n\nvar ReactCompositeComponentBase = function() {};\nmixInto(ReactCompositeComponentBase, ReactComponent.Mixin);\nmixInto(ReactCompositeComponentBase, ReactOwner.Mixin);\nmixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);\nmixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);\n\n/**\n * Module for creating composite components.\n *\n * @class ReactCompositeComponent\n * @extends ReactComponent\n * @extends ReactOwner\n * @extends ReactPropTransferer\n */\nvar ReactCompositeComponent = {\n\n LifeCycle: CompositeLifeCycle,\n\n Base: ReactCompositeComponentBase,\n\n /**\n * Creates a composite component class given a class specification.\n *\n * @param {object} spec Class specification (which must define `render`).\n * @return {function} Component constructor function.\n * @public\n */\n createClass: function(spec) {\n var Constructor = function() {};\n Constructor.prototype = new ReactCompositeComponentBase();\n Constructor.prototype.constructor = Constructor;\n mixSpecIntoComponent(Constructor, spec);\n\n invariant(\n Constructor.prototype.render,\n 'createClass(...): Class specification must implement a `render` method.'\n );\n\n if (true) {\n if (Constructor.prototype.componentShouldUpdate) {\n console.warn(\n (spec.displayName || 'A component') + ' has a method called ' +\n 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +\n 'The name is phrased as a question because the function is ' +\n 'expected to return a value.'\n );\n }\n }\n\n // Reduce time spent doing lookups by setting these on the prototype.\n for (var methodName in ReactCompositeComponentInterface) {\n if (!Constructor.prototype[methodName]) {\n Constructor.prototype[methodName] = null;\n }\n }\n\n var ConvenienceConstructor = function(props, children) {\n var instance = new Constructor();\n instance.construct.apply(instance, arguments);\n return instance;\n };\n ConvenienceConstructor.componentConstructor = Constructor;\n ConvenienceConstructor.originalSpec = spec;\n return ConvenienceConstructor;\n },\n\n /**\n * Checks if a value is a valid component constructor.\n *\n * @param {*}\n * @return {boolean}\n * @public\n */\n isValidClass: function(componentClass) {\n return componentClass instanceof Function &&\n 'componentConstructor' in componentClass &&\n componentClass.componentConstructor instanceof Function;\n }\n};\n\nmodule.exports = ReactCompositeComponent;\n\nrequire(\"./mock-modules\").register(\"ReactCompositeComponent\", module);\n", +"ReactCurrentOwner":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactCurrentOwner\n */\n\n\"use strict\";\n\n/**\n * Keeps track of the current owner.\n *\n * The current owner is the component who should own any components that are\n * currently being constructed.\n *\n * The depth indicate how many composite components are above this render level.\n */\nvar ReactCurrentOwner = {\n\n /**\n * @internal\n * @type {ReactComponent}\n */\n current: null\n\n};\n\nmodule.exports = ReactCurrentOwner;\n\nrequire(\"./mock-modules\").register(\"ReactCurrentOwner\", module);\n", +"cx":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule cx\n */\n\n/**\n * This function is used to mark string literals representing CSS class names\n * so that they can be transformed statically. This allows for modularization\n * and minification of CSS class names.\n *\n * In static_upstream, this function is actually implemented, but it should\n * eventually be replaced with something more descriptive, and the transform\n * that is used in the main stack should be ported for use elsewhere.\n *\n * @param string|object className to modularize, or an object of key/values.\n * In the object case, the values are conditions that\n * determine if the className keys should be included.\n * @param [string ...] Variable list of classNames in the string case.\n * @return string Renderable space-separated CSS className.\n */\nfunction cx(classNames) {\n if (typeof classNames == 'object') {\n return Object.keys(classNames).map(function(className) {\n return classNames[className] ? className : '';\n }).join(' ');\n } else {\n return Array.prototype.join.call(arguments, ' ');\n }\n}\n\nmodule.exports = cx;\n\nrequire(\"./mock-modules\").register(\"cx\", module);\n", +"ReactPropTypes":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactPropTypes\n */\n\n\"use strict\";\n\nvar createObjectFrom = require(\"./createObjectFrom\");\nvar invariant = require(\"./invariant\");\n\n/**\n * Collection of methods that allow declaration and validation of props that are\n * supplied to React components. Example usage:\n *\n * var Props = require('ReactPropTypes');\n * var MyArticle = React.createClass({\n * propTypes: {\n * // An optional string prop named \"description\".\n * description: Props.string,\n *\n * // A required enum prop named \"category\".\n * category: Props.oneOf(['News','Photos']).isRequired,\n *\n * // A prop named \"dialog\" that requires an instance of Dialog.\n * dialog: Props.instanceOf(Dialog).isRequired\n * },\n * render: function() { ... }\n * });\n *\n * A more formal specification of how these methods are used:\n *\n * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)\n * decl := ReactPropTypes.{type}(.isRequired)?\n *\n * Each and every declaration produces a function with the same signature. This\n * allows the creation of custom validation functions. For example:\n *\n * var Props = require('ReactPropTypes');\n * var MyLink = React.createClass({\n * propTypes: {\n * // An optional string or URI prop named \"href\".\n * href: function(props, propName, componentName) {\n * var propValue = props[propName];\n * invariant(\n * propValue == null ||\n * typeof propValue === 'string' ||\n * propValue instanceof URI,\n * 'Invalid `%s` supplied to `%s`, expected string or URI.',\n * propName,\n * componentName\n * );\n * }\n * },\n * render: function() { ... }\n * });\n *\n * @internal\n */\nvar Props = {\n\n array: createPrimitiveTypeChecker('array'),\n bool: createPrimitiveTypeChecker('boolean'),\n func: createPrimitiveTypeChecker('function'),\n number: createPrimitiveTypeChecker('number'),\n object: createPrimitiveTypeChecker('object'),\n string: createPrimitiveTypeChecker('string'),\n\n oneOf: createEnumTypeChecker,\n\n instanceOf: createInstanceTypeChecker\n\n};\n\nvar ANONYMOUS = '<>';\n\nfunction createPrimitiveTypeChecker(expectedType) {\n function validatePrimitiveType(propValue, propName, componentName) {\n var propType = typeof propValue;\n if (propType === 'object' && Array.isArray(propValue)) {\n propType = 'array';\n }\n invariant(\n propType === expectedType,\n 'Invalid prop `%s` of type `%s` supplied to `%s`, expected `%s`.',\n propName,\n propType,\n componentName,\n expectedType\n );\n }\n return createChainableTypeChecker(validatePrimitiveType);\n}\n\nfunction createEnumTypeChecker(expectedValues) {\n var expectedEnum = createObjectFrom(expectedValues);\n function validateEnumType(propValue, propName, componentName) {\n invariant(\n expectedEnum[propValue],\n 'Invalid prop `%s` supplied to `%s`, expected one of %s.',\n propName,\n componentName,\n JSON.stringify(Object.keys(expectedEnum))\n );\n }\n return createChainableTypeChecker(validateEnumType);\n}\n\nfunction createInstanceTypeChecker(expectedClass) {\n function validateInstanceType(propValue, propName, componentName) {\n invariant(\n propValue instanceof expectedClass,\n 'Invalid prop `%s` supplied to `%s`, expected instance of `%s`.',\n propName,\n componentName,\n expectedClass.name || ANONYMOUS\n );\n }\n return createChainableTypeChecker(validateInstanceType);\n}\n\nfunction createChainableTypeChecker(validate) {\n function createTypeChecker(isRequired) {\n function checkType(props, propName, componentName) {\n var propValue = props[propName];\n if (propValue != null) {\n // Only validate if there is a value to check.\n validate(propValue, propName, componentName || ANONYMOUS);\n } else {\n invariant(\n !isRequired,\n 'Required prop `%s` was not specified in `%s`.',\n propName,\n componentName || ANONYMOUS\n );\n }\n }\n if (!isRequired) {\n checkType.isRequired = createTypeChecker(true);\n }\n return checkType;\n }\n return createTypeChecker(false);\n}\n\nmodule.exports = Props;\n\nrequire(\"./mock-modules\").register(\"ReactPropTypes\", module);\n", +"ReactMount":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactMount\n */\n\n\"use strict\";\n\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactInstanceHandles = require(\"./ReactInstanceHandles\");\n\nvar $ = require(\"./$\");\nvar getReactRootElementInContainer = require(\"./getReactRootElementInContainer\");\nvar invariant = require(\"./invariant\");\nvar nodeContains = require(\"./nodeContains\");\n\nvar SEPARATOR = ReactInstanceHandles.SEPARATOR;\n\nvar ATTR_NAME = 'data-reactid';\nvar nodeCache = {};\n\nvar ELEMENT_NODE_TYPE = 1;\nvar DOC_NODE_TYPE = 9;\n\n/** Mapping from reactRootID to React component instance. */\nvar instancesByReactRootID = {};\n\n/** Mapping from reactRootID to `container` nodes. */\nvar containersByReactRootID = {};\n\nif (true) {\n /** __DEV__-only mapping from reactRootID to root elements. */\n var rootElementsByReactRootID = {};\n}\n\n/**\n * @param {DOMElement} container DOM element that may contain a React component.\n * @return {?string} A \"reactRoot\" ID, if a React component is rendered.\n */\nfunction getReactRootID(container) {\n var rootElement = getReactRootElementInContainer(container);\n return rootElement && ReactMount.getID(rootElement);\n}\n\n/**\n * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form\n * element can return its control whose name or ID equals ATTR_NAME. All\n * DOM nodes support `getAttributeNode` but this can also get called on\n * other objects so just return '' if we're given something other than a\n * DOM node (such as window).\n *\n * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.\n * @return {string} ID of the supplied `domNode`.\n */\nfunction getID(node) {\n var id = internalGetID(node);\n if (id) {\n if (nodeCache.hasOwnProperty(id)) {\n var cached = nodeCache[id];\n if (cached !== node) {\n invariant(\n !isValid(cached, id),\n 'ReactMount: Two valid but unequal nodes with the same `%s`: %s',\n ATTR_NAME, id\n );\n\n nodeCache[id] = node;\n }\n } else {\n nodeCache[id] = node;\n }\n }\n\n return id;\n}\n\nfunction internalGetID(node) {\n // If node is something like a window, document, or text node, none of\n // which support attributes or a .getAttribute method, gracefully return\n // the empty string, as if the attribute were missing.\n return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';\n}\n\n/**\n * Sets the React-specific ID of the given node.\n *\n * @param {DOMElement} node The DOM node whose ID will be set.\n * @param {string} id The value of the ID attribute.\n */\nfunction setID(node, id) {\n var oldID = internalGetID(node);\n if (oldID !== id) {\n delete nodeCache[oldID];\n }\n node.setAttribute(ATTR_NAME, id);\n nodeCache[id] = node;\n}\n\n/**\n * Finds the node with the supplied React-generated DOM ID.\n *\n * @param {string} id A React-generated DOM ID.\n * @return {DOMElement} DOM node with the suppled `id`.\n * @internal\n */\nfunction getNode(id) {\n if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {\n nodeCache[id] = ReactMount.findReactNodeByID(id);\n }\n return nodeCache[id];\n}\n\n/**\n * A node is \"valid\" if it is contained by a currently mounted container.\n *\n * This means that the node does not have to be contained by a document in\n * order to be considered valid.\n *\n * @param {?DOMElement} node The candidate DOM node.\n * @param {string} id The expected ID of the node.\n * @return {boolean} Whether the node is contained by a mounted container.\n */\nfunction isValid(node, id) {\n if (node) {\n invariant(\n internalGetID(node) === id,\n 'ReactMount: Unexpected modification of `%s`',\n ATTR_NAME\n );\n\n var container = ReactMount.findReactContainerForID(id);\n if (container && nodeContains(container, node)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Causes the cache to forget about one React-specific ID.\n *\n * @param {string} id The ID to forget.\n */\nfunction purgeID(id) {\n delete nodeCache[id];\n}\n\n/**\n * Mounting is the process of initializing a React component by creatings its\n * representative DOM elements and inserting them into a supplied `container`.\n * Any prior content inside `container` is destroyed in the process.\n *\n * ReactMount.renderComponent(component, $('container'));\n *\n *
<-- Supplied `container`.\n *
<-- Rendered reactRoot of React\n * // ... component.\n *
\n *
\n *\n * Inside of `container`, the first element rendered is the \"reactRoot\".\n */\nvar ReactMount = {\n /**\n * Safety guard to prevent accidentally rendering over the entire HTML tree.\n */\n allowFullPageRender: false,\n\n /** Time spent generating markup. */\n totalInstantiationTime: 0,\n\n /** Time spent inserting markup into the DOM. */\n totalInjectionTime: 0,\n\n /** Whether support for touch events should be initialized. */\n useTouchEvents: false,\n\n /** Exposed for debugging purposes **/\n _instancesByReactRootID: instancesByReactRootID,\n\n /**\n * This is a hook provided to support rendering React components while\n * ensuring that the apparent scroll position of its `container` does not\n * change.\n *\n * @param {DOMElement} container The `container` being rendered into.\n * @param {function} renderCallback This must be called once to do the render.\n */\n scrollMonitor: function(container, renderCallback) {\n renderCallback();\n },\n\n /**\n * Ensures that the top-level event delegation listener is set up. This will\n * be invoked some time before the first time any React component is rendered.\n * @param {DOMElement} container container we're rendering into\n *\n * @private\n */\n prepareEnvironmentForDOM: function(container) {\n invariant(\n container && (\n container.nodeType === ELEMENT_NODE_TYPE ||\n container.nodeType === DOC_NODE_TYPE\n ),\n 'prepareEnvironmentForDOM(...): Target container is not a DOM element.'\n );\n var doc = container.nodeType === ELEMENT_NODE_TYPE ?\n container.ownerDocument :\n container;\n ReactEventEmitter.ensureListening(ReactMount.useTouchEvents, doc);\n },\n\n /**\n * Take a component that's already mounted into the DOM and replace its props\n * @param {ReactComponent} prevComponent component instance already in the DOM\n * @param {ReactComponent} nextComponent component instance to render\n * @param {DOMElement} container container to render into\n * @param {?function} callback function triggered on completion\n */\n _updateRootComponent: function(\n prevComponent,\n nextComponent,\n container,\n callback) {\n var nextProps = nextComponent.props;\n ReactMount.scrollMonitor(container, function() {\n prevComponent.replaceProps(nextProps, callback);\n });\n\n if (true) {\n // Record the root element in case it later gets transplanted.\n rootElementsByReactRootID[getReactRootID(container)] =\n getReactRootElementInContainer(container);\n }\n\n return prevComponent;\n },\n\n /**\n * Register a component into the instance map and start the events system.\n * @param {ReactComponent} nextComponent component instance to render\n * @param {DOMElement} container container to render into\n * @return {string} reactRoot ID prefix\n */\n _registerComponent: function(nextComponent, container) {\n ReactMount.prepareEnvironmentForDOM(container);\n\n var reactRootID = ReactMount.registerContainer(container);\n instancesByReactRootID[reactRootID] = nextComponent;\n return reactRootID;\n },\n\n /**\n * Render a new component into the DOM.\n * @param {ReactComponent} nextComponent component instance to render\n * @param {DOMElement} container container to render into\n * @param {boolean} shouldReuseMarkup if we should skip the markup insertion\n * @return {ReactComponent} nextComponent\n */\n _renderNewRootComponent: function(\n nextComponent,\n container,\n shouldReuseMarkup) {\n var reactRootID = ReactMount._registerComponent(nextComponent, container);\n nextComponent.mountComponentIntoNode(\n reactRootID,\n container,\n shouldReuseMarkup\n );\n\n if (true) {\n // Record the root element in case it later gets transplanted.\n rootElementsByReactRootID[reactRootID] =\n getReactRootElementInContainer(container);\n }\n\n return nextComponent;\n },\n\n /**\n * Renders a React component into the DOM in the supplied `container`.\n *\n * If the React component was previously rendered into `container`, this will\n * perform an update on it and only mutate the DOM as necessary to reflect the\n * latest React component.\n *\n * @param {ReactComponent} nextComponent Component instance to render.\n * @param {DOMElement} container DOM element to render into.\n * @param {?function} callback function triggered on completion\n * @return {ReactComponent} Component instance rendered in `container`.\n */\n renderComponent: function(nextComponent, container, callback) {\n var registeredComponent = instancesByReactRootID[getReactRootID(container)];\n\n if (registeredComponent) {\n if (registeredComponent.constructor === nextComponent.constructor) {\n return ReactMount._updateRootComponent(\n registeredComponent,\n nextComponent,\n container,\n callback\n );\n } else {\n ReactMount.unmountComponentAtNode(container);\n }\n }\n\n var reactRootElement = getReactRootElementInContainer(container);\n var containerHasReactMarkup =\n reactRootElement && ReactMount.isRenderedByReact(reactRootElement);\n\n var shouldReuseMarkup = containerHasReactMarkup && !registeredComponent;\n\n var component = ReactMount._renderNewRootComponent(\n nextComponent,\n container,\n shouldReuseMarkup\n );\n callback && callback();\n return component;\n },\n\n /**\n * Constructs a component instance of `constructor` with `initialProps` and\n * renders it into the supplied `container`.\n *\n * @param {function} constructor React component constructor.\n * @param {?object} props Initial props of the component instance.\n * @param {DOMElement} container DOM element to render into.\n * @return {ReactComponent} Component instance rendered in `container`.\n */\n constructAndRenderComponent: function(constructor, props, container) {\n return ReactMount.renderComponent(constructor(props), container);\n },\n\n /**\n * Constructs a component instance of `constructor` with `initialProps` and\n * renders it into a container node identified by supplied `id`.\n *\n * @param {function} componentConstructor React component constructor\n * @param {?object} props Initial props of the component instance.\n * @param {string} id ID of the DOM element to render into.\n * @return {ReactComponent} Component instance rendered in the container node.\n */\n constructAndRenderComponentByID: function(constructor, props, id) {\n return ReactMount.constructAndRenderComponent(constructor, props, $(id));\n },\n\n /**\n * Registers a container node into which React components will be rendered.\n * This also creates the \"reatRoot\" ID that will be assigned to the element\n * rendered within.\n *\n * @param {DOMElement} container DOM element to register as a container.\n * @return {string} The \"reactRoot\" ID of elements rendered within.\n */\n registerContainer: function(container) {\n var reactRootID = getReactRootID(container);\n if (reactRootID) {\n // If one exists, make sure it is a valid \"reactRoot\" ID.\n reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);\n }\n if (!reactRootID) {\n // No valid \"reactRoot\" ID found, create one.\n reactRootID = ReactInstanceHandles.createReactRootID();\n }\n containersByReactRootID[reactRootID] = container;\n return reactRootID;\n },\n\n /**\n * Unmounts and destroys the React component rendered in the `container`.\n *\n * @param {DOMElement} container DOM element containing a React component.\n * @return {boolean} True if a component was found in and unmounted from\n * `container`\n */\n unmountComponentAtNode: function(container) {\n var reactRootID = getReactRootID(container);\n var component = instancesByReactRootID[reactRootID];\n if (!component) {\n return false;\n }\n ReactMount.unmountComponentFromNode(component, container);\n delete instancesByReactRootID[reactRootID];\n delete containersByReactRootID[reactRootID];\n if (true) {\n delete rootElementsByReactRootID[reactRootID];\n }\n return true;\n },\n\n /**\n * @deprecated\n */\n unmountAndReleaseReactRootNode: function() {\n if (true) {\n console.warn(\n 'unmountAndReleaseReactRootNode() has been renamed to ' +\n 'unmountComponentAtNode() and will be removed in the next ' +\n 'version of React.'\n );\n }\n return ReactMount.unmountComponentAtNode.apply(this, arguments);\n },\n\n /**\n * Unmounts a component and removes it from the DOM.\n *\n * @param {ReactComponent} instance React component instance.\n * @param {DOMElement} container DOM element to unmount from.\n * @final\n * @internal\n * @see {ReactMount.unmountComponentAtNode}\n */\n unmountComponentFromNode: function(instance, container) {\n instance.unmountComponent();\n\n // http://jsperf.com/emptying-a-node\n while (container.lastChild) {\n container.removeChild(container.lastChild);\n }\n },\n\n /**\n * Finds the container DOM element that contains React component to which the\n * supplied DOM `id` belongs.\n *\n * @param {string} id The ID of an element rendered by a React component.\n * @return {?DOMElement} DOM element that contains the `id`.\n */\n findReactContainerForID: function(id) {\n var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);\n var container = containersByReactRootID[reactRootID];\n\n if (true) {\n var rootElement = rootElementsByReactRootID[reactRootID];\n if (rootElement && rootElement.parentNode !== container) {\n invariant(\n // Call internalGetID here because getID calls isValid which calls\n // findReactContainerForID (this function).\n internalGetID(rootElement) === reactRootID,\n 'ReactMount: Root element ID differed from reactRootID.'\n );\n\n var containerChild = container.firstChild;\n if (containerChild &&\n reactRootID === internalGetID(containerChild)) {\n // If the container has a new child with the same ID as the old\n // root element, then rootElementsByReactRootID[reactRootID] is\n // just stale and needs to be updated. The case that deserves a\n // warning is when the container is empty.\n rootElementsByReactRootID[reactRootID] = containerChild;\n } else {\n console.warn(\n 'ReactMount: Root element has been removed from its original ' +\n 'container. New container:', rootElement.parentNode\n );\n }\n }\n }\n\n return container;\n },\n\n /**\n * Finds an element rendered by React with the supplied ID.\n *\n * @param {string} id ID of a DOM node in the React component.\n * @return {DOMElement} Root DOM node of the React component.\n */\n findReactNodeByID: function(id) {\n var reactRoot = ReactMount.findReactContainerForID(id);\n return ReactMount.findComponentRoot(reactRoot, id);\n },\n\n /**\n * True if the supplied `node` is rendered by React.\n *\n * @param {*} node DOM Element to check.\n * @return {boolean} True if the DOM Element appears to be rendered by React.\n * @internal\n */\n isRenderedByReact: function(node) {\n if (node.nodeType !== 1) {\n // Not a DOMElement, therefore not a React component\n return false;\n }\n var id = ReactMount.getID(node);\n return id ? id.charAt(0) === SEPARATOR : false;\n },\n\n /**\n * Traverses up the ancestors of the supplied node to find a node that is a\n * DOM representation of a React component.\n *\n * @param {*} node\n * @return {?DOMEventTarget}\n * @internal\n */\n getFirstReactDOM: function(node) {\n var current = node;\n while (current && current.parentNode !== current) {\n if (ReactMount.isRenderedByReact(current)) {\n return current;\n }\n current = current.parentNode;\n }\n return null;\n },\n\n /**\n * Finds a node with the supplied `id` inside of the supplied `ancestorNode`.\n * Exploits the ID naming scheme to perform the search quickly.\n *\n * @param {DOMEventTarget} ancestorNode Search from this root.\n * @pararm {string} id ID of the DOM representation of the component.\n * @return {DOMEventTarget} DOM node with the supplied `id`.\n * @internal\n */\n findComponentRoot: function(ancestorNode, id) {\n var firstChildren = [ancestorNode.firstChild];\n var childIndex = 0;\n\n while (childIndex < firstChildren.length) {\n var child = firstChildren[childIndex++];\n while (child) {\n var childID = ReactMount.getID(child);\n if (childID) {\n if (id === childID) {\n return child;\n } else if (ReactInstanceHandles.isAncestorIDOf(childID, id)) {\n // If we find a child whose ID is an ancestor of the given ID,\n // then we can be sure that we only want to search the subtree\n // rooted at this child, so we can throw out the rest of the\n // search state.\n firstChildren.length = childIndex = 0;\n firstChildren.push(child.firstChild);\n break;\n } else {\n // TODO This should not be necessary if the ID hierarchy is\n // correct, but is occasionally necessary if the DOM has been\n // modified in unexpected ways.\n firstChildren.push(child.firstChild);\n }\n } else {\n // If this child had no ID, then there's a chance that it was\n // injected automatically by the browser, as when a ``\n // element sprouts an extra `` child as a side effect of\n // `.innerHTML` parsing. Optimistically continue down this\n // branch, but not before examining the other siblings.\n firstChildren.push(child.firstChild);\n }\n child = child.nextSibling;\n }\n }\n\n if (true) {\n console.error(\n 'Error while invoking `findComponentRoot` with the following ' +\n 'ancestor node:',\n ancestorNode\n );\n }\n invariant(\n false,\n 'findComponentRoot(..., %s): Unable to find element. This probably ' +\n 'means the DOM was unexpectedly mutated (e.g. by the browser).',\n id,\n ReactMount.getID(ancestorNode)\n );\n },\n\n\n /**\n * React ID utilities.\n */\n\n ATTR_NAME: ATTR_NAME,\n\n getID: getID,\n\n setID: setID,\n\n getNode: getNode,\n\n purgeID: purgeID,\n\n injection: {}\n};\n\nmodule.exports = ReactMount;\n\nrequire(\"./mock-modules\").register(\"ReactMount\", module);\n", +"ReactDOM":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDOM\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar ReactDOMComponent = require(\"./ReactDOMComponent\");\n\nvar mergeInto = require(\"./mergeInto\");\nvar objMapKeyVal = require(\"./objMapKeyVal\");\n\n/**\n * Creates a new React class that is idempotent and capable of containing other\n * React components. It accepts event listeners and DOM properties that are\n * valid according to `DOMProperty`.\n *\n * - Event listeners: `onClick`, `onMouseDown`, etc.\n * - DOM properties: `className`, `name`, `title`, etc.\n *\n * The `style` property functions differently from the DOM API. It accepts an\n * object mapping of style properties to values.\n *\n * @param {string} tag Tag name (e.g. `div`).\n * @param {boolean} omitClose True if the close tag should be omitted.\n * @private\n */\nfunction createDOMComponentClass(tag, omitClose) {\n var Constructor = function() {};\n Constructor.prototype = new ReactDOMComponent(tag, omitClose);\n Constructor.prototype.constructor = Constructor;\n Constructor.displayName = tag;\n\n var ConvenienceConstructor = function(props, children) {\n var instance = new Constructor();\n instance.construct.apply(instance, arguments);\n return instance;\n };\n ConvenienceConstructor.componentConstructor = Constructor;\n return ConvenienceConstructor;\n}\n\n/**\n * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.\n * This is also accessible via `React.DOM`.\n *\n * @public\n */\nvar ReactDOM = objMapKeyVal({\n a: false,\n abbr: false,\n address: false,\n area: false,\n article: false,\n aside: false,\n audio: false,\n b: false,\n base: false,\n bdi: false,\n bdo: false,\n big: false,\n blockquote: false,\n body: false,\n br: true,\n button: false,\n canvas: false,\n caption: false,\n cite: false,\n code: false,\n col: true,\n colgroup: false,\n data: false,\n datalist: false,\n dd: false,\n del: false,\n details: false,\n dfn: false,\n div: false,\n dl: false,\n dt: false,\n em: false,\n embed: true,\n fieldset: false,\n figcaption: false,\n figure: false,\n footer: false,\n form: false, // NOTE: Injected, see `ReactDOMForm`.\n h1: false,\n h2: false,\n h3: false,\n h4: false,\n h5: false,\n h6: false,\n head: false,\n header: false,\n hr: true,\n html: false,\n i: false,\n iframe: false,\n img: true,\n input: true,\n ins: false,\n kbd: false,\n keygen: true,\n label: false,\n legend: false,\n li: false,\n link: false,\n main: false,\n map: false,\n mark: false,\n menu: false,\n menuitem: false, // NOTE: Close tag should be omitted, but causes problems.\n meta: true,\n meter: false,\n nav: false,\n noscript: false,\n object: false,\n ol: false,\n optgroup: false,\n option: false,\n output: false,\n p: false,\n param: true,\n pre: false,\n progress: false,\n q: false,\n rp: false,\n rt: false,\n ruby: false,\n s: false,\n samp: false,\n script: false,\n section: false,\n select: false,\n small: false,\n source: false,\n span: false,\n strong: false,\n style: false,\n sub: false,\n summary: false,\n sup: false,\n table: false,\n tbody: false,\n td: false,\n textarea: false, // NOTE: Injected, see `ReactDOMTextarea`.\n tfoot: false,\n th: false,\n thead: false,\n time: false,\n title: false,\n tr: false,\n track: true,\n u: false,\n ul: false,\n 'var': false,\n video: false,\n wbr: false,\n\n // SVG\n circle: false,\n g: false,\n line: false,\n path: false,\n polyline: false,\n rect: false,\n svg: false,\n text: false\n}, createDOMComponentClass);\n\nvar injection = {\n injectComponentClasses: function(componentClasses) {\n mergeInto(ReactDOM, componentClasses);\n }\n};\n\nReactDOM.injection = injection;\n\nmodule.exports = ReactDOM;\n\nrequire(\"./mock-modules\").register(\"ReactDOM\", module);\n", +"ReactReconcileTransaction":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactReconcileTransaction\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar ExecutionEnvironment = require(\"./ExecutionEnvironment\");\nvar PooledClass = require(\"./PooledClass\");\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactInputSelection = require(\"./ReactInputSelection\");\nvar ReactMountReady = require(\"./ReactMountReady\");\nvar Transaction = require(\"./Transaction\");\n\nvar mixInto = require(\"./mixInto\");\n\n/**\n * Ensures that, when possible, the selection range (currently selected text\n * input) is not disturbed by performing the transaction.\n */\nvar SELECTION_RESTORATION = {\n /**\n * @return {Selection} Selection information.\n */\n initialize: ReactInputSelection.getSelectionInformation,\n /**\n * @param {Selection} sel Selection information returned from `initialize`.\n */\n close: ReactInputSelection.restoreSelection\n};\n\n/**\n * Suppresses events (blur/focus) that could be inadvertently dispatched due to\n * high level DOM manipulations (like temporarily removing a text input from the\n * DOM).\n */\nvar EVENT_SUPPRESSION = {\n /**\n * @return {boolean} The enabled status of `ReactEventEmitter` before the\n * reconciliation.\n */\n initialize: function() {\n var currentlyEnabled = ReactEventEmitter.isEnabled();\n ReactEventEmitter.setEnabled(false);\n return currentlyEnabled;\n },\n\n /**\n * @param {boolean} previouslyEnabled Enabled status of `ReactEventEmitter`\n * before the reconciliation occured. `close` restores the previous value.\n */\n close: function(previouslyEnabled) {\n ReactEventEmitter.setEnabled(previouslyEnabled);\n }\n};\n\n/**\n * Provides a `ReactMountReady` queue for collecting `onDOMReady` callbacks\n * during the performing of the transaction.\n */\nvar ON_DOM_READY_QUEUEING = {\n /**\n * Initializes the internal `onDOMReady` queue.\n */\n initialize: function() {\n this.reactMountReady.reset();\n },\n\n /**\n * After DOM is flushed, invoke all registered `onDOMReady` callbacks.\n */\n close: function() {\n this.reactMountReady.notifyAll();\n }\n};\n\n/**\n * Executed within the scope of the `Transaction` instance. Consider these as\n * being member methods, but with an implied ordering while being isolated from\n * each other.\n */\nvar TRANSACTION_WRAPPERS = [\n SELECTION_RESTORATION,\n EVENT_SUPPRESSION,\n ON_DOM_READY_QUEUEING\n];\n\n/**\n * Currently:\n * - The order that these are listed in the transaction is critical:\n * - Suppresses events.\n * - Restores selection range.\n *\n * Future:\n * - Restore document/overflow scroll positions that were unintentionally\n * modified via DOM insertions above the top viewport boundary.\n * - Implement/integrate with customized constraint based layout system and keep\n * track of which dimensions must be remeasured.\n *\n * @class ReactReconcileTransaction\n */\nfunction ReactReconcileTransaction() {\n this.reinitializeTransaction();\n this.reactMountReady = ReactMountReady.getPooled(null);\n}\n\nvar Mixin = {\n /**\n * @see Transaction\n * @abstract\n * @final\n * @return {array} List of operation wrap proceedures.\n * TODO: convert to array\n */\n getTransactionWrappers: function() {\n if (ExecutionEnvironment.canUseDOM) {\n return TRANSACTION_WRAPPERS;\n } else {\n return [];\n }\n },\n\n /**\n * @return {object} The queue to collect `onDOMReady` callbacks with.\n * TODO: convert to ReactMountReady\n */\n getReactMountReady: function() {\n return this.reactMountReady;\n },\n\n /**\n * `PooledClass` looks for this, and will invoke this before allowing this\n * instance to be resused.\n */\n destructor: function() {\n ReactMountReady.release(this.reactMountReady);\n this.reactMountReady = null;\n }\n};\n\n\nmixInto(ReactReconcileTransaction, Transaction.Mixin);\nmixInto(ReactReconcileTransaction, Mixin);\n\nPooledClass.addPoolingTo(ReactReconcileTransaction);\n\nmodule.exports = ReactReconcileTransaction;\n\nrequire(\"./mock-modules\").register(\"ReactReconcileTransaction\", module);\n", +"ReactDefaultInjection":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDefaultInjection\n */\n\n\"use strict\";\n\nvar ReactDOM = require(\"./ReactDOM\");\nvar ReactDOMButton = require(\"./ReactDOMButton\");\nvar ReactDOMForm = require(\"./ReactDOMForm\");\nvar ReactDOMInput = require(\"./ReactDOMInput\");\nvar ReactDOMOption = require(\"./ReactDOMOption\");\nvar ReactDOMSelect = require(\"./ReactDOMSelect\");\nvar ReactDOMTextarea = require(\"./ReactDOMTextarea\");\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactEventTopLevelCallback = require(\"./ReactEventTopLevelCallback\");\nvar ReactPerf = require(\"./ReactPerf\");\n\nvar DefaultDOMPropertyConfig = require(\"./DefaultDOMPropertyConfig\");\nvar DOMProperty = require(\"./DOMProperty\");\n\nvar ChangeEventPlugin = require(\"./ChangeEventPlugin\");\nvar CompositionEventPlugin = require(\"./CompositionEventPlugin\");\nvar DefaultEventPluginOrder = require(\"./DefaultEventPluginOrder\");\nvar EnterLeaveEventPlugin = require(\"./EnterLeaveEventPlugin\");\nvar EventPluginHub = require(\"./EventPluginHub\");\nvar MobileSafariClickEventPlugin = require(\"./MobileSafariClickEventPlugin\");\nvar ReactInstanceHandles = require(\"./ReactInstanceHandles\");\nvar SelectEventPlugin = require(\"./SelectEventPlugin\");\nvar SimpleEventPlugin = require(\"./SimpleEventPlugin\");\n\nvar ReactDefaultBatchingStrategy = require(\"./ReactDefaultBatchingStrategy\");\nvar ReactUpdates = require(\"./ReactUpdates\");\n\nfunction inject() {\n ReactEventEmitter.TopLevelCallbackCreator = ReactEventTopLevelCallback;\n /**\n * Inject module for resolving DOM hierarchy and plugin ordering.\n */\n EventPluginHub.injection.injectEventPluginOrder(DefaultEventPluginOrder);\n EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles);\n\n /**\n * Some important event plugins included by default (without having to require\n * them).\n */\n EventPluginHub.injection.injectEventPluginsByName({\n SimpleEventPlugin: SimpleEventPlugin,\n EnterLeaveEventPlugin: EnterLeaveEventPlugin,\n ChangeEventPlugin: ChangeEventPlugin,\n CompositionEventPlugin: CompositionEventPlugin,\n MobileSafariClickEventPlugin: MobileSafariClickEventPlugin,\n SelectEventPlugin: SelectEventPlugin\n });\n\n ReactDOM.injection.injectComponentClasses({\n button: ReactDOMButton,\n form: ReactDOMForm,\n input: ReactDOMInput,\n option: ReactDOMOption,\n select: ReactDOMSelect,\n textarea: ReactDOMTextarea\n });\n\n DOMProperty.injection.injectDOMPropertyConfig(DefaultDOMPropertyConfig);\n\n if (true) {\n ReactPerf.injection.injectMeasure(require(\"./ReactDefaultPerf\").measure);\n }\n\n ReactUpdates.injection.injectBatchingStrategy(\n ReactDefaultBatchingStrategy\n );\n}\n\nmodule.exports = {\n inject: inject\n};\n\nrequire(\"./mock-modules\").register(\"ReactDefaultInjection\", module);\n", +"mixInto":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule mixInto\n */\n\n\"use strict\";\n\n/**\n * Simply copies properties to the prototype.\n */\nvar mixInto = function(constructor, methodBag) {\n var methodName;\n for (methodName in methodBag) {\n if (!methodBag.hasOwnProperty(methodName)) {\n continue;\n }\n constructor.prototype[methodName] = methodBag[methodName];\n }\n};\n\nmodule.exports = mixInto;\n\nrequire(\"./mock-modules\").register(\"mixInto\", module);\n", +"ReactDOMComponent":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDOMComponent\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar CSSPropertyOperations = require(\"./CSSPropertyOperations\");\nvar DOMProperty = require(\"./DOMProperty\");\nvar DOMPropertyOperations = require(\"./DOMPropertyOperations\");\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactMultiChild = require(\"./ReactMultiChild\");\nvar ReactMount = require(\"./ReactMount\");\nvar ReactPerf = require(\"./ReactPerf\");\n\nvar escapeTextForBrowser = require(\"./escapeTextForBrowser\");\nvar invariant = require(\"./invariant\");\nvar keyOf = require(\"./keyOf\");\nvar merge = require(\"./merge\");\nvar mixInto = require(\"./mixInto\");\n\nvar putListener = ReactEventEmitter.putListener;\nvar deleteListener = ReactEventEmitter.deleteListener;\nvar registrationNames = ReactEventEmitter.registrationNames;\n\n// For quickly matching children type, to test if can be treated as content.\nvar CONTENT_TYPES = {'string': true, 'number': true};\n\nvar STYLE = keyOf({style: null});\n\n/**\n * @param {?object} props\n */\nfunction assertValidProps(props) {\n if (!props) {\n return;\n }\n // Note the use of `==` which checks for null or undefined.\n invariant(\n props.children == null || props.dangerouslySetInnerHTML == null,\n 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'\n );\n invariant(\n props.style == null || typeof props.style === 'object',\n 'The `style` prop expects a mapping from style properties to values, ' +\n 'not a string.'\n );\n}\n\n/**\n * @constructor ReactDOMComponent\n * @extends ReactComponent\n * @extends ReactMultiChild\n */\nfunction ReactDOMComponent(tag, omitClose) {\n this._tagOpen = '<' + tag;\n this._tagClose = omitClose ? '' : '';\n this.tagName = tag.toUpperCase();\n}\n\nReactDOMComponent.Mixin = {\n\n /**\n * Generates root tag markup then recurses. This method has side effects and\n * is not idempotent.\n *\n * @internal\n * @param {string} rootID The root DOM ID for this node.\n * @param {ReactReconcileTransaction} transaction\n * @param {number} mountDepth number of components in the owner hierarchy\n * @return {string} The computed markup.\n */\n mountComponent: ReactPerf.measure(\n 'ReactDOMComponent',\n 'mountComponent',\n function(rootID, transaction, mountDepth) {\n ReactComponent.Mixin.mountComponent.call(\n this,\n rootID,\n transaction,\n mountDepth\n );\n assertValidProps(this.props);\n return (\n this._createOpenTagMarkup() +\n this._createContentMarkup(transaction) +\n this._tagClose\n );\n }\n ),\n\n /**\n * Creates markup for the open tag and all attributes.\n *\n * This method has side effects because events get registered.\n *\n * Iterating over object properties is faster than iterating over arrays.\n * @see http://jsperf.com/obj-vs-arr-iteration\n *\n * @private\n * @return {string} Markup of opening tag.\n */\n _createOpenTagMarkup: function() {\n var props = this.props;\n var ret = this._tagOpen;\n\n for (var propKey in props) {\n if (!props.hasOwnProperty(propKey)) {\n continue;\n }\n var propValue = props[propKey];\n if (propValue == null) {\n continue;\n }\n if (registrationNames[propKey]) {\n putListener(this._rootNodeID, propKey, propValue);\n } else {\n if (propKey === STYLE) {\n if (propValue) {\n propValue = props.style = merge(props.style);\n }\n propValue = CSSPropertyOperations.createMarkupForStyles(propValue);\n }\n var markup =\n DOMPropertyOperations.createMarkupForProperty(propKey, propValue);\n if (markup) {\n ret += ' ' + markup;\n }\n }\n }\n\n var escapedID = escapeTextForBrowser(this._rootNodeID);\n return ret + ' ' + ReactMount.ATTR_NAME + '=\"' + escapedID + '\">';\n },\n\n /**\n * Creates markup for the content between the tags.\n *\n * @private\n * @param {ReactReconcileTransaction} transaction\n * @return {string} Content markup.\n */\n _createContentMarkup: function(transaction) {\n // Intentional use of != to avoid catching zero/false.\n var innerHTML = this.props.dangerouslySetInnerHTML;\n if (innerHTML != null) {\n if (innerHTML.__html != null) {\n return innerHTML.__html;\n }\n } else {\n var contentToUse =\n CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;\n var childrenToUse = contentToUse != null ? null : this.props.children;\n if (contentToUse != null) {\n return escapeTextForBrowser(contentToUse);\n } else if (childrenToUse != null) {\n var mountImages = this.mountChildren(\n childrenToUse,\n transaction\n );\n return mountImages.join('');\n }\n }\n return '';\n },\n\n receiveProps: function(nextProps, transaction) {\n assertValidProps(nextProps);\n ReactComponent.Mixin.receiveProps.call(this, nextProps, transaction);\n },\n\n /**\n * Updates a native DOM component after it has already been allocated and\n * attached to the DOM. Reconciles the root DOM node, then recurses.\n *\n * @param {ReactReconcileTransaction} transaction\n * @param {object} prevProps\n * @internal\n * @overridable\n */\n updateComponent: ReactPerf.measure(\n 'ReactDOMComponent',\n 'updateComponent',\n function(transaction, prevProps) {\n ReactComponent.Mixin.updateComponent.call(this, transaction, prevProps);\n this._updateDOMProperties(prevProps);\n this._updateDOMChildren(prevProps, transaction);\n }\n ),\n\n /**\n * Reconciles the properties by detecting differences in property values and\n * updating the DOM as necessary. This function is probably the single most\n * critical path for performance optimization.\n *\n * TODO: Benchmark whether checking for changed values in memory actually\n * improves performance (especially statically positioned elements).\n * TODO: Benchmark the effects of putting this at the top since 99% of props\n * do not change for a given reconciliation.\n * TODO: Benchmark areas that can be improved with caching.\n *\n * @private\n * @param {object} lastProps\n */\n _updateDOMProperties: function(lastProps) {\n var nextProps = this.props;\n var propKey;\n var styleName;\n var styleUpdates;\n for (propKey in lastProps) {\n if (nextProps.hasOwnProperty(propKey) ||\n !lastProps.hasOwnProperty(propKey)) {\n continue;\n }\n if (propKey === STYLE) {\n var lastStyle = lastProps[propKey];\n for (styleName in lastStyle) {\n if (lastStyle.hasOwnProperty(styleName)) {\n styleUpdates = styleUpdates || {};\n styleUpdates[styleName] = '';\n }\n }\n } else if (registrationNames[propKey]) {\n deleteListener(this._rootNodeID, propKey);\n } else if (\n DOMProperty.isStandardName[propKey] ||\n DOMProperty.isCustomAttribute(propKey)) {\n ReactComponent.DOMIDOperations.deletePropertyByID(\n this._rootNodeID,\n propKey\n );\n }\n }\n for (propKey in nextProps) {\n var nextProp = nextProps[propKey];\n var lastProp = lastProps[propKey];\n if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {\n continue;\n }\n if (propKey === STYLE) {\n if (nextProp) {\n nextProp = nextProps.style = merge(nextProp);\n }\n if (lastProp) {\n // Unset styles on `lastProp` but not on `nextProp`.\n for (styleName in lastProp) {\n if (lastProp.hasOwnProperty(styleName) &&\n !nextProp.hasOwnProperty(styleName)) {\n styleUpdates = styleUpdates || {};\n styleUpdates[styleName] = '';\n }\n }\n // Update styles that changed since `lastProp`.\n for (styleName in nextProp) {\n if (nextProp.hasOwnProperty(styleName) &&\n lastProp[styleName] !== nextProp[styleName]) {\n styleUpdates = styleUpdates || {};\n styleUpdates[styleName] = nextProp[styleName];\n }\n }\n } else {\n // Relies on `updateStylesByID` not mutating `styleUpdates`.\n styleUpdates = nextProp;\n }\n } else if (registrationNames[propKey]) {\n putListener(this._rootNodeID, propKey, nextProp);\n } else if (\n DOMProperty.isStandardName[propKey] ||\n DOMProperty.isCustomAttribute(propKey)) {\n ReactComponent.DOMIDOperations.updatePropertyByID(\n this._rootNodeID,\n propKey,\n nextProp\n );\n }\n }\n if (styleUpdates) {\n ReactComponent.DOMIDOperations.updateStylesByID(\n this._rootNodeID,\n styleUpdates\n );\n }\n },\n\n /**\n * Reconciles the children with the various properties that affect the\n * children content.\n *\n * @param {object} lastProps\n * @param {ReactReconcileTransaction} transaction\n */\n _updateDOMChildren: function(lastProps, transaction) {\n var nextProps = this.props;\n\n var lastContent =\n CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;\n var nextContent =\n CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;\n\n var lastHtml =\n lastProps.dangerouslySetInnerHTML &&\n lastProps.dangerouslySetInnerHTML.__html;\n var nextHtml =\n nextProps.dangerouslySetInnerHTML &&\n nextProps.dangerouslySetInnerHTML.__html;\n\n // Note the use of `!=` which checks for null or undefined.\n var lastChildren = lastContent != null ? null : lastProps.children;\n var nextChildren = nextContent != null ? null : nextProps.children;\n\n // If we're switching from children to content/html or vice versa, remove\n // the old content\n var lastHasContentOrHtml = lastContent != null || lastHtml != null;\n var nextHasContentOrHtml = nextContent != null || nextHtml != null;\n if (lastChildren != null && nextChildren == null) {\n this.updateChildren(null, transaction);\n } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {\n this.updateTextContent('');\n }\n\n if (nextContent != null) {\n if (lastContent !== nextContent) {\n this.updateTextContent('' + nextContent);\n }\n } else if (nextHtml != null) {\n if (lastHtml !== nextHtml) {\n ReactComponent.DOMIDOperations.updateInnerHTMLByID(\n this._rootNodeID,\n nextHtml\n );\n }\n } else if (nextChildren != null) {\n this.updateChildren(nextChildren, transaction);\n }\n },\n\n /**\n * Destroys all event registrations for this instance. Does not remove from\n * the DOM. That must be done by the parent.\n *\n * @internal\n */\n unmountComponent: function() {\n ReactEventEmitter.deleteAllListeners(this._rootNodeID);\n ReactComponent.Mixin.unmountComponent.call(this);\n this.unmountChildren();\n }\n\n};\n\nmixInto(ReactDOMComponent, ReactComponent.Mixin);\nmixInto(ReactDOMComponent, ReactDOMComponent.Mixin);\nmixInto(ReactDOMComponent, ReactMultiChild.Mixin);\n\nmodule.exports = ReactDOMComponent;\n\nrequire(\"./mock-modules\").register(\"ReactDOMComponent\", module);\n", +"ReactMultiChild":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactMultiChild\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactMultiChildUpdateTypes = require(\"./ReactMultiChildUpdateTypes\");\n\nvar flattenChildren = require(\"./flattenChildren\");\n\n/**\n * Given a `curChild` and `newChild`, determines if `curChild` should be\n * updated as opposed to being destroyed or replaced.\n *\n * @param {?ReactComponent} curChild\n * @param {?ReactComponent} newChild\n * @return {boolean} True if `curChild` should be updated with `newChild`.\n * @protected\n */\nfunction shouldUpdateChild(curChild, newChild) {\n return curChild && newChild && curChild.constructor === newChild.constructor;\n}\n\n/**\n * Updating children of a component may trigger recursive updates. The depth is\n * used to batch recursive updates to render markup more efficiently.\n *\n * @type {number}\n * @private\n */\nvar updateDepth = 0;\n\n/**\n * Queue of update configuration objects.\n *\n * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`.\n *\n * @type {array}\n * @private\n */\nvar updateQueue = [];\n\n/**\n * Queue of markup to be rendered.\n *\n * @type {array}\n * @private\n */\nvar markupQueue = [];\n\n/**\n * Enqueues markup to be rendered and inserted at a supplied index.\n *\n * @param {string} parentID ID of the parent component.\n * @param {string} markup Markup that renders into an element.\n * @param {number} toIndex Destination index.\n * @private\n */\nfunction enqueueMarkup(parentID, markup, toIndex) {\n // NOTE: Null values reduce hidden classes.\n updateQueue.push({\n parentID: parentID,\n parentNode: null,\n type: ReactMultiChildUpdateTypes.INSERT_MARKUP,\n markupIndex: markupQueue.push(markup) - 1,\n fromIndex: null,\n textContent: null,\n toIndex: toIndex\n });\n}\n\n/**\n * Enqueues moving an existing element to another index.\n *\n * @param {string} parentID ID of the parent component.\n * @param {number} fromIndex Source index of the existing element.\n * @param {number} toIndex Destination index of the element.\n * @private\n */\nfunction enqueueMove(parentID, fromIndex, toIndex) {\n // NOTE: Null values reduce hidden classes.\n updateQueue.push({\n parentID: parentID,\n parentNode: null,\n type: ReactMultiChildUpdateTypes.MOVE_EXISTING,\n markupIndex: null,\n textContent: null,\n fromIndex: fromIndex,\n toIndex: toIndex\n });\n}\n\n/**\n * Enqueues removing an element at an index.\n *\n * @param {string} parentID ID of the parent component.\n * @param {number} fromIndex Index of the element to remove.\n * @private\n */\nfunction enqueueRemove(parentID, fromIndex) {\n // NOTE: Null values reduce hidden classes.\n updateQueue.push({\n parentID: parentID,\n parentNode: null,\n type: ReactMultiChildUpdateTypes.REMOVE_NODE,\n markupIndex: null,\n textContent: null,\n fromIndex: fromIndex,\n toIndex: null\n });\n}\n\n/**\n * Enqueues setting the text content.\n *\n * @param {string} parentID ID of the parent component.\n * @param {string} textContent Text content to set.\n * @private\n */\nfunction enqueueTextContent(parentID, textContent) {\n // NOTE: Null values reduce hidden classes.\n updateQueue.push({\n parentID: parentID,\n parentNode: null,\n type: ReactMultiChildUpdateTypes.TEXT_CONTENT,\n markupIndex: null,\n textContent: textContent,\n fromIndex: null,\n toIndex: null\n });\n}\n\n/**\n * Processes any enqueued updates.\n *\n * @private\n */\nfunction processQueue() {\n if (updateQueue.length) {\n ReactComponent.DOMIDOperations.dangerouslyProcessChildrenUpdates(\n updateQueue,\n markupQueue\n );\n clearQueue();\n }\n}\n\n/**\n * Clears any enqueued updates.\n *\n * @private\n */\nfunction clearQueue() {\n updateQueue.length = 0;\n markupQueue.length = 0;\n}\n\n/**\n * ReactMultiChild are capable of reconciling multiple children.\n *\n * @class ReactMultiChild\n * @internal\n */\nvar ReactMultiChild = {\n\n /**\n * Provides common functionality for components that must reconcile multiple\n * children. This is used by `ReactDOMComponent` to mount, update, and\n * unmount child components.\n *\n * @lends {ReactMultiChild.prototype}\n */\n Mixin: {\n\n /**\n * Generates a \"mount image\" for each of the supplied children. In the case\n * of `ReactDOMComponent`, a mount image is a string of markup.\n *\n * @param {?object} nestedChildren Nested child maps.\n * @return {array} An array of mounted representations.\n * @internal\n */\n mountChildren: function(nestedChildren, transaction) {\n var children = flattenChildren(nestedChildren);\n var mountImages = [];\n var index = 0;\n this._renderedChildren = children;\n for (var name in children) {\n var child = children[name];\n if (children.hasOwnProperty(name) && child) {\n // Inlined for performance, see `ReactInstanceHandles.createReactID`.\n var rootID = this._rootNodeID + '.' + name;\n var mountImage = child.mountComponent(\n rootID,\n transaction,\n this._mountDepth + 1\n );\n child._mountImage = mountImage;\n child._mountIndex = index;\n mountImages.push(mountImage);\n index++;\n }\n }\n return mountImages;\n },\n\n /**\n * Replaces any rendered children with a text content string.\n *\n * @param {string} nextContent String of content.\n * @internal\n */\n updateTextContent: function(nextContent) {\n updateDepth++;\n try {\n var prevChildren = this._renderedChildren;\n // Remove any rendered children.\n for (var name in prevChildren) {\n if (prevChildren.hasOwnProperty(name) &&\n prevChildren[name]) {\n this._unmountChildByName(prevChildren[name], name);\n }\n }\n // Set new text content.\n this.setTextContent(nextContent);\n } catch (error) {\n updateDepth--;\n updateDepth || clearQueue();\n throw error;\n }\n updateDepth--;\n updateDepth || processQueue();\n },\n\n /**\n * Updates the rendered children with new children.\n *\n * @param {?object} nextNestedChildren Nested child maps.\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n updateChildren: function(nextNestedChildren, transaction) {\n updateDepth++;\n try {\n this._updateChildren(nextNestedChildren, transaction);\n } catch (error) {\n updateDepth--;\n updateDepth || clearQueue();\n throw error;\n }\n updateDepth--;\n updateDepth || processQueue();\n },\n\n /**\n * Improve performance by isolating this hot code path from the try/catch\n * block in `updateChildren`.\n *\n * @param {?object} nextNestedChildren Nested child maps.\n * @param {ReactReconcileTransaction} transaction\n * @final\n * @protected\n */\n _updateChildren: function(nextNestedChildren, transaction) {\n var nextChildren = flattenChildren(nextNestedChildren);\n var prevChildren = this._renderedChildren;\n if (!nextChildren && !prevChildren) {\n return;\n }\n var name;\n // `nextIndex` will increment for each child in `nextChildren`, but\n // `lastIndex` will be the last index visited in `prevChildren`.\n var lastIndex = 0;\n var nextIndex = 0;\n for (name in nextChildren) {\n if (!nextChildren.hasOwnProperty(name)) {\n continue;\n }\n var prevChild = prevChildren && prevChildren[name];\n var nextChild = nextChildren[name];\n if (shouldUpdateChild(prevChild, nextChild)) {\n this.moveChild(prevChild, nextIndex, lastIndex);\n lastIndex = Math.max(prevChild._mountIndex, lastIndex);\n prevChild.receiveProps(nextChild.props, transaction);\n prevChild._mountIndex = nextIndex;\n } else {\n if (prevChild) {\n // Update `lastIndex` before `_mountIndex` gets unset by unmounting.\n lastIndex = Math.max(prevChild._mountIndex, lastIndex);\n this._unmountChildByName(prevChild, name);\n }\n if (nextChild) {\n this._mountChildByNameAtIndex(\n nextChild, name, nextIndex, transaction\n );\n }\n }\n if (nextChild) {\n nextIndex++;\n }\n }\n // Remove children that are no longer present.\n for (name in prevChildren) {\n if (prevChildren.hasOwnProperty(name) &&\n prevChildren[name] &&\n !(nextChildren && nextChildren[name])) {\n this._unmountChildByName(prevChildren[name], name);\n }\n }\n },\n\n /**\n * Unmounts all rendered children. This should be used to clean up children\n * when this component is unmounted.\n *\n * @internal\n */\n unmountChildren: function() {\n var renderedChildren = this._renderedChildren;\n for (var name in renderedChildren) {\n var renderedChild = renderedChildren[name];\n if (renderedChild && renderedChild.unmountComponent) {\n renderedChild.unmountComponent();\n }\n }\n this._renderedChildren = null;\n },\n\n /**\n * Moves a child component to the supplied index.\n *\n * @param {ReactComponent} child Component to move.\n * @param {number} toIndex Destination index of the element.\n * @param {number} lastIndex Last index visited of the siblings of `child`.\n * @protected\n */\n moveChild: function(child, toIndex, lastIndex) {\n // If the index of `child` is less than `lastIndex`, then it needs to\n // be moved. Otherwise, we do not need to move it because a child will be\n // inserted or moved before `child`.\n if (child._mountIndex < lastIndex) {\n enqueueMove(this._rootNodeID, child._mountIndex, toIndex);\n }\n },\n\n /**\n * Creates a child component.\n *\n * @param {ReactComponent} child Component to create.\n * @protected\n */\n createChild: function(child) {\n enqueueMarkup(this._rootNodeID, child._mountImage, child._mountIndex);\n },\n\n /**\n * Removes a child component.\n *\n * @param {ReactComponent} child Child to remove.\n * @protected\n */\n removeChild: function(child) {\n enqueueRemove(this._rootNodeID, child._mountIndex);\n },\n\n /**\n * Sets this text content string.\n *\n * @param {string} textContent Text content to set.\n * @protected\n */\n setTextContent: function(textContent) {\n enqueueTextContent(this._rootNodeID, textContent);\n },\n\n /**\n * Mounts a child with the supplied name.\n *\n * NOTE: This is part of `updateChildren` and is here for readability.\n *\n * @param {ReactComponent} child Component to mount.\n * @param {string} name Name of the child.\n * @param {number} index Index at which to insert the child.\n * @param {ReactReconcileTransaction} transaction\n * @private\n */\n _mountChildByNameAtIndex: function(child, name, index, transaction) {\n // Inlined for performance, see `ReactInstanceHandles.createReactID`.\n var rootID = this._rootNodeID + '.' + name;\n var mountImage = child.mountComponent(\n rootID,\n transaction,\n this._mountDepth + 1\n );\n child._mountImage = mountImage;\n child._mountIndex = index;\n this.createChild(child);\n this._renderedChildren = this._renderedChildren || {};\n this._renderedChildren[name] = child;\n },\n\n /**\n * Unmounts a rendered child by name.\n *\n * NOTE: This is part of `updateChildren` and is here for readability.\n *\n * @param {ReactComponent} child Component to unmount.\n * @param {string} name Name of the child in `this._renderedChildren`.\n * @private\n */\n _unmountChildByName: function(child, name) {\n if (ReactComponent.isValidComponent(child)) {\n this.removeChild(child);\n child._mountImage = null;\n child._mountIndex = null;\n child.unmountComponent();\n delete this._renderedChildren[name];\n }\n }\n\n }\n\n};\n\nmodule.exports = ReactMultiChild;\n\nrequire(\"./mock-modules\").register(\"ReactMultiChild\", module);\n", +"ReactEventEmitter":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactEventEmitter\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar EventConstants = require(\"./EventConstants\");\nvar EventListener = require(\"./EventListener\");\nvar EventPluginHub = require(\"./EventPluginHub\");\nvar ExecutionEnvironment = require(\"./ExecutionEnvironment\");\nvar ReactEventEmitterMixin = require(\"./ReactEventEmitterMixin\");\nvar ViewportMetrics = require(\"./ViewportMetrics\");\n\nvar invariant = require(\"./invariant\");\nvar isEventSupported = require(\"./isEventSupported\");\nvar merge = require(\"./merge\");\n\n/**\n * Summary of `ReactEventEmitter` event handling:\n *\n * - Top-level delegation is used to trap native browser events. We normalize\n * and de-duplicate events to account for browser quirks.\n *\n * - Forward these native events (with the associated top-level type used to\n * trap it) to `EventPluginHub`, which in turn will ask plugins if they want\n * to extract any synthetic events.\n *\n * - The `EventPluginHub` will then process each event by annotating them with\n * \"dispatches\", a sequence of listeners and IDs that care about that event.\n *\n * - The `EventPluginHub` then dispatches the events.\n *\n * Overview of React and the event system:\n *\n * .\n * +------------+ .\n * | DOM | .\n * +------------+ . +-----------+\n * + . +--------+|SimpleEvent|\n * | . | |Plugin |\n * +-----|------+ . v +-----------+\n * | | | . +--------------+ +------------+\n * | +-----------.--->|EventPluginHub| | Event |\n * | | . | | +-----------+ | Propagators|\n * | ReactEvent | . | | |TapEvent | |------------|\n * | Emitter | . | |<---+|Plugin | |other plugin|\n * | | . | | +-----------+ | utilities |\n * | +-----------.---------+ | +------------+\n * | | | . +----|---------+\n * +-----|------+ . | ^ +-----------+\n * | . | | |Enter/Leave|\n * + . | +-------+|Plugin |\n * +-------------+ . v +-----------+\n * | application | . +----------+\n * |-------------| . | callback |\n * | | . | registry |\n * | | . +----------+\n * +-------------+ .\n * .\n * React Core . General Purpose Event Plugin System\n */\n\n/**\n * Traps top-level events by using event bubbling.\n *\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {string} handlerBaseName Event name (e.g. \"click\").\n * @param {DOMEventTarget} element Element on which to attach listener.\n * @internal\n */\nfunction trapBubbledEvent(topLevelType, handlerBaseName, element) {\n EventListener.listen(\n element,\n handlerBaseName,\n ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(\n topLevelType\n )\n );\n}\n\n/**\n * Traps a top-level event by using event capturing.\n *\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {string} handlerBaseName Event name (e.g. \"click\").\n * @param {DOMEventTarget} element Element on which to attach listener.\n * @internal\n */\nfunction trapCapturedEvent(topLevelType, handlerBaseName, element) {\n EventListener.capture(\n element,\n handlerBaseName,\n ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(\n topLevelType\n )\n );\n}\n\n/**\n * Listens to window scroll and resize events. We cache scroll values so that\n * application code can access them without triggering reflows.\n *\n * NOTE: Scroll events do not bubble.\n *\n * @private\n * @see http://www.quirksmode.org/dom/events/scroll.html\n */\nfunction registerScrollValueMonitoring() {\n var refresh = ViewportMetrics.refreshScrollValues;\n EventListener.listen(window, 'scroll', refresh);\n EventListener.listen(window, 'resize', refresh);\n}\n\n/**\n * `ReactEventEmitter` is used to attach top-level event listeners. For example:\n *\n * ReactEventEmitter.putListener('myID', 'onClick', myFunction);\n *\n * This would allocate a \"registration\" of `('onClick', myFunction)` on 'myID'.\n *\n * @internal\n */\nvar ReactEventEmitter = merge(ReactEventEmitterMixin, {\n\n /**\n * React references `ReactEventTopLevelCallback` using this property in order\n * to allow dependency injection.\n */\n TopLevelCallbackCreator: null,\n\n /**\n * Ensures that top-level event delegation listeners are installed.\n *\n * There are issues with listening to both touch events and mouse events on\n * the top-level, so we make the caller choose which one to listen to. (If\n * there's a touch top-level listeners, anchors don't receive clicks for some\n * reason, and only in some cases).\n *\n * @param {boolean} touchNotMouse Listen to touch events instead of mouse.\n * @param {DOMDocument} contentDocument DOM document to listen on\n */\n ensureListening: function(touchNotMouse, contentDocument) {\n invariant(\n ExecutionEnvironment.canUseDOM,\n 'ensureListening(...): Cannot toggle event listening in a Worker ' +\n 'thread. This is likely a bug in the framework. Please report ' +\n 'immediately.'\n );\n invariant(\n ReactEventEmitter.TopLevelCallbackCreator,\n 'ensureListening(...): Cannot be called without a top level callback ' +\n 'creator being injected.'\n );\n // Call out to base implementation.\n ReactEventEmitterMixin.ensureListening.call(\n ReactEventEmitter,\n {\n touchNotMouse: touchNotMouse,\n contentDocument: contentDocument\n }\n );\n },\n\n /**\n * Sets whether or not any created callbacks should be enabled.\n *\n * @param {boolean} enabled True if callbacks should be enabled.\n */\n setEnabled: function(enabled) {\n invariant(\n ExecutionEnvironment.canUseDOM,\n 'setEnabled(...): Cannot toggle event listening in a Worker thread. ' +\n 'This is likely a bug in the framework. Please report immediately.'\n );\n if (ReactEventEmitter.TopLevelCallbackCreator) {\n ReactEventEmitter.TopLevelCallbackCreator.setEnabled(enabled);\n }\n },\n\n /**\n * @return {boolean} True if callbacks are enabled.\n */\n isEnabled: function() {\n return !!(\n ReactEventEmitter.TopLevelCallbackCreator &&\n ReactEventEmitter.TopLevelCallbackCreator.isEnabled()\n );\n },\n\n /**\n * We listen for bubbled touch events on the document object.\n *\n * Firefox v8.01 (and possibly others) exhibited strange behavior when\n * mounting `onmousemove` events at some node that was not the document\n * element. The symptoms were that if your mouse is not moving over something\n * contained within that mount point (for example on the background) the\n * top-level listeners for `onmousemove` won't be called. However, if you\n * register the `mousemove` on the document object, then it will of course\n * catch all `mousemove`s. This along with iOS quirks, justifies restricting\n * top-level listeners to the document object only, at least for these\n * movement types of events and possibly all events.\n *\n * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html\n *\n * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but\n * they bubble to document.\n *\n * @param {boolean} touchNotMouse Listen to touch events instead of mouse.\n * @param {DOMDocument} contentDocument Document which owns the container\n * @private\n * @see http://www.quirksmode.org/dom/events/keys.html.\n */\n listenAtTopLevel: function(touchNotMouse, contentDocument) {\n invariant(\n !contentDocument._isListening,\n 'listenAtTopLevel(...): Cannot setup top-level listener more than once.'\n );\n var topLevelTypes = EventConstants.topLevelTypes;\n var mountAt = contentDocument;\n\n registerScrollValueMonitoring();\n trapBubbledEvent(topLevelTypes.topMouseOver, 'mouseover', mountAt);\n trapBubbledEvent(topLevelTypes.topMouseDown, 'mousedown', mountAt);\n trapBubbledEvent(topLevelTypes.topMouseUp, 'mouseup', mountAt);\n trapBubbledEvent(topLevelTypes.topMouseMove, 'mousemove', mountAt);\n trapBubbledEvent(topLevelTypes.topMouseOut, 'mouseout', mountAt);\n trapBubbledEvent(topLevelTypes.topClick, 'click', mountAt);\n trapBubbledEvent(topLevelTypes.topDoubleClick, 'dblclick', mountAt);\n if (touchNotMouse) {\n trapBubbledEvent(topLevelTypes.topTouchStart, 'touchstart', mountAt);\n trapBubbledEvent(topLevelTypes.topTouchEnd, 'touchend', mountAt);\n trapBubbledEvent(topLevelTypes.topTouchMove, 'touchmove', mountAt);\n trapBubbledEvent(topLevelTypes.topTouchCancel, 'touchcancel', mountAt);\n }\n trapBubbledEvent(topLevelTypes.topKeyUp, 'keyup', mountAt);\n trapBubbledEvent(topLevelTypes.topKeyPress, 'keypress', mountAt);\n trapBubbledEvent(topLevelTypes.topKeyDown, 'keydown', mountAt);\n trapBubbledEvent(topLevelTypes.topInput, 'input', mountAt);\n trapBubbledEvent(topLevelTypes.topChange, 'change', mountAt);\n trapBubbledEvent(\n topLevelTypes.topSelectionChange,\n 'selectionchange',\n mountAt\n );\n\n trapBubbledEvent(\n topLevelTypes.topCompositionEnd,\n 'compositionend',\n mountAt\n );\n trapBubbledEvent(\n topLevelTypes.topCompositionStart,\n 'compositionstart',\n mountAt\n );\n trapBubbledEvent(\n topLevelTypes.topCompositionUpdate,\n 'compositionupdate',\n mountAt\n );\n\n if (isEventSupported('drag')) {\n trapBubbledEvent(topLevelTypes.topDrag, 'drag', mountAt);\n trapBubbledEvent(topLevelTypes.topDragEnd, 'dragend', mountAt);\n trapBubbledEvent(topLevelTypes.topDragEnter, 'dragenter', mountAt);\n trapBubbledEvent(topLevelTypes.topDragExit, 'dragexit', mountAt);\n trapBubbledEvent(topLevelTypes.topDragLeave, 'dragleave', mountAt);\n trapBubbledEvent(topLevelTypes.topDragOver, 'dragover', mountAt);\n trapBubbledEvent(topLevelTypes.topDragStart, 'dragstart', mountAt);\n trapBubbledEvent(topLevelTypes.topDrop, 'drop', mountAt);\n }\n\n if (isEventSupported('wheel')) {\n trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt);\n } else if (isEventSupported('mousewheel')) {\n trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt);\n } else {\n // Firefox needs to capture a different mouse scroll event.\n // @see http://www.quirksmode.org/dom/events/tests/scroll.html\n trapBubbledEvent(topLevelTypes.topWheel, 'DOMMouseScroll', mountAt);\n }\n\n // IE<9 does not support capturing so just trap the bubbled event there.\n if (isEventSupported('scroll', true)) {\n trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt);\n } else {\n trapBubbledEvent(topLevelTypes.topScroll, 'scroll', window);\n }\n\n if (isEventSupported('focus', true)) {\n trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt);\n trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);\n } else if (isEventSupported('focusin')) {\n // IE has `focusin` and `focusout` events which bubble.\n // @see\n // http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html\n trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);\n trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);\n }\n\n if (isEventSupported('copy')) {\n trapBubbledEvent(topLevelTypes.topCopy, 'copy', mountAt);\n trapBubbledEvent(topLevelTypes.topCut, 'cut', mountAt);\n trapBubbledEvent(topLevelTypes.topPaste, 'paste', mountAt);\n }\n },\n\n registrationNames: EventPluginHub.registrationNames,\n\n putListener: EventPluginHub.putListener,\n\n getListener: EventPluginHub.getListener,\n\n deleteListener: EventPluginHub.deleteListener,\n\n deleteAllListeners: EventPluginHub.deleteAllListeners,\n\n trapBubbledEvent: trapBubbledEvent,\n\n trapCapturedEvent: trapCapturedEvent\n\n});\n\n\nmodule.exports = ReactEventEmitter;\n\nrequire(\"./mock-modules\").register(\"ReactEventEmitter\", module);\n", +"DOMPropertyOperations":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule DOMPropertyOperations\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar DOMProperty = require(\"./DOMProperty\");\n\nvar escapeTextForBrowser = require(\"./escapeTextForBrowser\");\nvar memoizeStringOnly = require(\"./memoizeStringOnly\");\n\nvar processAttributeNameAndPrefix = memoizeStringOnly(function(name) {\n return escapeTextForBrowser(name) + '=\"';\n});\n\nif (true) {\n var reactProps = {\n __owner__: true,\n children: true,\n dangerouslySetInnerHTML: true,\n key: true,\n ref: true\n };\n var warnedProperties = {};\n\n var warnUnknownProperty = function(name) {\n if (reactProps[name] || warnedProperties[name]) {\n return;\n }\n\n warnedProperties[name] = true;\n var lowerCasedName = name.toLowerCase();\n\n // data-* attributes should be lowercase; suggest the lowercase version\n var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ?\n lowerCasedName : DOMProperty.getPossibleStandardName[lowerCasedName];\n\n // For now, only warn when we have a suggested correction. This prevents\n // logging too much when using transferPropsTo.\n if (standardName != null) {\n console.warn(\n 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?'\n );\n }\n\n };\n}\n\n/**\n * Operations for dealing with DOM properties.\n */\nvar DOMPropertyOperations = {\n\n /**\n * Creates markup for a property.\n *\n * @param {string} name\n * @param {*} value\n * @return {?string} Markup string, or null if the property was invalid.\n */\n createMarkupForProperty: function(name, value) {\n if (DOMProperty.isStandardName[name]) {\n if (value == null || DOMProperty.hasBooleanValue[name] && !value) {\n return '';\n }\n var attributeName = DOMProperty.getAttributeName[name];\n return processAttributeNameAndPrefix(attributeName) +\n escapeTextForBrowser(value) + '\"';\n } else if (DOMProperty.isCustomAttribute(name)) {\n if (value == null) {\n return '';\n }\n return processAttributeNameAndPrefix(name) +\n escapeTextForBrowser(value) + '\"';\n } else if (true) {\n warnUnknownProperty(name);\n }\n return null;\n },\n\n /**\n * Sets the value for a property on a node.\n *\n * @param {DOMElement} node\n * @param {string} name\n * @param {*} value\n */\n setValueForProperty: function(node, name, value) {\n if (DOMProperty.isStandardName[name]) {\n var mutationMethod = DOMProperty.getMutationMethod[name];\n if (mutationMethod) {\n mutationMethod(node, value);\n } else if (DOMProperty.mustUseAttribute[name]) {\n if (DOMProperty.hasBooleanValue[name] && !value) {\n node.removeAttribute(DOMProperty.getAttributeName[name]);\n } else {\n node.setAttribute(DOMProperty.getAttributeName[name], '' + value);\n }\n } else {\n var propName = DOMProperty.getPropertyName[name];\n if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) {\n node[propName] = value;\n }\n }\n } else if (DOMProperty.isCustomAttribute(name)) {\n node.setAttribute(name, '' + value);\n } else if (true) {\n warnUnknownProperty(name);\n }\n },\n\n /**\n * Deletes the value for a property on a node.\n *\n * @param {DOMElement} node\n * @param {string} name\n */\n deleteValueForProperty: function(node, name) {\n if (DOMProperty.isStandardName[name]) {\n var mutationMethod = DOMProperty.getMutationMethod[name];\n if (mutationMethod) {\n mutationMethod(node, undefined);\n } else if (DOMProperty.mustUseAttribute[name]) {\n node.removeAttribute(DOMProperty.getAttributeName[name]);\n } else {\n var propName = DOMProperty.getPropertyName[name];\n node[propName] = DOMProperty.getDefaultValueForProperty(\n node.nodeName,\n name\n );\n }\n } else if (DOMProperty.isCustomAttribute(name)) {\n node.removeAttribute(name);\n } else if (true) {\n warnUnknownProperty(name);\n }\n }\n\n};\n\nmodule.exports = DOMPropertyOperations;\n\nrequire(\"./mock-modules\").register(\"DOMPropertyOperations\", module);\n", +"ReactDOMIDOperations":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDOMIDOperations\n * @typechecks static-only\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar CSSPropertyOperations = require(\"./CSSPropertyOperations\");\nvar DOMChildrenOperations = require(\"./DOMChildrenOperations\");\nvar DOMPropertyOperations = require(\"./DOMPropertyOperations\");\nvar ReactMount = require(\"./ReactMount\");\n\nvar getTextContentAccessor = require(\"./getTextContentAccessor\");\nvar invariant = require(\"./invariant\");\n\n/**\n * Errors for properties that should not be updated with `updatePropertyById()`.\n *\n * @type {object}\n * @private\n */\nvar INVALID_PROPERTY_ERRORS = {\n dangerouslySetInnerHTML:\n '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',\n style: '`style` must be set using `updateStylesByID()`.'\n};\n\n/**\n * The DOM property to use when setting text content.\n *\n * @type {string}\n * @private\n */\nvar textContentAccessor = getTextContentAccessor() || 'NA';\n\nvar LEADING_SPACE = /^ /;\n\n/**\n * Operations used to process updates to DOM nodes. This is made injectable via\n * `ReactComponent.DOMIDOperations`.\n */\nvar ReactDOMIDOperations = {\n\n /**\n * Updates a DOM node with new property values. This should only be used to\n * update DOM properties in `DOMProperty`.\n *\n * @param {string} id ID of the node to update.\n * @param {string} name A valid property name, see `DOMProperty`.\n * @param {*} value New value of the property.\n * @internal\n */\n updatePropertyByID: function(id, name, value) {\n var node = ReactMount.getNode(id);\n invariant(\n !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),\n 'updatePropertyByID(...): %s',\n INVALID_PROPERTY_ERRORS[name]\n );\n\n // If we're updating to null or undefined, we should remove the property\n // from the DOM node instead of inadvertantly setting to a string. This\n // brings us in line with the same behavior we have on initial render.\n if (value != null) {\n DOMPropertyOperations.setValueForProperty(node, name, value);\n } else {\n DOMPropertyOperations.deleteValueForProperty(node, name);\n }\n },\n\n /**\n * Updates a DOM node to remove a property. This should only be used to remove\n * DOM properties in `DOMProperty`.\n *\n * @param {string} id ID of the node to update.\n * @param {string} name A property name to remove, see `DOMProperty`.\n * @internal\n */\n deletePropertyByID: function(id, name, value) {\n var node = ReactMount.getNode(id);\n invariant(\n !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),\n 'updatePropertyByID(...): %s',\n INVALID_PROPERTY_ERRORS[name]\n );\n DOMPropertyOperations.deleteValueForProperty(node, name, value);\n },\n\n /**\n * This should almost never be used instead of `updatePropertyByID()` due to\n * the extra object allocation required by the API. That said, this is useful\n * for batching up several operations across worker thread boundaries.\n *\n * @param {string} id ID of the node to update.\n * @param {object} properties A mapping of valid property names.\n * @internal\n * @see {ReactDOMIDOperations.updatePropertyByID}\n */\n updatePropertiesByID: function(id, properties) {\n for (var name in properties) {\n if (!properties.hasOwnProperty(name)) {\n continue;\n }\n ReactDOMIDOperations.updatePropertiesByID(id, name, properties[name]);\n }\n },\n\n /**\n * Updates a DOM node with new style values. If a value is specified as '',\n * the corresponding style property will be unset.\n *\n * @param {string} id ID of the node to update.\n * @param {object} styles Mapping from styles to values.\n * @internal\n */\n updateStylesByID: function(id, styles) {\n var node = ReactMount.getNode(id);\n CSSPropertyOperations.setValueForStyles(node, styles);\n },\n\n /**\n * Updates a DOM node's innerHTML.\n *\n * @param {string} id ID of the node to update.\n * @param {string} html An HTML string.\n * @internal\n */\n updateInnerHTMLByID: function(id, html) {\n var node = ReactMount.getNode(id);\n // HACK: IE8- normalize whitespace in innerHTML, removing leading spaces.\n // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html\n node.innerHTML = html.replace(LEADING_SPACE, ' ');\n },\n\n /**\n * Updates a DOM node's text content set by `props.content`.\n *\n * @param {string} id ID of the node to update.\n * @param {string} content Text content.\n * @internal\n */\n updateTextContentByID: function(id, content) {\n var node = ReactMount.getNode(id);\n node[textContentAccessor] = content;\n },\n\n /**\n * Replaces a DOM node that exists in the document with markup.\n *\n * @param {string} id ID of child to be replaced.\n * @param {string} markup Dangerous markup to inject in place of child.\n * @internal\n * @see {Danger.dangerouslyReplaceNodeWithMarkup}\n */\n dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {\n var node = ReactMount.getNode(id);\n DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);\n },\n\n /**\n * Updates a component's children by processing a series of updates.\n *\n * @param {array} updates List of update configurations.\n * @param {array} markup List of markup strings.\n * @internal\n */\n dangerouslyProcessChildrenUpdates: function(updates, markup) {\n for (var i = 0; i < updates.length; i++) {\n updates[i].parentNode = ReactMount.getNode(updates[i].parentID);\n }\n DOMChildrenOperations.processUpdates(updates, markup);\n }\n\n};\n\nmodule.exports = ReactDOMIDOperations;\n\nrequire(\"./mock-modules\").register(\"ReactDOMIDOperations\", module);\n", +"keyOf":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule keyOf\n */\n\n/**\n * Allows extraction of a minified key. Let's the build system minify keys\n * without loosing the ability to dynamically use key strings as values\n * themselves. Pass in an object with a single key/val pair and it will return\n * you the string key of that single record. Suppose you want to grab the\n * value for a key 'className' inside of an object. Key/val minification may\n * have aliased that key to be 'xa12'. keyOf({className: null}) will return\n * 'xa12' in that case. Resolve keys you want to use once at startup time, then\n * reuse those resolutions.\n */\nvar keyOf = function(oneKeyObj) {\n var key;\n for (key in oneKeyObj) {\n if (!oneKeyObj.hasOwnProperty(key)) {\n continue;\n }\n return key;\n }\n return null;\n};\n\n\nmodule.exports = keyOf;\n\nrequire(\"./mock-modules\").register(\"keyOf\", module);\n", +"EventPluginHub":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule EventPluginHub\n */\n\n\"use strict\";\n\nvar CallbackRegistry = require(\"./CallbackRegistry\");\nvar EventPluginRegistry = require(\"./EventPluginRegistry\");\nvar EventPluginUtils = require(\"./EventPluginUtils\");\nvar EventPropagators = require(\"./EventPropagators\");\nvar ExecutionEnvironment = require(\"./ExecutionEnvironment\");\n\nvar accumulate = require(\"./accumulate\");\nvar forEachAccumulated = require(\"./forEachAccumulated\");\nvar invariant = require(\"./invariant\");\n\n/**\n * Internal queue of events that have accumulated their dispatches and are\n * waiting to have their dispatches executed.\n */\nvar eventQueue = null;\n\n/**\n * Dispatches an event and releases it back into the pool, unless persistent.\n *\n * @param {?object} event Synthetic event to be dispatched.\n * @private\n */\nvar executeDispatchesAndRelease = function(event) {\n if (event) {\n var executeDispatch = EventPluginUtils.executeDispatch;\n // Plugins can provide custom behavior when dispatching events.\n var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event);\n if (PluginModule && PluginModule.executeDispatch) {\n executeDispatch = PluginModule.executeDispatch;\n }\n EventPluginUtils.executeDispatchesInOrder(event, executeDispatch);\n\n if (!event.isPersistent()) {\n event.constructor.release(event);\n }\n }\n};\n\n/**\n * This is a unified interface for event plugins to be installed and configured.\n *\n * Event plugins can implement the following properties:\n *\n * `extractEvents` {function(string, DOMEventTarget, string, object): *}\n * Required. When a top-level event is fired, this method is expected to\n * extract synthetic events that will in turn be queued and dispatched.\n *\n * `eventTypes` {object}\n * Optional, plugins that fire events must publish a mapping of registration\n * names that are used to register listeners. Values of this mapping must\n * be objects that contain `registrationName` or `phasedRegistrationNames`.\n *\n * `executeDispatch` {function(object, function, string)}\n * Optional, allows plugins to override how an event gets dispatched. By\n * default, the listener is simply invoked.\n *\n * Each plugin that is injected into `EventsPluginHub` is immediately operable.\n *\n * @public\n */\nvar EventPluginHub = {\n\n /**\n * Methods for injecting dependencies.\n */\n injection: {\n\n /**\n * @param {object} InjectedInstanceHandle\n * @public\n */\n injectInstanceHandle: EventPropagators.injection.injectInstanceHandle,\n\n /**\n * @param {array} InjectedEventPluginOrder\n * @public\n */\n injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,\n\n /**\n * @param {object} injectedNamesToPlugins Map from names to plugin modules.\n */\n injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName\n\n },\n\n registrationNames: EventPluginRegistry.registrationNames,\n\n putListener: CallbackRegistry.putListener,\n\n getListener: CallbackRegistry.getListener,\n\n deleteListener: CallbackRegistry.deleteListener,\n\n deleteAllListeners: CallbackRegistry.deleteAllListeners,\n\n /**\n * Allows registered plugins an opportunity to extract events from top-level\n * native browser events.\n *\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {DOMEventTarget} topLevelTarget The listening component root node.\n * @param {string} topLevelTargetID ID of `topLevelTarget`.\n * @param {object} nativeEvent Native browser event.\n * @return {*} An accumulation of synthetic events.\n * @internal\n */\n extractEvents: function(\n topLevelType,\n topLevelTarget,\n topLevelTargetID,\n nativeEvent) {\n var events;\n var plugins = EventPluginRegistry.plugins;\n for (var i = 0, l = plugins.length; i < l; i++) {\n // Not every plugin in the ordering may be loaded at runtime.\n var possiblePlugin = plugins[i];\n if (possiblePlugin) {\n var extractedEvents = possiblePlugin.extractEvents(\n topLevelType,\n topLevelTarget,\n topLevelTargetID,\n nativeEvent\n );\n if (extractedEvents) {\n events = accumulate(events, extractedEvents);\n }\n }\n }\n return events;\n },\n\n /**\n * Enqueues a synthetic event that should be dispatched when\n * `processEventQueue` is invoked.\n *\n * @param {*} events An accumulation of synthetic events.\n * @internal\n */\n enqueueEvents: function(events) {\n if (events) {\n eventQueue = accumulate(eventQueue, events);\n }\n },\n\n /**\n * Dispatches all synthetic events on the event queue.\n *\n * @internal\n */\n processEventQueue: function() {\n // Set `eventQueue` to null before processing it so that we can tell if more\n // events get enqueued while processing.\n var processingEventQueue = eventQueue;\n eventQueue = null;\n forEachAccumulated(processingEventQueue, executeDispatchesAndRelease);\n invariant(\n !eventQueue,\n 'processEventQueue(): Additional events were enqueued while processing ' +\n 'an event queue. Support for this has not yet been implemented.'\n );\n }\n\n};\n\nif (ExecutionEnvironment.canUseDOM) {\n window.EventPluginHub = EventPluginHub;\n}\n\nmodule.exports = EventPluginHub;\n\nrequire(\"./mock-modules\").register(\"EventPluginHub\", module);\n", +"TapEventPlugin":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule TapEventPlugin\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar EventPluginUtils = require(\"./EventPluginUtils\");\nvar EventPropagators = require(\"./EventPropagators\");\nvar SyntheticUIEvent = require(\"./SyntheticUIEvent\");\nvar TouchEventUtils = require(\"./TouchEventUtils\");\nvar ViewportMetrics = require(\"./ViewportMetrics\");\n\nvar keyOf = require(\"./keyOf\");\n\nvar isStartish = EventPluginUtils.isStartish;\nvar isEndish = EventPluginUtils.isEndish;\n\n/**\n * Number of pixels that are tolerated in between a `touchStart` and `touchEnd`\n * in order to still be considered a 'tap' event.\n */\nvar tapMoveThreshold = 10;\nvar startCoords = {x: null, y: null};\n\nvar Axis = {\n x: {page: 'pageX', client: 'clientX', envScroll: 'currentPageScrollLeft'},\n y: {page: 'pageY', client: 'clientY', envScroll: 'currentPageScrollTop'}\n};\n\nfunction getAxisCoordOfEvent(axis, nativeEvent) {\n var singleTouch = TouchEventUtils.extractSingleTouch(nativeEvent);\n if (singleTouch) {\n return singleTouch[axis.page];\n }\n return axis.page in nativeEvent ?\n nativeEvent[axis.page] :\n nativeEvent[axis.client] + ViewportMetrics[axis.envScroll];\n}\n\nfunction getDistance(coords, nativeEvent) {\n var pageX = getAxisCoordOfEvent(Axis.x, nativeEvent);\n var pageY = getAxisCoordOfEvent(Axis.y, nativeEvent);\n return Math.pow(\n Math.pow(pageX - coords.x, 2) + Math.pow(pageY - coords.y, 2),\n 0.5\n );\n}\n\nvar eventTypes = {\n touchTap: {\n phasedRegistrationNames: {\n bubbled: keyOf({onTouchTap: null}),\n captured: keyOf({onTouchTapCapture: null})\n }\n }\n};\n\nvar TapEventPlugin = {\n\n tapMoveThreshold: tapMoveThreshold,\n\n eventTypes: eventTypes,\n\n /**\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {DOMEventTarget} topLevelTarget The listening component root node.\n * @param {string} topLevelTargetID ID of `topLevelTarget`.\n * @param {object} nativeEvent Native browser event.\n * @return {*} An accumulation of synthetic events.\n * @see {EventPluginHub.extractEvents}\n */\n extractEvents: function(\n topLevelType,\n topLevelTarget,\n topLevelTargetID,\n nativeEvent) {\n if (!isStartish(topLevelType) && !isEndish(topLevelType)) {\n return null;\n }\n var event = null;\n var distance = getDistance(startCoords, nativeEvent);\n if (isEndish(topLevelType) && distance < tapMoveThreshold) {\n event = SyntheticUIEvent.getPooled(\n eventTypes.touchTap,\n topLevelTargetID,\n nativeEvent\n );\n }\n if (isStartish(topLevelType)) {\n startCoords.x = getAxisCoordOfEvent(Axis.x, nativeEvent);\n startCoords.y = getAxisCoordOfEvent(Axis.y, nativeEvent);\n } else if (isEndish(topLevelType)) {\n startCoords.x = 0;\n startCoords.y = 0;\n }\n EventPropagators.accumulateTwoPhaseDispatches(event);\n return event;\n }\n\n};\n\nmodule.exports = TapEventPlugin;\n\nrequire(\"./mock-modules\").register(\"TapEventPlugin\", module);\n", +"ReactInstanceHandles":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactInstanceHandles\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar invariant = require(\"./invariant\");\n\nvar SEPARATOR = '.';\nvar SEPARATOR_LENGTH = SEPARATOR.length;\n\n/**\n * Maximum depth of traversals before we consider the possibility of a bad ID.\n */\nvar MAX_TREE_DEPTH = 100;\n\n/**\n * Size of the reactRoot ID space. We generate random numbers for React root\n * IDs and if there's a collision the events and DOM update system will\n * get confused. If we assume 100 React components per page, and a user\n * loads 1 page per minute 24/7 for 50 years, with a mount point space of\n * 9,999,999 the likelihood of never having a collision is 99.997%.\n */\nvar GLOBAL_MOUNT_POINT_MAX = 9999999;\n\n/**\n * Creates a DOM ID prefix to use when mounting React components.\n *\n * @param {number} index A unique integer\n * @return {string} React root ID.\n * @internal\n */\nfunction getReactRootIDString(index) {\n return SEPARATOR + 'r[' + index.toString(36) + ']';\n}\n\n/**\n * Checks if a character in the supplied ID is a separator or the end.\n *\n * @param {string} id A React DOM ID.\n * @param {number} index Index of the character to check.\n * @return {boolean} True if the character is a separator or end of the ID.\n * @private\n */\nfunction isBoundary(id, index) {\n return id.charAt(index) === SEPARATOR || index === id.length;\n}\n\n/**\n * Checks if the supplied string is a valid React DOM ID.\n *\n * @param {string} id A React DOM ID, maybe.\n * @return {boolean} True if the string is a valid React DOM ID.\n * @private\n */\nfunction isValidID(id) {\n return id === '' || (\n id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR\n );\n}\n\n/**\n * Checks if the first ID is an ancestor of or equal to the second ID.\n *\n * @param {string} ancestorID\n * @param {string} descendantID\n * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`.\n * @internal\n */\nfunction isAncestorIDOf(ancestorID, descendantID) {\n return (\n descendantID.indexOf(ancestorID) === 0 &&\n isBoundary(descendantID, ancestorID.length)\n );\n}\n\n/**\n * Gets the parent ID of the supplied React DOM ID, `id`.\n *\n * @param {string} id ID of a component.\n * @return {string} ID of the parent, or an empty string.\n * @private\n */\nfunction getParentID(id) {\n return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';\n}\n\n/**\n * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the\n * supplied `destinationID`. If they are equal, the ID is returned.\n *\n * @param {string} ancestorID ID of an ancestor node of `destinationID`.\n * @param {string} destinationID ID of the destination node.\n * @return {string} Next ID on the path from `ancestorID` to `destinationID`.\n * @private\n */\nfunction getNextDescendantID(ancestorID, destinationID) {\n invariant(\n isValidID(ancestorID) && isValidID(destinationID),\n 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.',\n ancestorID,\n destinationID\n );\n invariant(\n isAncestorIDOf(ancestorID, destinationID),\n 'getNextDescendantID(...): React has made an invalid assumption about ' +\n 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.',\n ancestorID,\n destinationID\n );\n if (ancestorID === destinationID) {\n return ancestorID;\n }\n // Skip over the ancestor and the immediate separator. Traverse until we hit\n // another separator or we reach the end of `destinationID`.\n var start = ancestorID.length + SEPARATOR_LENGTH;\n for (var i = start; i < destinationID.length; i++) {\n if (isBoundary(destinationID, i)) {\n break;\n }\n }\n return destinationID.substr(0, i);\n}\n\n/**\n * Gets the nearest common ancestor ID of two IDs.\n *\n * Using this ID scheme, the nearest common ancestor ID is the longest common\n * prefix of the two IDs that immediately preceded a \"marker\" in both strings.\n *\n * @param {string} oneID\n * @param {string} twoID\n * @return {string} Nearest common ancestor ID, or the empty string if none.\n * @private\n */\nfunction getFirstCommonAncestorID(oneID, twoID) {\n var minLength = Math.min(oneID.length, twoID.length);\n if (minLength === 0) {\n return '';\n }\n var lastCommonMarkerIndex = 0;\n // Use `<=` to traverse until the \"EOL\" of the shorter string.\n for (var i = 0; i <= minLength; i++) {\n if (isBoundary(oneID, i) && isBoundary(twoID, i)) {\n lastCommonMarkerIndex = i;\n } else if (oneID.charAt(i) !== twoID.charAt(i)) {\n break;\n }\n }\n var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);\n invariant(\n isValidID(longestCommonID),\n 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s',\n oneID,\n twoID,\n longestCommonID\n );\n return longestCommonID;\n}\n\n/**\n * Traverses the parent path between two IDs (either up or down). The IDs must\n * not be the same, and there must exist a parent path between them.\n *\n * @param {?string} start ID at which to start traversal.\n * @param {?string} stop ID at which to end traversal.\n * @param {function} cb Callback to invoke each ID with.\n * @param {?boolean} skipFirst Whether or not to skip the first node.\n * @param {?boolean} skipLast Whether or not to skip the last node.\n * @private\n */\nfunction traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {\n start = start || '';\n stop = stop || '';\n invariant(\n start !== stop,\n 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.',\n start\n );\n var traverseUp = isAncestorIDOf(stop, start);\n invariant(\n traverseUp || isAncestorIDOf(start, stop),\n 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' +\n 'not have a parent path.',\n start,\n stop\n );\n // Traverse from `start` to `stop` one depth at a time.\n var depth = 0;\n var traverse = traverseUp ? getParentID : getNextDescendantID;\n for (var id = start; /* until break */; id = traverse(id, stop)) {\n if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {\n cb(id, traverseUp, arg);\n }\n if (id === stop) {\n // Only break //after// visiting `stop`.\n break;\n }\n invariant(\n depth++ < MAX_TREE_DEPTH,\n 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' +\n 'traversing the React DOM ID tree. This may be due to malformed IDs: %s',\n start, stop\n );\n }\n}\n\n/**\n * Manages the IDs assigned to DOM representations of React components. This\n * uses a specific scheme in order to traverse the DOM efficiently (e.g. in\n * order to simulate events).\n *\n * @internal\n */\nvar ReactInstanceHandles = {\n\n createReactRootID: function() {\n return getReactRootIDString(\n Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX)\n );\n },\n\n /**\n * Constructs a React ID by joining a root ID with a name.\n *\n * @param {string} rootID Root ID of a parent component.\n * @param {string} name A component's name (as flattened children).\n * @return {string} A React ID.\n * @internal\n */\n createReactID: function(rootID, name) {\n return rootID + SEPARATOR + name;\n },\n\n /**\n * Gets the DOM ID of the React component that is the root of the tree that\n * contains the React component with the supplied DOM ID.\n *\n * @param {string} id DOM ID of a React component.\n * @return {?string} DOM ID of the React component that is the root.\n * @internal\n */\n getReactRootIDFromNodeID: function(id) {\n var regexResult = /\\.r\\[[^\\]]+\\]/.exec(id);\n return regexResult && regexResult[0];\n },\n\n /**\n * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that\n * should would receive a `mouseEnter` or `mouseLeave` event.\n *\n * NOTE: Does not invoke the callback on the nearest common ancestor because\n * nothing \"entered\" or \"left\" that element.\n *\n * @param {string} leaveID ID being left.\n * @param {string} enterID ID being entered.\n * @param {function} cb Callback to invoke on each entered/left ID.\n * @param {*} upArg Argument to invoke the callback with on left IDs.\n * @param {*} downArg Argument to invoke the callback with on entered IDs.\n * @internal\n */\n traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) {\n var ancestorID = getFirstCommonAncestorID(leaveID, enterID);\n if (ancestorID !== leaveID) {\n traverseParentPath(leaveID, ancestorID, cb, upArg, false, true);\n }\n if (ancestorID !== enterID) {\n traverseParentPath(ancestorID, enterID, cb, downArg, true, false);\n }\n },\n\n /**\n * Simulates the traversal of a two-phase, capture/bubble event dispatch.\n *\n * NOTE: This traversal happens on IDs without touching the DOM.\n *\n * @param {string} targetID ID of the target node.\n * @param {function} cb Callback to invoke.\n * @param {*} arg Argument to invoke the callback with.\n * @internal\n */\n traverseTwoPhase: function(targetID, cb, arg) {\n if (targetID) {\n traverseParentPath('', targetID, cb, arg, true, false);\n traverseParentPath(targetID, '', cb, arg, false, true);\n }\n },\n\n /**\n * Exposed for unit testing.\n * @private\n */\n _getFirstCommonAncestorID: getFirstCommonAncestorID,\n\n /**\n * Exposed for unit testing.\n * @private\n */\n _getNextDescendantID: getNextDescendantID,\n\n isAncestorIDOf: isAncestorIDOf,\n\n SEPARATOR: SEPARATOR\n\n};\n\nmodule.exports = ReactInstanceHandles;\n\nrequire(\"./mock-modules\").register(\"ReactInstanceHandles\", module);\n", +"objMapKeyVal":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule objMapKeyVal\n */\n\n\"use strict\";\n\n/**\n * Behaves the same as `objMap` but invokes func with the key first, and value\n * second. Use `objMap` unless you need this special case.\n * Invokes func as:\n *\n * func(key, value, iteration)\n *\n * @param {?object} obj Object to map keys over\n * @param {!function} func Invoked for each key/val pair.\n * @param {?*} context\n * @return {?object} Result of mapping or null if obj is falsey\n */\nfunction objMapKeyVal(obj, func, context) {\n if (!obj) {\n return null;\n }\n var i = 0;\n var ret = {};\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n ret[key] = func.call(context, key, obj[key], i++);\n }\n }\n return ret;\n}\n\nmodule.exports = objMapKeyVal;\n\nrequire(\"./mock-modules\").register(\"objMapKeyVal\", module);\n", +"getTestDocument":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule getTestDocument\n */\n\n/**\n * We need to work around the fact that we have two different\n * test implementations: once that breaks if we clobber document\n * (open-source) and one that doesn't support createHTMLDocument()\n * (jst).\n */\nfunction getTestDocument() {\n if (document.implementation &&\n document.implementation.createHTMLDocument) {\n return document.implementation.createHTMLDocument('test doc');\n }\n return null;\n}\n\nmodule.exports = getTestDocument;\n\nrequire(\"./mock-modules\").register(\"getTestDocument\", module);\n", +"ReactStateSetters":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactStateSetters\n */\n\n\"use strict\";\n\nvar ReactStateSetters = {\n /**\n * Returns a function that calls the provided function, and uses the result\n * of that to set the component's state.\n *\n * @param {ReactCompositeComponent} component\n * @param {function} funcReturningState Returned callback uses this to\n * determine how to update state.\n * @return {function} callback that when invoked uses funcReturningState to\n * determined the object literal to setState.\n */\n createStateSetter: function(component, funcReturningState) {\n return function(a, b, c, d, e, f) {\n var partialState = funcReturningState.call(component, a, b, c, d, e, f);\n if (partialState) {\n component.setState(partialState);\n }\n };\n },\n\n /**\n * Returns a single-argument callback that can be used to update a single\n * key in the component's state.\n *\n * Note: this is memoized function, which makes it inexpensive to call.\n *\n * @param {ReactCompositeComponent} component\n * @param {string} key The key in the state that you should update.\n * @return {function} callback of 1 argument which calls setState() with\n * the provided keyName and callback argument.\n */\n createStateKeySetter: function(component, key) {\n // Memoize the setters.\n var cache = component.__keySetters || (component.__keySetters = {});\n return cache[key] || (cache[key] = createStateKeySetter(component, key));\n }\n};\n\nfunction createStateKeySetter(component, key) {\n // Partial state is allocated outside of the function closure so it can be\n // reused with every call, avoiding memory allocation when this function\n // is called.\n var partialState = {};\n return function stateKeySetter(value) {\n partialState[key] = value;\n component.setState(partialState);\n };\n}\n\nReactStateSetters.Mixin = {\n /**\n * Returns a function that calls the provided function, and uses the result\n * of that to set the component's state.\n *\n * For example, these statements are equivalent:\n *\n * this.setState({x: 1});\n * this.createStateSetter(function(xValue) {\n * return {x: xValue};\n * })(1);\n *\n * @param {function} funcReturningState Returned callback uses this to\n * determine how to update state.\n * @return {function} callback that when invoked uses funcReturningState to\n * determined the object literal to setState.\n */\n createStateSetter: function(funcReturningState) {\n return ReactStateSetters.createStateSetter(this, funcReturningState);\n },\n\n /**\n * Returns a single-argument callback that can be used to update a single\n * key in the component's state.\n *\n * For example, these statements are equivalent:\n *\n * this.setState({x: 1});\n * this.createStateKeySetter('x')(1);\n *\n * Note: this is memoized function, which makes it inexpensive to call.\n *\n * @param {string} key The key in the state that you should update.\n * @return {function} callback of 1 argument which calls setState() with\n * the provided keyName and callback argument.\n */\n createStateKeySetter: function(key) {\n return ReactStateSetters.createStateKeySetter(this, key);\n }\n};\n\nmodule.exports = ReactStateSetters;\n\nrequire(\"./mock-modules\").register(\"ReactStateSetters\", module);\n", +"ReactUpdates":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactUpdates\n */\n\n\"use strict\";\n\nvar invariant = require(\"./invariant\");\n\nvar dirtyComponents = [];\n\nvar batchingStrategy = null;\n\nfunction ensureBatchingStrategy() {\n invariant(batchingStrategy, 'ReactUpdates: must inject a batching strategy');\n}\n\nfunction batchedUpdates(callback, param) {\n ensureBatchingStrategy();\n batchingStrategy.batchedUpdates(callback, param);\n}\n\n/**\n * Array comparator for ReactComponents by owner depth\n *\n * @param {ReactComponent} c1 first component you're comparing\n * @param {ReactComponent} c2 second component you're comparing\n * @return {number} Return value usable by Array.prototype.sort().\n */\nfunction mountDepthComparator(c1, c2) {\n return c1._mountDepth - c2._mountDepth;\n}\n\nfunction runBatchedUpdates() {\n // Since reconciling a component higher in the owner hierarchy usually (not\n // always -- see shouldComponentUpdate()) will reconcile children, reconcile\n // them before their children by sorting the array.\n\n dirtyComponents.sort(mountDepthComparator);\n\n for (var i = 0; i < dirtyComponents.length; i++) {\n // If a component is unmounted before pending changes apply, ignore them\n // TODO: Queue unmounts in the same list to avoid this happening at all\n var component = dirtyComponents[i];\n if (component.isMounted()) {\n // If performUpdateIfNecessary happens to enqueue any new updates, we\n // shouldn't execute the callbacks until the next render happens, so\n // stash the callbacks first\n var callbacks = component._pendingCallbacks;\n component._pendingCallbacks = null;\n component.performUpdateIfNecessary();\n if (callbacks) {\n for (var j = 0; j < callbacks.length; j++) {\n callbacks[j].call(component);\n }\n }\n }\n }\n}\n\nfunction clearDirtyComponents() {\n dirtyComponents.length = 0;\n}\n\nfunction flushBatchedUpdates() {\n // Run these in separate functions so the JIT can optimize\n try {\n runBatchedUpdates();\n } catch (e) {\n // IE 8 requires catch to use finally.\n throw e;\n } finally {\n clearDirtyComponents();\n }\n}\n\n/**\n * Mark a component as needing a rerender, adding an optional callback to a\n * list of functions which will be executed once the rerender occurs.\n */\nfunction enqueueUpdate(component, callback) {\n invariant(\n !callback || typeof callback === \"function\",\n 'enqueueUpdate(...): You called `setProps`, `replaceProps`, ' +\n '`setState`, `replaceState`, or `forceUpdate` with a callback that ' +\n 'isn\\'t callable.'\n );\n ensureBatchingStrategy();\n\n if (!batchingStrategy.isBatchingUpdates) {\n component.performUpdateIfNecessary();\n callback && callback();\n return;\n }\n\n dirtyComponents.push(component);\n\n if (callback) {\n if (component._pendingCallbacks) {\n component._pendingCallbacks.push(callback);\n } else {\n component._pendingCallbacks = [callback];\n }\n }\n}\n\nvar ReactUpdatesInjection = {\n injectBatchingStrategy: function(_batchingStrategy) {\n invariant(\n _batchingStrategy,\n 'ReactUpdates: must provide a batching strategy'\n );\n invariant(\n typeof _batchingStrategy.batchedUpdates === 'function',\n 'ReactUpdates: must provide a batchedUpdates() function'\n );\n invariant(\n typeof _batchingStrategy.isBatchingUpdates === 'boolean',\n 'ReactUpdates: must provide an isBatchingUpdates boolean attribute'\n );\n batchingStrategy = _batchingStrategy;\n }\n};\n\nvar ReactUpdates = {\n batchedUpdates: batchedUpdates,\n enqueueUpdate: enqueueUpdate,\n flushBatchedUpdates: flushBatchedUpdates,\n injection: ReactUpdatesInjection\n};\n\nmodule.exports = ReactUpdates;\n\nrequire(\"./mock-modules\").register(\"ReactUpdates\", module);\n", +"CSSPropertyOperations":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule CSSPropertyOperations\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar CSSProperty = require(\"./CSSProperty\");\n\nvar dangerousStyleValue = require(\"./dangerousStyleValue\");\nvar escapeTextForBrowser = require(\"./escapeTextForBrowser\");\nvar hyphenate = require(\"./hyphenate\");\nvar memoizeStringOnly = require(\"./memoizeStringOnly\");\n\nvar processStyleName = memoizeStringOnly(function(styleName) {\n return escapeTextForBrowser(hyphenate(styleName));\n});\n\n/**\n * Operations for dealing with CSS properties.\n */\nvar CSSPropertyOperations = {\n\n /**\n * Serializes a mapping of style properties for use as inline styles:\n *\n * > createMarkupForStyles({width: '200px', height: 0})\n * \"width:200px;height:0;\"\n *\n * Undefined values are ignored so that declarative programming is easier.\n *\n * @param {object} styles\n * @return {?string}\n */\n createMarkupForStyles: function(styles) {\n var serialized = '';\n for (var styleName in styles) {\n if (!styles.hasOwnProperty(styleName)) {\n continue;\n }\n var styleValue = styles[styleName];\n if (styleValue != null) {\n serialized += processStyleName(styleName) + ':';\n serialized += dangerousStyleValue(styleName, styleValue) + ';';\n }\n }\n return serialized || null;\n },\n\n /**\n * Sets the value for multiple styles on a node. If a value is specified as\n * '' (empty string), the corresponding style property will be unset.\n *\n * @param {DOMElement} node\n * @param {object} styles\n */\n setValueForStyles: function(node, styles) {\n var style = node.style;\n for (var styleName in styles) {\n if (!styles.hasOwnProperty(styleName)) {\n continue;\n }\n var styleValue = dangerousStyleValue(styleName, styles[styleName]);\n if (styleValue) {\n style[styleName] = styleValue;\n } else {\n var expansion = CSSProperty.shorthandPropertyExpansions[styleName];\n if (expansion) {\n // Shorthand property that IE8 won't like unsetting, so unset each\n // component to placate it\n for (var individualStyleName in expansion) {\n style[individualStyleName] = '';\n }\n } else {\n style[styleName] = '';\n }\n }\n }\n }\n\n};\n\nmodule.exports = CSSPropertyOperations;\n\nrequire(\"./mock-modules\").register(\"CSSPropertyOperations\", module);\n", +"DOMProperty":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule DOMProperty\n * @typechecks static-only\n */\n\n/*jslint bitwise: true */\n\n\"use strict\";\n\nvar invariant = require(\"./invariant\");\n\nvar DOMPropertyInjection = {\n /**\n * Mapping from normalized, camelcased property names to a configuration that\n * specifies how the associated DOM property should be accessed or rendered.\n */\n MUST_USE_ATTRIBUTE: 0x1,\n MUST_USE_PROPERTY: 0x2,\n HAS_BOOLEAN_VALUE: 0x4,\n HAS_SIDE_EFFECTS: 0x8,\n\n /**\n * Inject some specialized knowledge about the DOM. This takes a config object\n * with the following properties:\n *\n * isCustomAttribute: function that given an attribute name will return true\n * if it can be inserted into the DOM verbatim. Useful for data-* or aria-*\n * attributes where it's impossible to enumerate all of the possible\n * attribute names,\n *\n * Properties: object mapping DOM property name to one of the\n * DOMPropertyInjection constants or null. If your attribute isn't in here,\n * it won't get written to the DOM.\n *\n * DOMAttributeNames: object mapping React attribute name to the DOM\n * attribute name. Attribute names not specified use the **lowercase**\n * normalized name.\n *\n * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.\n * Property names not specified use the normalized name.\n *\n * DOMMutationMethods: Properties that require special mutation methods. If\n * `value` is undefined, the mutation method should unset the property.\n *\n * @param {object} domPropertyConfig the config as described above.\n */\n injectDOMPropertyConfig: function(domPropertyConfig) {\n var Properties = domPropertyConfig.Properties || {};\n var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};\n var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};\n var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};\n\n if (domPropertyConfig.isCustomAttribute) {\n DOMProperty._isCustomAttributeFunctions.push(\n domPropertyConfig.isCustomAttribute\n );\n }\n\n for (var propName in Properties) {\n invariant(\n !DOMProperty.isStandardName[propName],\n 'injectDOMPropertyConfig(...): You\\'re trying to inject DOM property ' +\n '\\'%s\\' which has already been injected. You may be accidentally ' +\n 'injecting the same DOM property config twice, or you may be ' +\n 'injecting two configs that have conflicting property names.',\n propName\n );\n\n DOMProperty.isStandardName[propName] = true;\n\n var lowerCased = propName.toLowerCase();\n DOMProperty.getPossibleStandardName[lowerCased] = propName;\n\n var attributeName = DOMAttributeNames[propName];\n if (attributeName) {\n DOMProperty.getPossibleStandardName[attributeName] = propName;\n }\n\n DOMProperty.getAttributeName[propName] = attributeName || lowerCased;\n\n DOMProperty.getPropertyName[propName] =\n DOMPropertyNames[propName] || propName;\n\n var mutationMethod = DOMMutationMethods[propName];\n if (mutationMethod) {\n DOMProperty.getMutationMethod[propName] = mutationMethod;\n }\n\n var propConfig = Properties[propName];\n DOMProperty.mustUseAttribute[propName] =\n propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE;\n DOMProperty.mustUseProperty[propName] =\n propConfig & DOMPropertyInjection.MUST_USE_PROPERTY;\n DOMProperty.hasBooleanValue[propName] =\n propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE;\n DOMProperty.hasSideEffects[propName] =\n propConfig & DOMPropertyInjection.HAS_SIDE_EFFECTS;\n\n invariant(\n !DOMProperty.mustUseAttribute[propName] ||\n !DOMProperty.mustUseProperty[propName],\n 'DOMProperty: Cannot use require using both attribute and property: %s',\n propName\n );\n invariant(\n DOMProperty.mustUseProperty[propName] ||\n !DOMProperty.hasSideEffects[propName],\n 'DOMProperty: Properties that have side effects must use property: %s',\n propName\n );\n }\n }\n};\nvar defaultValueCache = {};\n\n/**\n * DOMProperty exports lookup objects that can be used like functions:\n *\n * > DOMProperty.isValid['id']\n * true\n * > DOMProperty.isValid['foobar']\n * undefined\n *\n * Although this may be confusing, it performs better in general.\n *\n * @see http://jsperf.com/key-exists\n * @see http://jsperf.com/key-missing\n */\nvar DOMProperty = {\n\n /**\n * Checks whether a property name is a standard property.\n * @type {Object}\n */\n isStandardName: {},\n\n /**\n * Mapping from lowercase property names to the properly cased version, used\n * to warn in the case of missing properties.\n * @type {Object}\n */\n getPossibleStandardName: {},\n\n /**\n * Mapping from normalized names to attribute names that differ. Attribute\n * names are used when rendering markup or with `*Attribute()`.\n * @type {Object}\n */\n getAttributeName: {},\n\n /**\n * Mapping from normalized names to properties on DOM node instances.\n * (This includes properties that mutate due to external factors.)\n * @type {Object}\n */\n getPropertyName: {},\n\n /**\n * Mapping from normalized names to mutation methods. This will only exist if\n * mutation cannot be set simply by the property or `setAttribute()`.\n * @type {Object}\n */\n getMutationMethod: {},\n\n /**\n * Whether the property must be accessed and mutated as an object property.\n * @type {Object}\n */\n mustUseAttribute: {},\n\n /**\n * Whether the property must be accessed and mutated using `*Attribute()`.\n * (This includes anything that fails ` in `.)\n * @type {Object}\n */\n mustUseProperty: {},\n\n /**\n * Whether the property should be removed when set to a falsey value.\n * @type {Object}\n */\n hasBooleanValue: {},\n\n /**\n * Whether or not setting a value causes side effects such as triggering\n * resources to be loaded or text selection changes. We must ensure that\n * the value is only set if it has changed.\n * @type {Object}\n */\n hasSideEffects: {},\n\n /**\n * All of the isCustomAttribute() functions that have been injected.\n */\n _isCustomAttributeFunctions: [],\n\n /**\n * Checks whether a property name is a custom attribute.\n * @method\n */\n isCustomAttribute: function(attributeName) {\n return DOMProperty._isCustomAttributeFunctions.some(\n function(isCustomAttributeFn) {\n return isCustomAttributeFn.call(null, attributeName);\n }\n );\n },\n\n /**\n * Returns the default property value for a DOM property (i.e., not an\n * attribute). Most default values are '' or false, but not all. Worse yet,\n * some (in particular, `type`) vary depending on the type of element.\n *\n * TODO: Is it better to grab all the possible properties when creating an\n * element to avoid having to create the same element twice?\n */\n getDefaultValueForProperty: function(nodeName, prop) {\n var nodeDefaults = defaultValueCache[nodeName];\n var testElement;\n if (!nodeDefaults) {\n defaultValueCache[nodeName] = nodeDefaults = {};\n }\n if (!(prop in nodeDefaults)) {\n testElement = document.createElement(nodeName);\n nodeDefaults[prop] = testElement[prop];\n }\n return nodeDefaults[prop];\n },\n\n injection: DOMPropertyInjection\n};\n\nmodule.exports = DOMProperty;\n\nrequire(\"./mock-modules\").register(\"DOMProperty\", module);\n", +"Danger":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule Danger\n * @typechecks static-only\n */\n\n/*jslint evil: true, sub: true */\n\n\"use strict\";\n\nvar ExecutionEnvironment = require(\"./ExecutionEnvironment\");\n\nvar createNodesFromMarkup = require(\"./createNodesFromMarkup\");\nvar emptyFunction = require(\"./emptyFunction\");\nvar getMarkupWrap = require(\"./getMarkupWrap\");\nvar invariant = require(\"./invariant\");\nvar mutateHTMLNodeWithMarkup = require(\"./mutateHTMLNodeWithMarkup\");\n\nvar OPEN_TAG_NAME_EXP = /^(<[^ \\/>]+)/;\nvar RESULT_INDEX_ATTR = 'data-danger-index';\n\n/**\n * Extracts the `nodeName` from a string of markup.\n *\n * NOTE: Extracting the `nodeName` does not require a regular expression match\n * because we make assumptions about React-generated markup (i.e. there are no\n * spaces surrounding the opening tag and there is at least one attribute).\n *\n * @param {string} markup String of markup.\n * @return {string} Node name of the supplied markup.\n * @see http://jsperf.com/extract-nodename\n */\nfunction getNodeName(markup) {\n return markup.substring(1, markup.indexOf(' '));\n}\n\nvar Danger = {\n\n /**\n * Renders markup into an array of nodes. The markup is expected to render\n * into a list of root nodes. Also, the length of `resultList` and\n * `markupList` should be the same.\n *\n * @param {array} markupList List of markup strings to render.\n * @return {array} List of rendered nodes.\n * @internal\n */\n dangerouslyRenderMarkup: function(markupList) {\n invariant(\n ExecutionEnvironment.canUseDOM,\n 'dangerouslyRenderMarkup(...): Cannot render markup in a Worker ' +\n 'thread. This is likely a bug in the framework. Please report ' +\n 'immediately.'\n );\n var nodeName;\n var markupByNodeName = {};\n // Group markup by `nodeName` if a wrap is necessary, else by '*'.\n for (var i = 0; i < markupList.length; i++) {\n invariant(\n markupList[i],\n 'dangerouslyRenderMarkup(...): Missing markup.'\n );\n nodeName = getNodeName(markupList[i]);\n nodeName = getMarkupWrap(nodeName) ? nodeName : '*';\n markupByNodeName[nodeName] = markupByNodeName[nodeName] || [];\n markupByNodeName[nodeName][i] = markupList[i];\n }\n var resultList = [];\n var resultListAssignmentCount = 0;\n for (nodeName in markupByNodeName) {\n if (!markupByNodeName.hasOwnProperty(nodeName)) {\n continue;\n }\n var markupListByNodeName = markupByNodeName[nodeName];\n\n // This for-in loop skips the holes of the sparse array. The order of\n // iteration should follow the order of assignment, which happens to match\n // numerical index order, but we don't rely on that.\n for (var resultIndex in markupListByNodeName) {\n if (markupListByNodeName.hasOwnProperty(resultIndex)) {\n var markup = markupListByNodeName[resultIndex];\n\n // Push the requested markup with an additional RESULT_INDEX_ATTR\n // attribute. If the markup does not start with a < character, it\n // will be discarded below (with an appropriate console.error).\n markupListByNodeName[resultIndex] = markup.replace(\n OPEN_TAG_NAME_EXP,\n // This index will be parsed back out below.\n '$1 ' + RESULT_INDEX_ATTR + '=\"' + resultIndex + '\" '\n );\n }\n }\n\n // Render each group of markup with similar wrapping `nodeName`.\n var renderNodes = createNodesFromMarkup(\n markupListByNodeName.join(''),\n emptyFunction // Do nothing special with + + + + + + + diff --git a/vendor/jasmine-jsreporter/jasmine-jsreporter.js b/vendor/jasmine-jsreporter/jasmine-jsreporter.js new file mode 100755 index 0000000000000..67eeea3fca97d --- /dev/null +++ b/vendor/jasmine-jsreporter/jasmine-jsreporter.js @@ -0,0 +1,161 @@ +/* + This file is part of the Jasmine JSReporter project from Ivan De Marino. + + Copyright (C) 2011 Ivan De Marino (aka detro, aka detronizator), http://blog.ivandemarino.me, ivan.de.marino@gmail.com + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL IVAN DE MARINO BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +(function () { + // Ensure that Jasmine library is loaded first + if (typeof jasmine === "undefined") { + throw new Error("[Jasmine JSReporter] 'Jasmine' library not found"); + } + + /** + * Calculate elapsed time, in Seconds. + * @param startMs Start time in Milliseconds + * @param finishMs Finish time in Milliseconds + * @return Elapsed time in Seconds */ + function elapsedSec (startMs, finishMs) { + return (finishMs - startMs) / 1000; + } + + /** + * Round an amount to the given number of Digits. + * If no number of digits is given, than '2' is assumed. + * @param amount Amount to round + * @param numOfDecDigits Number of Digits to round to. Default value is '2'. + * @return Rounded amount */ + function round (amount, numOfDecDigits) { + numOfDecDigits = numOfDecDigits || 2; + return Math.round(amount * Math.pow(10, numOfDecDigits)) / Math.pow(10, numOfDecDigits); + } + + /** + * Collect information about a Suite, recursively, and return a JSON result. + * @param suite The Jasmine Suite to get data from + */ + function getSuiteData (suite) { + var suiteData = { + description : suite.description, + durationSec : 0, + specs: [], + suites: [], + passed: true + }, + specs = suite.specs(), + suites = suite.suites(), + i, ilen; + + // Loop over all the Suite's Specs + for (i = 0, ilen = specs.length; i < ilen; ++i) { + suiteData.specs[i] = { + description : specs[i].description, + durationSec : specs[i].durationSec, + passed : specs[i].results().passedCount === specs[i].results().totalCount, + skipped : specs[i].results().skipped, + passedCount : specs[i].results().passedCount, + failedCount : specs[i].results().failedCount, + totalCount : specs[i].results().totalCount + }; + suiteData.passed = !suiteData.specs[i].passed ? false : suiteData.passed; + suiteData.durationSec += suiteData.specs[i].durationSec; + } + + // Loop over all the Suite's sub-Suites + for (i = 0, ilen = suites.length; i < ilen; ++i) { + suiteData.suites[i] = getSuiteData(suites[i]); //< recursive population + suiteData.passed = !suiteData.suites[i].passed ? false : suiteData.passed; + suiteData.durationSec += suiteData.suites[i].durationSec; + } + + // Rounding duration numbers to 3 decimal digits + suiteData.durationSec = round(suiteData.durationSec, 4); + + return suiteData; + } + + var JSReporter = function () { + }; + + JSReporter.prototype = { + reportRunnerStarting: function (runner) { + // Nothing to do + }, + + reportSpecStarting: function (spec) { + // Start timing this spec + spec.startedAt = new Date(); + }, + + reportSpecResults: function (spec) { + // Finish timing this spec and calculate duration/delta (in sec) + spec.finishedAt = new Date(); + spec.durationSec = elapsedSec(spec.startedAt.getTime(), spec.finishedAt.getTime()); + }, + + reportSuiteResults: function (suite) { + // Nothing to do + }, + + reportRunnerResults: function (runner) { + var suites = runner.suites(), + i, ilen; + + // Attach results to the "jasmine" object to make those results easy to scrap/find + jasmine.runnerResults = { + suites: [], + durationSec : 0, + passed : true + }; + + // Loop over all the Suites + for (i = 0, ilen = suites.length; i < ilen; ++i) { + if (suites[i].parentSuite === null) { + jasmine.runnerResults.suites[i] = getSuiteData(suites[i]); + // If 1 suite fails, the whole runner fails + jasmine.runnerResults.passed = !jasmine.runnerResults.suites[i].passed ? false : jasmine.runnerResults.passed; + // Add up all the durations + jasmine.runnerResults.durationSec += jasmine.runnerResults.suites[i].durationSec; + } + } + + // Decorate the 'jasmine' object with getters + jasmine.getJSReport = function () { + if (jasmine.runnerResults) { + return jasmine.runnerResults; + } + return null; + }; + jasmine.getJSReportAsString = function () { + return JSON.stringify(jasmine.getJSReport()); + }; + } + }; + + // export public + jasmine.JSReporter = JSReporter; +})(); + From 6a7a15cf30a81914dac3572dce41bc652138c489 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Tue, 29 Oct 2013 18:23:35 -0400 Subject: [PATCH 13/47] disable testling --- package.json | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/package.json b/package.json index 649e74c8b41ca..01495176fd226 100644 --- a/package.json +++ b/package.json @@ -35,30 +35,6 @@ "scripts": { "test": "grunt build && grunt test" }, - "testling": { - "scripts": [ - "test/browser-runner.js" - ], - "browsers": [ - "iexplore/10.0", - "iexplore/8.0", - "iexplore/9.0", - "chrome/21.0", - "chrome/29.0", - "chrome/canary", - "firefox/24.0", - "firefox/3.6", - "firefox/nightly", - "opera/15.0", - "opera/next", - "safari/5.0.5", - "safari/5.1", - "safari/6.0", - "ipad/6.0", - "iphone/6.0", - "android-browser/4.2" - ] - }, "dependencies": { "commoner": "~0.8.4", "esprima-fb": "~1001.1001.2000-dev-harmony-fb", From b111521f4026782da8b4515f14504e07f3783e0a Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Tue, 29 Oct 2013 18:45:56 -0400 Subject: [PATCH 14/47] Correct SauceLabs tokens --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 866c8089f4975..0f00ae082cb9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,5 +13,5 @@ env: - secure: qPvsJ46XzGrdIuPA70b55xQNGF8jcK7N1LN5CCQYYocXLa+fBrl+fTE77QvehOPhqwJXcj6kOxI+sY0KrVwV7gmq2XY2HZGWUSCxTN0SZlNIzqPA80Y7G/yOjA4PUt8LKgP+8tptyhTAY56qf+hgW8BoLiKOdztYF2p+3zXOLuA= # SECRET_TOKEN - secure: dkpPW+VnoqC/okhRdV90m36NcyBFhcwEKL3bNFExAwi0dXnFao8RoFlvnwiPlA23h2faROkMIetXlti6Aju08BgUFV+f9aL6vLyU7gUent4Nd3413zf2fwDtXIWIETg6uLnOpSykGKgCAT/hY3Q2oPLqOoY0OxfgnbqwxkxljrE= - - secure: EOPQOI/kPyv6Yw4prbFnmH/zexDMyTm9800iiItU8U287pIhD6r5xRqmShJ5astrSNsOMsogfSMGO85HvAkyhOSykmbeQe61V5vjzfcWXd8pR3cCGAS1/7ajBXmkI2CPD3UFNQAAXSQDIipgR5CC6yeuk3kubsVbVc2c3TIlAi4= - - secure: X8EKc78pIGcaIzAz11VYVZdMHqpg18ykDthtuxwcKsE3N60TBSTqYRA0ptR5QaqfYHm9VElXkWsUNiTZjqQiIjI6JCP7d3EpjmJJF4RjwQDhOFm9jgIqShJdk8RbftkrzPVx4sIaBTJQXoKfVK0CvNWrVHkWnIlUOS79xc7L2ZE= + - secure: eHMg4yQWJ+5zFxNcjVwpdpcbZCQMaSByqJy0wwQ2XOOMItdCvSfO/fa+mYoVND/9Orsi5kvXC9tx4sYHyth5hLrvO+bghYjiayrbxYYrxso6G/aU8Pttc7s/qk3I4zadLlua1kGy2TauByxS6nt9nUDe0FDaJKA9k1QXVlpq5Ac= + - secure: v65jUPPNBvJg1xhj4cY7wMKinCESUseHsW1d2gp68SluFHHyjWZOvXYXZdABqB/1uNmQxjbUkwkdSNAOn5k7ppjRcRnlAH2uu1xDqXrGp6cW4MfNPchrAe+FcUMtse/3THGJj8SZ9IQWIl+BHv4XASQ7FwqCR8cwlOfhsqdfch8= From 284d8d67bd32fcd3d83424575a2e2112bfbaeb89 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 13:25:13 -0400 Subject: [PATCH 15/47] Upgrade to the latest version of jasmine Necessary for IE8 support --- vendor/jasmine/jasmine-html.js | 2 -- vendor/jasmine/jasmine.js | 39 ++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/vendor/jasmine/jasmine-html.js b/vendor/jasmine/jasmine-html.js index 86688f32753f4..543d56963eb4a 100644 --- a/vendor/jasmine/jasmine-html.js +++ b/vendor/jasmine/jasmine-html.js @@ -1,5 +1,3 @@ -var jasmine = require("./jasmine"); - jasmine.HtmlReporterHelpers = {}; jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) { diff --git a/vendor/jasmine/jasmine.js b/vendor/jasmine/jasmine.js index 684c7cdf5b437..596411280c36a 100644 --- a/vendor/jasmine/jasmine.js +++ b/vendor/jasmine/jasmine.js @@ -1,10 +1,12 @@ +var isCommonJS = typeof window == "undefined" && typeof exports == "object"; + /** * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. * * @namespace */ var jasmine = {}; -exports = module.exports = jasmine; +if (isCommonJS) exports.jasmine = jasmine; /** * @private */ @@ -478,7 +480,7 @@ jasmine.log = function() { var spyOn = function(obj, methodName) { return jasmine.getEnv().currentSpec.spyOn(obj, methodName); }; -exports.spyOn = spyOn; +if (isCommonJS) exports.spyOn = spyOn; /** * Creates a Jasmine spec that will be added to the current suite. @@ -496,7 +498,7 @@ exports.spyOn = spyOn; var it = function(desc, func) { return jasmine.getEnv().it(desc, func); }; -exports.it = it; +if (isCommonJS) exports.it = it; /** * Creates a disabled Jasmine spec. @@ -509,7 +511,7 @@ exports.it = it; var xit = function(desc, func) { return jasmine.getEnv().xit(desc, func); }; -exports.xit = xit; +if (isCommonJS) exports.xit = xit; /** * Starts a chain for a Jasmine expectation. @@ -523,7 +525,7 @@ exports.xit = xit; var expect = function(actual) { return jasmine.getEnv().currentSpec.expect(actual); }; -exports.expect = expect; +if (isCommonJS) exports.expect = expect; /** * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. @@ -533,7 +535,7 @@ exports.expect = expect; var runs = function(func) { jasmine.getEnv().currentSpec.runs(func); }; -exports.runs = runs; +if (isCommonJS) exports.runs = runs; /** * Waits a fixed time period before moving to the next block. @@ -544,7 +546,7 @@ exports.runs = runs; var waits = function(timeout) { jasmine.getEnv().currentSpec.waits(timeout); }; -exports.waits = waits; +if (isCommonJS) exports.waits = waits; /** * Waits for the latchFunction to return true before proceeding to the next block. @@ -556,7 +558,7 @@ exports.waits = waits; var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); }; -exports.waitsFor = waitsFor; +if (isCommonJS) exports.waitsFor = waitsFor; /** * A function that is called before each spec in a suite. @@ -568,7 +570,7 @@ exports.waitsFor = waitsFor; var beforeEach = function(beforeEachFunction) { jasmine.getEnv().beforeEach(beforeEachFunction); }; -exports.beforeEach = beforeEach; +if (isCommonJS) exports.beforeEach = beforeEach; /** * A function that is called after each spec in a suite. @@ -580,7 +582,7 @@ exports.beforeEach = beforeEach; var afterEach = function(afterEachFunction) { jasmine.getEnv().afterEach(afterEachFunction); }; -exports.afterEach = afterEach; +if (isCommonJS) exports.afterEach = afterEach; /** * Defines a suite of specifications. @@ -600,7 +602,7 @@ exports.afterEach = afterEach; var describe = function(description, specDefinitions) { return jasmine.getEnv().describe(description, specDefinitions); }; -exports.describe = describe; +if (isCommonJS) exports.describe = describe; /** * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. @@ -611,7 +613,7 @@ exports.describe = describe; var xdescribe = function(description, specDefinitions) { return jasmine.getEnv().xdescribe(description, specDefinitions); }; -exports.xdescribe = xdescribe; +if (isCommonJS) exports.xdescribe = xdescribe; // Provide the XMLHttpRequest class for IE 5.x-6.x: @@ -871,10 +873,11 @@ jasmine.Env.prototype.it = function(description, func) { }; jasmine.Env.prototype.xit = function(desc, func) { - var spec = this.it(desc, func); - spec.results_.skipped = true; - spec.runs = function() {}; - return spec; + return { + id: this.nextSpecId(), + runs: function() { + } + }; }; jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) { @@ -2592,6 +2595,6 @@ jasmine.WaitsForBlock.prototype.execute = function(onComplete) { jasmine.version_= { "major": 1, "minor": 3, - "build": 1, - "revision": 1354556913 + "build": 0, + "revision": 1354052693 }; From 465b8dc6466443d991fcb11e562059d541b674d1 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 13:26:54 -0400 Subject: [PATCH 16/47] test server middleware for receiving test results --- Gruntfile.js | 2 +- grunt/config/server.js | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 041f8330b811d..e345293fae860 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,7 +17,7 @@ module.exports = function(grunt) { browserify: require('./grunt/config/browserify'), populist: require('./grunt/config/populist'), phantom: require('./grunt/config/phantom'), - connect: require('./grunt/config/server'), + connect: require('./grunt/config/server')(grunt), "saucelabs-jasmine": require('./grunt/config/saucelabs-jasmine'), npm: require('./grunt/config/npm'), clean: ['./build', './*.gem', './docs/_site', './examples/shared/*.js'], diff --git a/grunt/config/server.js b/grunt/config/server.js index ce6cb43ba4391..70a72cd3baf67 100644 --- a/grunt/config/server.js +++ b/grunt/config/server.js @@ -1,8 +1,37 @@ -module.exports = { - server: { - options: { - base: "", - port: 9999 +var pxlgif = Buffer('R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==', 'base64'); + +module.exports = function(grunt){ + + function printMiddleware(req, res, next) { + if (req._parsedUrl.pathname != '/print') return next(); + grunt[req.query.type || 'log'].writeln(req.query.message); + res.end(pxlgif); + } + function testResultLoggerMiddleware(req, res, next) { + if (!(req.body && req.body.data)) return next(); + grunt.log.writeln(req.body.data); + res.end('Got it, thanks!'); + } + + return { + server: { + options: { + base: '.', + hostname: '*', + port: 9999, + middleware: function(connect, options) { + return [ + connect.logger(':method :url - :referrer'), + + connect.query(), + printMiddleware, + connect.bodyParser(), + testResultLoggerMiddleware, + + connect.static(options.base) + ]; + }, + } } } } From 694cd6e9e83b73c90159e3e5d9f8d5393cd39321 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 13:27:37 -0400 Subject: [PATCH 17/47] test runner requires es5-shim --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 01495176fd226..bade43777339a 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,8 @@ "grunt-contrib-compress": "~0.5.1", "jasmine-tapreporter": "~0.2.2", "grunt-saucelabs": "~4.1.2", - "grunt-contrib-connect": "~0.5.0" + "grunt-contrib-connect": "~0.5.0", + "es5-shim": "~2.1.0" }, "engines": { "node": ">=0.10.0" From c4727944dff365a03f1ca8a58f25ceb7c7e6042f Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 13:28:51 -0400 Subject: [PATCH 18/47] Simple test result logger --- test/reportTestResults.browser.js | 75 +++++++++++++++++++++++++++++++ test/testImageURL.browser.js | 60 +++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 test/reportTestResults.browser.js create mode 100644 test/testImageURL.browser.js diff --git a/test/reportTestResults.browser.js b/test/reportTestResults.browser.js new file mode 100644 index 0000000000000..dfb2a254eefbb --- /dev/null +++ b/test/reportTestResults.browser.js @@ -0,0 +1,75 @@ +console._error = console.error; +console._warn = console.warn; +console._log = console.log; + +console.log = window.print = function(message){ + console._log(message); + testImageURL('/print?type=log&message=' + encodeURIComponent(message) + '&_=' + Date.now().toString(36)); +}; + +console.error = function(message){ + console._error(message); + testImageURL('/print?type=error&message=' + encodeURIComponent(message) + '&_=' + Date.now().toString(36)); +}; + +console.warn = function(message){ + console._warn(message); + testImageURL('/print?type=warn&message=' + encodeURIComponent(message) + '&_=' + Date.now().toString(36)); +}; + +;(function(env){ + + env.addReporter(new jasmine.JSReporter()); + env.addReporter(new TAPReporter(window.print)); + + function report(){ + if (typeof jasmine.getJSReport != 'function') return setTimeout(report, 100); + postDataToURL(JSON.stringify(jasmine.getJSReport()), '/reportTestResults', function(error, event){ + if (error) return console.error(error); + console.log(event); + }); + } + + var oldCallback = env.currentRunner().finishCallback; + env.currentRunner().finishCallback = function(){ + if (oldCallback) oldCallback.apply(this, arguments); + report(); + }; + + function postDataToURL(data, url, callback){ + var id = '$' + (+new Date()).toString(36); + + var postReportingTarget = document.createElement('iframe'); + postReportingTarget.id = postReportingTarget.name = 'postReportingTarget' + id; + + var postReportingForm = document.createElement('form'); + postReportingForm.method = 'POST'; + postReportingForm.action = url; + postReportingForm.target = postReportingTarget.name; + + var postReportingData = document.createElement('input'); + postReportingData.type = 'hidden'; + postReportingData.name = 'data'; + postReportingData.value = data || '{"error":"unknown error in postReportingData"}'; + + postReportingForm.appendChild(postReportingData); + postReportingForm.appendChild(postReportingTarget); + postReportingForm.style.cssText = "visibility:hidden; position:absolute; bottom:100%; right:100%"; + + function done(error, event){ + postReportingForm.parentNode.removeChild(postReportingForm); + callback(error, event); + } + + postReportingTarget.onerror = function(error){ + done(error); + } + postReportingTarget.onload = function(event){ + done(null, event); + } + document.body.appendChild(postReportingForm); + postReportingForm.submit(); + } + +}(window.jasmine.getEnv())); + diff --git a/test/testImageURL.browser.js b/test/testImageURL.browser.js new file mode 100644 index 0000000000000..8dc34d16f12a9 --- /dev/null +++ b/test/testImageURL.browser.js @@ -0,0 +1,60 @@ +testImageURL._recycle = function(img){ + console.log('_recycle', img); + try { + img.src = ''; + img.onload = img.onerror = null; + } catch(e){} + testImageURL._recycleBin.push(img); +} +testImageURL.getImage = function(callback){ + // if (!testImageURL._recycleBin) testImageURL._recycleBin = [new Image(),new Image(),new Image(),new Image()]; + // function get(){ + // if (testImageURL._recycleBin.length === 0) return setTimeout(get, 100); + // callback(testImageURL._recycleBin.shift(), testImageURL._recycle); + // } + // get(); + callback(new Image(), function recycle(){}); +} + +testImageURL.defaultCallback = function(error, event){} + +function testImageURL(url, timeout, callback){ + if (typeof timeout == 'function'){ + callback = timeout; + timeout = testImageURL.timeout; + } + if (typeof callback != 'function') callback = testImageURL.defaultCallback; + + testImageURL.getImage(function(img, done){ + function callbackWrapper(error, event){ + callbackWrapper = testImageURL.noop; + clearTimeout(timer); + done(img); + img = url = timeout = null; + callback(error, event); + error = event = callback = null; + } + + var timer = setTimeout(function(){callbackWrapper(Error('timeout'));}, timeout); + + try { + img.onload = function(event){ callbackWrapper(null, event || window.event); }; + img.onerror = function(error){ callbackWrapper(error); }; + img.src = url; + + if (img.complete === true + || img.readyState == 4 + || img.width > 0 + || img.height > 0 + || img.readyState == 'complete' + ) callbackWrapper(null, null); + } + catch(error){ + callbackWrapper(error); + } + }); +} + +testImageURL.noop = function(){}; + +testImageURL.timeout = 5000; From f65f7b3bbd756502a30f9c8c3f2957808b423481 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 14:25:21 -0400 Subject: [PATCH 19/47] IE8 support in jasmine-support --- vendor/jasmine/jasmine-support.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/jasmine/jasmine-support.js b/vendor/jasmine/jasmine-support.js index d6d1e3ef3b873..70cd6b3b14871 100644 --- a/vendor/jasmine/jasmine-support.js +++ b/vendor/jasmine/jasmine-support.js @@ -120,8 +120,8 @@ if (typeof WeakMap !== "undefined") { mismatchValues.push("arrays were not the same length"); } - _comparedObjects.delete(a); - _comparedObjects.delete(b); + _comparedObjects["delete"](a); + _comparedObjects["delete"](b); return (mismatchKeys.length == 0 && mismatchValues.length == 0); }; } From d64f34b5d849bb062f98316f16b95190348a0a62 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 14:27:34 -0400 Subject: [PATCH 20/47] inserted iframes can be targeted after a delay --- test/reportTestResults.browser.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/reportTestResults.browser.js b/test/reportTestResults.browser.js index dfb2a254eefbb..78e3fe08d24b1 100644 --- a/test/reportTestResults.browser.js +++ b/test/reportTestResults.browser.js @@ -68,7 +68,9 @@ console.warn = function(message){ done(null, event); } document.body.appendChild(postReportingForm); - postReportingForm.submit(); + setTimeout(function(){ + postReportingForm.submit(); + },0); } }(window.jasmine.getEnv())); From 46e86df420cd519d7fa37b2503e79b6dbb3a9323 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 14:28:07 -0400 Subject: [PATCH 21/47] move html reporter and its requirements --- test/jasmine-execute.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/jasmine-execute.js b/test/jasmine-execute.js index 3da6eb7e22d09..b0460e2508fd9 100644 --- a/test/jasmine-execute.js +++ b/test/jasmine-execute.js @@ -1,7 +1,7 @@ +document.write(''); + ;(function(env){ - env.addReporter(new TAPReporter(console.log.bind(console))); - env.addReporter(new jasmine.JSReporter()); - + env.addReporter(new jasmine.HtmlReporter); // Clean up any nodes the previous test might have added. env.afterEach(function() { harness.removeNextSiblings(document.body); From 7bbf6cbfd1dcdef65cfb5f3891b926066d2226d6 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 14:28:25 -0400 Subject: [PATCH 22/47] browser support for jasmine-support --- vendor/jasmine/jasmine-support.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/jasmine/jasmine-support.js b/vendor/jasmine/jasmine-support.js index 70cd6b3b14871..630d86651fa52 100644 --- a/vendor/jasmine/jasmine-support.js +++ b/vendor/jasmine/jasmine-support.js @@ -1,4 +1,4 @@ -var jasmine = require("./jasmine"); +if (typeof jasmine == 'undefined') jasmine = require("./jasmine"); var spec = false; // TODO // Add some matcher for mock functions From 2cd663940af6c936d94097df7654b96186fc66fa Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 14:28:43 -0400 Subject: [PATCH 23/47] don't double-log test results --- grunt/config/server.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/grunt/config/server.js b/grunt/config/server.js index 70a72cd3baf67..ceab3b2bc2b4f 100644 --- a/grunt/config/server.js +++ b/grunt/config/server.js @@ -21,13 +21,12 @@ module.exports = function(grunt){ port: 9999, middleware: function(connect, options) { return [ - connect.logger(':method :url - :referrer'), - connect.query(), printMiddleware, connect.bodyParser(), testResultLoggerMiddleware, + connect.logger(':method :url - :referrer'), connect.static(options.base) ]; }, From 93c0a46a1d872d3aac1227b58eba5114dba13db7 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 14:30:03 -0400 Subject: [PATCH 24/47] upgraded sauce harness Lost jasmine directly instead of using a module builder because it was failing in IE8 --- test/sauce-harness.html | 43 ++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/test/sauce-harness.html b/test/sauce-harness.html index 3e94b50a5dfdc..af3f51aa44758 100644 --- a/test/sauce-harness.html +++ b/test/sauce-harness.html @@ -1,21 +1,38 @@ - - + - - - - - - - From e086cbb44b5b9e452673d00c4942ef3a27fea1a5 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 14:31:50 -0400 Subject: [PATCH 25/47] separate grunt task for saucelabs browser testing --- Gruntfile.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index e345293fae860..0da397424bad9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -70,17 +70,15 @@ module.exports = function(grunt) { 'jsx:jasmine', 'jsx:test', 'version-check', - 'populist:jasmine', 'populist:test' ]); - grunt.registerTask('test', [ + grunt.registerTask('test:browser', [ 'build:test', - 'build:basic', - 'phantom:run', 'connect', 'saucelabs-jasmine' ]); + grunt.registerTask('test', ['build:test', 'build:basic', 'phantom:run']); grunt.registerTask('npm:test', ['build', 'npm:pack']); // Optimized build task that does all of our builds. The subtasks will be run From 0f274e5b225a9cdf4710cdd63f50a612f100cddf Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 18:58:25 -0400 Subject: [PATCH 26/47] new webdriver-jasmine task and config --- Gruntfile.js | 10 +++-- grunt/config/saucelabs-jasmine.js | 42 -------------------- grunt/config/webdriver-jasmine.js | 66 +++++++++++++++++++++++++++++++ grunt/tasks/webdriver-jasmine.js | 33 ++++++++++++++++ package.json | 4 +- 5 files changed, 108 insertions(+), 47 deletions(-) delete mode 100644 grunt/config/saucelabs-jasmine.js create mode 100644 grunt/config/webdriver-jasmine.js create mode 100644 grunt/tasks/webdriver-jasmine.js diff --git a/Gruntfile.js b/Gruntfile.js index 0da397424bad9..1423831567ce3 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,6 +5,7 @@ var jsxTask = require('./grunt/tasks/jsx'); var browserifyTask = require('./grunt/tasks/browserify'); var populistTask = require('./grunt/tasks/populist'); var phantomTask = require('./grunt/tasks/phantom'); +var webdriverJasmineTasks = require('./grunt/tasks/webdriver-jasmine.js'); var npmTask = require('./grunt/tasks/npm'); var releaseTasks = require('./grunt/tasks/release'); @@ -18,7 +19,7 @@ module.exports = function(grunt) { populist: require('./grunt/config/populist'), phantom: require('./grunt/config/phantom'), connect: require('./grunt/config/server')(grunt), - "saucelabs-jasmine": require('./grunt/config/saucelabs-jasmine'), + "webdriver-jasmine": require('./grunt/config/webdriver-jasmine.js'), npm: require('./grunt/config/npm'), clean: ['./build', './*.gem', './docs/_site', './examples/shared/*.js'], jshint: require('./grunt/config/jshint'), @@ -44,6 +45,8 @@ module.exports = function(grunt) { grunt.registerMultiTask('phantom', phantomTask); + grunt.registerMultiTask('webdriver-jasmine', webdriverJasmineTasks); + grunt.registerMultiTask('npm', npmTask); // Check that the version we're exporting is the same one we expect in the @@ -73,10 +76,9 @@ module.exports = function(grunt) { 'populist:test' ]); - grunt.registerTask('test:browser', [ - 'build:test', + grunt.registerTask('test:webdriver', [ 'connect', - 'saucelabs-jasmine' + 'webdriver-jasmine:local' ]); grunt.registerTask('test', ['build:test', 'build:basic', 'phantom:run']); grunt.registerTask('npm:test', ['build', 'npm:pack']); diff --git a/grunt/config/saucelabs-jasmine.js b/grunt/config/saucelabs-jasmine.js deleted file mode 100644 index 04c6cf9770ddd..0000000000000 --- a/grunt/config/saucelabs-jasmine.js +++ /dev/null @@ -1,42 +0,0 @@ -// https://saucelabs.com/docs/platforms - -var browsers = [ - { browserName: 'chrome', platform: 'linux' }, - - { browserName: 'android', platform: 'Linux', version: '4.0', 'device-type': 'tablet', 'device-orientation': 'portrait' }, - { browserName: 'android', platform: 'Linux', version: '4.0' }, - - { browserName: 'ipad', platform: 'OS X 10.6', version: '4' }, - { browserName: 'ipad', platform: 'OS X 10.8', version: '5.1' }, - { browserName: 'iphone', platform: 'OS X 10.8', version: '6.1' }, - - { browserName: 'firefox', version: '24', platform: 'Windows 7' }, - { browserName: 'firefox', version: '19', platform: 'Windows XP' }, - { browserName: 'firefox', version: '3', platform: 'Linux' }, - - { browserName: 'opera', platform: 'Windows 2008', version: '12' }, - - { browserName: 'internet explorer', platform: 'Windows 8', version: '10' }, - { browserName: 'internet explorer', platform: 'Windows 7', version: '9' }, - { browserName: 'internet explorer', platform: 'Windows 7', version: '8' }, - { browserName: 'internet explorer', platform: 'Windows XP', version: '8' }, - { browserName: 'internet explorer', platform: 'Windows XP', version: '7' }, - { browserName: 'internet explorer', platform: 'Windows XP', version: '6' }, - - { browserName: 'safari', platform: 'OS X 10.8', version: '6' }, - { browserName: 'safari', platform: 'OS X 10.6', version: '5' }, -]; - -module.exports = { - all: { - options: { - urls: ["http://127.0.0.1:9999/test/sauce-harness.html"], - tunnelTimeout: 5, - build: process.env.TRAVIS_JOB_ID || 'dev' + Date.now(), - concurrency: 3, - browsers: browsers, - testname: "React", - tags: ["master"] - } - } -} diff --git a/grunt/config/webdriver-jasmine.js b/grunt/config/webdriver-jasmine.js new file mode 100644 index 0000000000000..34b712a924d5c --- /dev/null +++ b/grunt/config/webdriver-jasmine.js @@ -0,0 +1,66 @@ +// https://saucelabs.com/docs/platforms + +var browsers = [ + { browserName: 'chrome', platform: 'linux' }, + + // { browserName: 'android', platform: 'Linux', version: '4.0', 'device-type': 'tablet', 'device-orientation': 'portrait' }, + // { browserName: 'android', platform: 'Linux', version: '4.0' }, + // + // { browserName: 'ipad', platform: 'OS X 10.6', version: '4' }, + // { browserName: 'ipad', platform: 'OS X 10.8', version: '5.1' }, + // { browserName: 'iphone', platform: 'OS X 10.8', version: '6.1' }, + // + // { browserName: 'firefox', version: '24', platform: 'Windows 7' }, + // { browserName: 'firefox', version: '19', platform: 'Windows XP' }, + // { browserName: 'firefox', version: '3', platform: 'Linux' }, + // + // { browserName: 'opera', platform: 'Windows 2008', version: '12' }, + // + // { browserName: 'internet explorer', platform: 'Windows 8', version: '10' }, + // { browserName: 'internet explorer', platform: 'Windows 7', version: '9' }, + // { browserName: 'internet explorer', platform: 'Windows 7', version: '8' }, + // { browserName: 'internet explorer', platform: 'Windows XP', version: '8' }, + // { browserName: 'internet explorer', platform: 'Windows XP', version: '7' }, + // { browserName: 'internet explorer', platform: 'Windows XP', version: '6' }, + // + // { browserName: 'safari', platform: 'OS X 10.8', version: '6' }, + // { browserName: 'safari', platform: 'OS X 10.6', version: '5' }, +]; + +exports.local = { + webdriver: { + remote: { + protocol: 'http:', + hostname: '127.0.0.1', + port: '9515', + path: '/' + } + }, + browser:{browserName:'chrome'}, + url: "http://127.0.0.1:9999/test/sauce-harness.html", + onComplete: function(report){ + var browser = this; + console.log('report.passed', report.passed) + } +} + +if (false) +exports.saucelabs = { + webdriver: { + remote:{ + // https://github.com/admc/wd/blob/master/README.md#named-parameters + user: process.env.SAUCE_USERNAME, + pwd: process.env.SAUCE_ACCESS_KEY, + + protocol: 'http:', + hostname: 'ondemand.saucelabs.com', + port: '80', + path: '/wd/hub' + } + }, + url: "http://127.0.0.1:9999/test/sauce-harness.html", + onComplete: function(report){ + var browser = this; + // .then(function(report){return browser.sauceJobStatus(report.passed);}) + } +} diff --git a/grunt/tasks/webdriver-jasmine.js b/grunt/tasks/webdriver-jasmine.js new file mode 100644 index 0000000000000..68237ad90650b --- /dev/null +++ b/grunt/tasks/webdriver-jasmine.js @@ -0,0 +1,33 @@ +var grunt = require("grunt"); +var wd = require('wd'); + +module.exports = function(){ + var taskSucceeded = this.async(); + var browser = wd.promiseChainRemote(this.data.webdriver.remote); + + browser.on('status', function(info) { + grunt.verbose.writeln(info); + }); + + browser.on('command', function(meth, path, data) { + grunt.verbose.writeln(' > ' + meth, path, data || ''); + }); + + browser + .init(this.data.browser) + .get(this.data.url) + .then(function(){return browser;}) + .then(getJSReport) + .then(this.data.onComplete.bind(browser), this.data.onError.bind(browser)) + .fin(browser.quit.bind(browser)) + .done(taskSucceeded.bind(null,true), taskSucceeded.bind(null,false)) + ; +} + +function getJSReport(browser){ + return browser + .waitForCondition("typeof window.jasmine != 'undefined'", 500) + .waitForCondition("typeof window.jasmine.getJSReport != 'undefined'", 10e3) + .eval("jasmine.getJSReport()") + ; +} diff --git a/package.json b/package.json index bade43777339a..f960e8665eff5 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,9 @@ "jasmine-tapreporter": "~0.2.2", "grunt-saucelabs": "~4.1.2", "grunt-contrib-connect": "~0.5.0", - "es5-shim": "~2.1.0" + "es5-shim": "~2.1.0", + "sauce-tunnel": "~1.0.2", + "wd": "~0.2.2" }, "engines": { "node": ">=0.10.0" From db299ed7614396d01a933bfb851be6e5906e598b Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 19:05:24 -0400 Subject: [PATCH 27/47] remove sauce labs stuff for now --- grunt/config/webdriver-jasmine.js | 50 ------------------------------- 1 file changed, 50 deletions(-) diff --git a/grunt/config/webdriver-jasmine.js b/grunt/config/webdriver-jasmine.js index 34b712a924d5c..e89da4f6b7cca 100644 --- a/grunt/config/webdriver-jasmine.js +++ b/grunt/config/webdriver-jasmine.js @@ -1,32 +1,3 @@ -// https://saucelabs.com/docs/platforms - -var browsers = [ - { browserName: 'chrome', platform: 'linux' }, - - // { browserName: 'android', platform: 'Linux', version: '4.0', 'device-type': 'tablet', 'device-orientation': 'portrait' }, - // { browserName: 'android', platform: 'Linux', version: '4.0' }, - // - // { browserName: 'ipad', platform: 'OS X 10.6', version: '4' }, - // { browserName: 'ipad', platform: 'OS X 10.8', version: '5.1' }, - // { browserName: 'iphone', platform: 'OS X 10.8', version: '6.1' }, - // - // { browserName: 'firefox', version: '24', platform: 'Windows 7' }, - // { browserName: 'firefox', version: '19', platform: 'Windows XP' }, - // { browserName: 'firefox', version: '3', platform: 'Linux' }, - // - // { browserName: 'opera', platform: 'Windows 2008', version: '12' }, - // - // { browserName: 'internet explorer', platform: 'Windows 8', version: '10' }, - // { browserName: 'internet explorer', platform: 'Windows 7', version: '9' }, - // { browserName: 'internet explorer', platform: 'Windows 7', version: '8' }, - // { browserName: 'internet explorer', platform: 'Windows XP', version: '8' }, - // { browserName: 'internet explorer', platform: 'Windows XP', version: '7' }, - // { browserName: 'internet explorer', platform: 'Windows XP', version: '6' }, - // - // { browserName: 'safari', platform: 'OS X 10.8', version: '6' }, - // { browserName: 'safari', platform: 'OS X 10.6', version: '5' }, -]; - exports.local = { webdriver: { remote: { @@ -43,24 +14,3 @@ exports.local = { console.log('report.passed', report.passed) } } - -if (false) -exports.saucelabs = { - webdriver: { - remote:{ - // https://github.com/admc/wd/blob/master/README.md#named-parameters - user: process.env.SAUCE_USERNAME, - pwd: process.env.SAUCE_ACCESS_KEY, - - protocol: 'http:', - hostname: 'ondemand.saucelabs.com', - port: '80', - path: '/wd/hub' - } - }, - url: "http://127.0.0.1:9999/test/sauce-harness.html", - onComplete: function(report){ - var browser = this; - // .then(function(report){return browser.sauceJobStatus(report.passed);}) - } -} From 772af52f4ae37a8358ddb407c034890894e96986 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 19:05:32 -0400 Subject: [PATCH 28/47] safer bind --- grunt/tasks/webdriver-jasmine.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grunt/tasks/webdriver-jasmine.js b/grunt/tasks/webdriver-jasmine.js index 68237ad90650b..125bfaf39ffd4 100644 --- a/grunt/tasks/webdriver-jasmine.js +++ b/grunt/tasks/webdriver-jasmine.js @@ -18,7 +18,7 @@ module.exports = function(){ .get(this.data.url) .then(function(){return browser;}) .then(getJSReport) - .then(this.data.onComplete.bind(browser), this.data.onError.bind(browser)) + .then(this.data.onComplete && this.data.onComplete.bind(browser), this.data.onError && this.data.onError.bind(browser)) .fin(browser.quit.bind(browser)) .done(taskSucceeded.bind(null,true), taskSucceeded.bind(null,false)) ; From b7250974099ed36e79c7907e55349d6defd71108 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 19:05:51 -0400 Subject: [PATCH 29/47] log using grunt --- grunt/config/server.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/grunt/config/server.js b/grunt/config/server.js index ceab3b2bc2b4f..d73e724266717 100644 --- a/grunt/config/server.js +++ b/grunt/config/server.js @@ -4,12 +4,18 @@ module.exports = function(grunt){ function printMiddleware(req, res, next) { if (req._parsedUrl.pathname != '/print') return next(); - grunt[req.query.type || 'log'].writeln(req.query.message); + if (req.query.message.indexOf('ok') === 0){ + grunt.log.ok(req.query.message); + } else if (req.query.message.indexOf('not ok') === 0){ + grunt.log.error(req.query.message); + } else { + grunt[req.query.type || 'log'].writeln('[%s][%s]', req.headers['user-agent'], Date.now(), req.query.message); + } res.end(pxlgif); } function testResultLoggerMiddleware(req, res, next) { if (!(req.body && req.body.data)) return next(); - grunt.log.writeln(req.body.data); + grunt.log.writeln('[%s][%s]', req.headers['user-agent'], Date.now(), req.body.data); res.end('Got it, thanks!'); } @@ -20,13 +26,17 @@ module.exports = function(grunt){ hostname: '*', port: 9999, middleware: function(connect, options) { + connect.logger.token('user-agent', function(req, res){ return req.headers['user-agent']; }); + connect.logger.token('timestamp', function(req, res){ return Date.now(); }); + return [ connect.query(), printMiddleware, + + connect.logger({format:'[:user-agent][:timestamp] :method :url', stream:grunt.verbose}), connect.bodyParser(), testResultLoggerMiddleware, - connect.logger(':method :url - :referrer'), connect.static(options.base) ]; }, From 2b273d856854a3f1740b38730f7797c29508739d Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 31 Oct 2013 19:06:01 -0400 Subject: [PATCH 30/47] remove saucelabs for now --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index f960e8665eff5..6b982e35e3478 100644 --- a/package.json +++ b/package.json @@ -58,10 +58,8 @@ "tmp": "~0.0.18", "grunt-contrib-compress": "~0.5.1", "jasmine-tapreporter": "~0.2.2", - "grunt-saucelabs": "~4.1.2", "grunt-contrib-connect": "~0.5.0", "es5-shim": "~2.1.0", - "sauce-tunnel": "~1.0.2", "wd": "~0.2.2" }, "engines": { From 2d979a9ce995b1a85216ac0233ad1b04b610fa1a Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 15:11:00 -0500 Subject: [PATCH 31/47] cleanup --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 1423831567ce3..4234e3dfb978f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,7 +5,7 @@ var jsxTask = require('./grunt/tasks/jsx'); var browserifyTask = require('./grunt/tasks/browserify'); var populistTask = require('./grunt/tasks/populist'); var phantomTask = require('./grunt/tasks/phantom'); -var webdriverJasmineTasks = require('./grunt/tasks/webdriver-jasmine.js'); +var webdriverJasmineTasks = require('./grunt/tasks/webdriver-jasmine'); var npmTask = require('./grunt/tasks/npm'); var releaseTasks = require('./grunt/tasks/release'); From 71772e763a929bbc3dba0b4c6f8de895a3a7d385 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 15:12:17 -0500 Subject: [PATCH 32/47] grunt task launch phantomjs as a webdriver server --- Gruntfile.js | 3 +++ grunt/tasks/webdriver-phantomjs.js | 37 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 grunt/tasks/webdriver-phantomjs.js diff --git a/Gruntfile.js b/Gruntfile.js index 4234e3dfb978f..fbc5c46ea650d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,6 +5,7 @@ var jsxTask = require('./grunt/tasks/jsx'); var browserifyTask = require('./grunt/tasks/browserify'); var populistTask = require('./grunt/tasks/populist'); var phantomTask = require('./grunt/tasks/phantom'); +var webdriverPhantomJSTask = require('./grunt/tasks/webdriver-phantomjs'); var webdriverJasmineTasks = require('./grunt/tasks/webdriver-jasmine'); var npmTask = require('./grunt/tasks/npm'); var releaseTasks = require('./grunt/tasks/release'); @@ -76,6 +77,8 @@ module.exports = function(grunt) { 'populist:test' ]); + grunt.registerTask('webdriver-phantomjs', webdriverPhantomJSTask); + grunt.registerTask('test:webdriver', [ 'connect', 'webdriver-jasmine:local' diff --git a/grunt/tasks/webdriver-phantomjs.js b/grunt/tasks/webdriver-phantomjs.js new file mode 100644 index 0000000000000..0f841b633e33e --- /dev/null +++ b/grunt/tasks/webdriver-phantomjs.js @@ -0,0 +1,37 @@ +var grunt = require('grunt'); + +module.exports = function(){ + var onReadyCallback = this.async(); + + var phantomjs = require("phantomjs").path; + var child_process = require('child_process'); + var config = this.data || {}; + + var args = ["--webdriver=" + (config.port || 9515)]; + grunt.verbose.writeln('phantomjs START path:%s args:%s', phantomjs, args); + + var child = child_process.spawn(phantomjs, args); + process.on('exit', function() { + child.kill(); + }); + + child.on('error', function(error) { + grunt.verbose.writeln('phantomjs ERROR'); + grunt.fatal(error); + }); + child.on('exit', function(code) { + grunt.verbose.writeln('phantomjs END'); + if (code) grunt.fatal('phantomjs FAIL'); + }); + + function verboseWrite(chunk) { + if (onReadyCallback && chunk.toString().indexOf('running on port') != -1) { + grunt.verbose.writeln('phantomjs STARTED'); + onReadyCallback(); + onReadyCallback = null; + } + grunt.verbose.write(chunk); + } + child.stdout.on('data', verboseWrite); + child.stderr.on('data', verboseWrite); +} From c780985d3e9bd56143ebe3916dd7e37583fac72f Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 15:13:39 -0500 Subject: [PATCH 33/47] wait for all results to finish sending --- grunt/tasks/webdriver-jasmine.js | 1 + 1 file changed, 1 insertion(+) diff --git a/grunt/tasks/webdriver-jasmine.js b/grunt/tasks/webdriver-jasmine.js index 125bfaf39ffd4..c08d792305d16 100644 --- a/grunt/tasks/webdriver-jasmine.js +++ b/grunt/tasks/webdriver-jasmine.js @@ -28,6 +28,7 @@ function getJSReport(browser){ return browser .waitForCondition("typeof window.jasmine != 'undefined'", 500) .waitForCondition("typeof window.jasmine.getJSReport != 'undefined'", 10e3) + .waitForCondition("window.testImageURL.running <= 0", 5e3) .eval("jasmine.getJSReport()") ; } From 1368b2959687adfadc06dd21f19d05ea716480a3 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 15:16:58 -0500 Subject: [PATCH 34/47] cleanup webdriver jasmine task --- grunt/tasks/webdriver-jasmine.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/grunt/tasks/webdriver-jasmine.js b/grunt/tasks/webdriver-jasmine.js index c08d792305d16..bd998dfcb7787 100644 --- a/grunt/tasks/webdriver-jasmine.js +++ b/grunt/tasks/webdriver-jasmine.js @@ -2,8 +2,10 @@ var grunt = require("grunt"); var wd = require('wd'); module.exports = function(){ + var config = this.data; var taskSucceeded = this.async(); - var browser = wd.promiseChainRemote(this.data.webdriver.remote); + grunt.verbose.write('webdriver remote', JSON.stringify(config.webdriver.remote)); + var browser = wd.promiseChainRemote(config.webdriver.remote); browser.on('status', function(info) { grunt.verbose.writeln(info); @@ -14,13 +16,21 @@ module.exports = function(){ }); browser - .init(this.data.browser) - .get(this.data.url) + .init(config.browser || {}) + .get(config.url) .then(function(){return browser;}) .then(getJSReport) - .then(this.data.onComplete && this.data.onComplete.bind(browser), this.data.onError && this.data.onError.bind(browser)) - .fin(browser.quit.bind(browser)) - .done(taskSucceeded.bind(null,true), taskSucceeded.bind(null,false)) + .then(config.onComplete && config.onComplete.bind(browser), config.onError && config.onError.bind(browser)) + .fail(grunt.verbose.writeln.bind(grunt.verbose)) + .fin(function(){ + if (grunt.option('webdriver-keep-open')) return; + grunt.verbose.writeln('Closing the browser window. To keep it open, pass the --webdriver-keep-open flag to grunt.'); + return browser.quit(); + }) + .done( + taskSucceeded.bind(null,true), + taskSucceeded.bind(null,false) + ) ; } From 159d64ddd3e42a06473c347f418bad6678fe1a02 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 15:17:04 -0500 Subject: [PATCH 35/47] cleanup --- test/reportTestResults.browser.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/reportTestResults.browser.js b/test/reportTestResults.browser.js index 78e3fe08d24b1..de65053399d9e 100644 --- a/test/reportTestResults.browser.js +++ b/test/reportTestResults.browser.js @@ -26,7 +26,6 @@ console.warn = function(message){ if (typeof jasmine.getJSReport != 'function') return setTimeout(report, 100); postDataToURL(JSON.stringify(jasmine.getJSReport()), '/reportTestResults', function(error, event){ if (error) return console.error(error); - console.log(event); }); } From dfb4dde8fdedd6a9df3026afae2acb9fa9288ca3 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 15:17:59 -0500 Subject: [PATCH 36/47] keep track of incomplete --- test/testImageURL.browser.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/testImageURL.browser.js b/test/testImageURL.browser.js index 8dc34d16f12a9..b02dd899a65bf 100644 --- a/test/testImageURL.browser.js +++ b/test/testImageURL.browser.js @@ -28,6 +28,7 @@ function testImageURL(url, timeout, callback){ testImageURL.getImage(function(img, done){ function callbackWrapper(error, event){ callbackWrapper = testImageURL.noop; + testImageURL.running = (testImageURL.running || 0) - 1; clearTimeout(timer); done(img); img = url = timeout = null; @@ -41,6 +42,7 @@ function testImageURL(url, timeout, callback){ img.onload = function(event){ callbackWrapper(null, event || window.event); }; img.onerror = function(error){ callbackWrapper(error); }; img.src = url; + testImageURL.running = (testImageURL.running || 0) + 1; if (img.complete === true || img.readyState == 4 From 3e2d3e48375af253fa85243f13bcb5492fd74875 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 15:19:17 -0500 Subject: [PATCH 37/47] add logging to webdriver config --- grunt/config/webdriver-jasmine.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/grunt/config/webdriver-jasmine.js b/grunt/config/webdriver-jasmine.js index e89da4f6b7cca..747b7214eb54c 100644 --- a/grunt/config/webdriver-jasmine.js +++ b/grunt/config/webdriver-jasmine.js @@ -1,16 +1,18 @@ +var grunt = require('grunt'); + + exports.local = { webdriver: { - remote: { - protocol: 'http:', - hostname: '127.0.0.1', - port: '9515', - path: '/' - } + remote: { protocol: 'http:', hostname: '127.0.0.1', port: 9515, path: '/' } }, - browser:{browserName:'chrome'}, url: "http://127.0.0.1:9999/test/sauce-harness.html", onComplete: function(report){ var browser = this; - console.log('report.passed', report.passed) + if (!report.passed){ + grunt.fatal("tests failed"); + } + }, + onError: function(error){ + grunt.fatal(error); } } From be7ee1ee6506fdc5423eb312e7c83de8333c86af Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 15:19:40 -0500 Subject: [PATCH 38/47] start a local webdriver server before using it --- Gruntfile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Gruntfile.js b/Gruntfile.js index fbc5c46ea650d..81f09ab87cbac 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -81,6 +81,7 @@ module.exports = function(grunt) { grunt.registerTask('test:webdriver', [ 'connect', + 'webdriver-phantomjs', 'webdriver-jasmine:local' ]); grunt.registerTask('test', ['build:test', 'build:basic', 'phantom:run']); From f4d487fb59a3c539365d3c13a8f24771bef5f4d0 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 15:30:29 -0500 Subject: [PATCH 39/47] removed compiled build files Not necessary now that we aren't supporting testling. --- build/jasmine.js | 74 - build/react-test.js | 266 - build/react.js | 14277 ------------------------------------------ 3 files changed, 14617 deletions(-) delete mode 100644 build/jasmine.js delete mode 100644 build/react-test.js delete mode 100644 build/react.js diff --git a/build/jasmine.js b/build/jasmine.js deleted file mode 100644 index 74b6dd64e212a..0000000000000 --- a/build/jasmine.js +++ /dev/null @@ -1,74 +0,0 @@ -//# sourceURL=populist/loader.js -(function(entries, sources) { - var modules = {}; - var hasOwn = modules.hasOwnProperty; - var global = Function("return this")(); - var doc = global.document; - var head = doc.documentElement.firstChild; - - function internalRequire(id) { - var module = getModule(id); - if (module && !hasOwn.call(module, "exports")) { - module(function(rid) { - return internalRequire(absolutize(id, rid)); - }, module.exports = {}, module, global); - - // If the module id has a non-null value in the entries object, - // define a global reference to its exports object. - var globalName = entries[id]; - if (globalName && hasOwn.call(entries, id)) - global[globalName] = module.exports; - } - - return module.exports; - } - - function getModule(id) { - if (!hasOwn.call(modules, id)) { - if (hasOwn.call(sources, id)) { - var name = "module$" + Math.random().toString(36).slice(2); - var script = doc.createElement("script"); - var code = "function " + name + "(require,exports,module,global){" + - sources[id] + "\n}\n//# sourceURL=" + id + ".js\n"; - script.setAttribute("type", "text/javascript"); - script.setAttribute("encoding", "utf8"); - script.appendChild(doc.createTextNode(code)); - head.appendChild(script); - modules[id] = global[name]; - } else { - throw new Error("Missing module: " + id); - } - } - - return modules[id]; - } - - var pathNormExp = /\/(\.?|[^\/]+\/\.\.)\//; - function absolutize(id, rid) { - if (rid.charAt(0) === ".") { - rid = "/" + id + "/../" + rid; - while (rid != (id = rid.replace(pathNormExp, "/"))) - rid = id; - rid = rid.replace(/^\//, ""); - } - return rid; - } - - // Eagerly require all identifiers that are keys of the entries object. - for (var id in entries) - if (hasOwn.call(entries, id)) - internalRequire(id); -})({"jasmine":"jasmine","all":null},{ -"jasmine":"/**\n * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.\n *\n * @namespace\n */\nvar jasmine = {};\nexports = module.exports = jasmine;\n/**\n * @private\n */\njasmine.unimplementedMethod_ = function() {\n throw new Error(\"unimplemented method\");\n};\n\n/**\n * Use jasmine.undefined instead of undefined, since undefined is just\n * a plain old variable and may be redefined by somebody else.\n *\n * @private\n */\njasmine.undefined = jasmine.___undefined___;\n\n/**\n * Show diagnostic messages in the console if set to true\n *\n */\njasmine.VERBOSE = false;\n\n/**\n * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.\n *\n */\njasmine.DEFAULT_UPDATE_INTERVAL = 250;\n\n/**\n * Maximum levels of nesting that will be included when an object is pretty-printed\n */\njasmine.MAX_PRETTY_PRINT_DEPTH = 40;\n\n/**\n * Default timeout interval in milliseconds for waitsFor() blocks.\n */\njasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;\n\n/**\n * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.\n * Set to false to let the exception bubble up in the browser.\n *\n */\njasmine.CATCH_EXCEPTIONS = true;\n\njasmine.getGlobal = function() {\n function getGlobal() {\n return this;\n }\n\n return getGlobal();\n};\n\n/**\n * Allows for bound functions to be compared. Internal use only.\n *\n * @ignore\n * @private\n * @param base {Object} bound 'this' for the function\n * @param name {Function} function to find\n */\njasmine.bindOriginal_ = function(base, name) {\n var original = base[name];\n if (original.apply) {\n return function() {\n return original.apply(base, arguments);\n };\n } else {\n // IE support\n return jasmine.getGlobal()[name];\n }\n};\n\njasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');\njasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');\njasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');\njasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');\n\njasmine.MessageResult = function(values) {\n this.type = 'log';\n this.values = values;\n this.trace = new Error(); // todo: test better\n};\n\njasmine.MessageResult.prototype.toString = function() {\n var text = \"\";\n for (var i = 0; i < this.values.length; i++) {\n if (i > 0) text += \" \";\n if (jasmine.isString_(this.values[i])) {\n text += this.values[i];\n } else {\n text += jasmine.pp(this.values[i]);\n }\n }\n return text;\n};\n\njasmine.ExpectationResult = function(params) {\n this.type = 'expect';\n this.matcherName = params.matcherName;\n this.passed_ = params.passed;\n this.expected = params.expected;\n this.actual = params.actual;\n this.message = this.passed_ ? 'Passed.' : params.message;\n\n var trace = (params.trace || new Error(this.message));\n this.trace = this.passed_ ? '' : trace;\n};\n\njasmine.ExpectationResult.prototype.toString = function () {\n return this.message;\n};\n\njasmine.ExpectationResult.prototype.passed = function () {\n return this.passed_;\n};\n\n/**\n * Getter for the Jasmine environment. Ensures one gets created\n */\njasmine.getEnv = function() {\n var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();\n return env;\n};\n\n/**\n * @ignore\n * @private\n * @param value\n * @returns {Boolean}\n */\njasmine.isArray_ = function(value) {\n return jasmine.isA_(\"Array\", value);\n};\n\n/**\n * @ignore\n * @private\n * @param value\n * @returns {Boolean}\n */\njasmine.isString_ = function(value) {\n return jasmine.isA_(\"String\", value);\n};\n\n/**\n * @ignore\n * @private\n * @param value\n * @returns {Boolean}\n */\njasmine.isNumber_ = function(value) {\n return jasmine.isA_(\"Number\", value);\n};\n\n/**\n * @ignore\n * @private\n * @param {String} typeName\n * @param value\n * @returns {Boolean}\n */\njasmine.isA_ = function(typeName, value) {\n return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';\n};\n\n/**\n * Pretty printer for expecations. Takes any object and turns it into a human-readable string.\n *\n * @param value {Object} an object to be outputted\n * @returns {String}\n */\njasmine.pp = function(value) {\n var stringPrettyPrinter = new jasmine.StringPrettyPrinter();\n stringPrettyPrinter.format(value);\n return stringPrettyPrinter.string;\n};\n\n/**\n * Returns true if the object is a DOM Node.\n *\n * @param {Object} obj object to check\n * @returns {Boolean}\n */\njasmine.isDomNode = function(obj) {\n return obj.nodeType > 0;\n};\n\n/**\n * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.\n *\n * @example\n * // don't care about which function is passed in, as long as it's a function\n * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));\n *\n * @param {Class} clazz\n * @returns matchable object of the type clazz\n */\njasmine.any = function(clazz) {\n return new jasmine.Matchers.Any(clazz);\n};\n\n/**\n * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the\n * attributes on the object.\n *\n * @example\n * // don't care about any other attributes than foo.\n * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: \"bar\"});\n *\n * @param sample {Object} sample\n * @returns matchable object for the sample\n */\njasmine.objectContaining = function (sample) {\n return new jasmine.Matchers.ObjectContaining(sample);\n};\n\n/**\n * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.\n *\n * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine\n * expectation syntax. Spies can be checked if they were called or not and what the calling params were.\n *\n * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).\n *\n * Spies are torn down at the end of every spec.\n *\n * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.\n *\n * @example\n * // a stub\n * var myStub = jasmine.createSpy('myStub'); // can be used anywhere\n *\n * // spy example\n * var foo = {\n * not: function(bool) { return !bool; }\n * }\n *\n * // actual foo.not will not be called, execution stops\n * spyOn(foo, 'not');\n\n // foo.not spied upon, execution will continue to implementation\n * spyOn(foo, 'not').andCallThrough();\n *\n * // fake example\n * var foo = {\n * not: function(bool) { return !bool; }\n * }\n *\n * // foo.not(val) will return val\n * spyOn(foo, 'not').andCallFake(function(value) {return value;});\n *\n * // mock example\n * foo.not(7 == 7);\n * expect(foo.not).toHaveBeenCalled();\n * expect(foo.not).toHaveBeenCalledWith(true);\n *\n * @constructor\n * @see spyOn, jasmine.createSpy, jasmine.createSpyObj\n * @param {String} name\n */\njasmine.Spy = function(name) {\n /**\n * The name of the spy, if provided.\n */\n this.identity = name || 'unknown';\n /**\n * Is this Object a spy?\n */\n this.isSpy = true;\n /**\n * The actual function this spy stubs.\n */\n this.plan = function() {\n };\n /**\n * Tracking of the most recent call to the spy.\n * @example\n * var mySpy = jasmine.createSpy('foo');\n * mySpy(1, 2);\n * mySpy.mostRecentCall.args = [1, 2];\n */\n this.mostRecentCall = {};\n\n /**\n * Holds arguments for each call to the spy, indexed by call count\n * @example\n * var mySpy = jasmine.createSpy('foo');\n * mySpy(1, 2);\n * mySpy(7, 8);\n * mySpy.mostRecentCall.args = [7, 8];\n * mySpy.argsForCall[0] = [1, 2];\n * mySpy.argsForCall[1] = [7, 8];\n */\n this.argsForCall = [];\n this.calls = [];\n};\n\n/**\n * Tells a spy to call through to the actual implemenatation.\n *\n * @example\n * var foo = {\n * bar: function() { // do some stuff }\n * }\n *\n * // defining a spy on an existing property: foo.bar\n * spyOn(foo, 'bar').andCallThrough();\n */\njasmine.Spy.prototype.andCallThrough = function() {\n this.plan = this.originalValue;\n return this;\n};\n\n/**\n * For setting the return value of a spy.\n *\n * @example\n * // defining a spy from scratch: foo() returns 'baz'\n * var foo = jasmine.createSpy('spy on foo').andReturn('baz');\n *\n * // defining a spy on an existing property: foo.bar() returns 'baz'\n * spyOn(foo, 'bar').andReturn('baz');\n *\n * @param {Object} value\n */\njasmine.Spy.prototype.andReturn = function(value) {\n this.plan = function() {\n return value;\n };\n return this;\n};\n\n/**\n * For throwing an exception when a spy is called.\n *\n * @example\n * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'\n * var foo = jasmine.createSpy('spy on foo').andThrow('baz');\n *\n * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'\n * spyOn(foo, 'bar').andThrow('baz');\n *\n * @param {String} exceptionMsg\n */\njasmine.Spy.prototype.andThrow = function(exceptionMsg) {\n this.plan = function() {\n throw exceptionMsg;\n };\n return this;\n};\n\n/**\n * Calls an alternate implementation when a spy is called.\n *\n * @example\n * var baz = function() {\n * // do some stuff, return something\n * }\n * // defining a spy from scratch: foo() calls the function baz\n * var foo = jasmine.createSpy('spy on foo').andCall(baz);\n *\n * // defining a spy on an existing property: foo.bar() calls an anonymnous function\n * spyOn(foo, 'bar').andCall(function() { return 'baz';} );\n *\n * @param {Function} fakeFunc\n */\njasmine.Spy.prototype.andCallFake = function(fakeFunc) {\n this.plan = fakeFunc;\n return this;\n};\n\n/**\n * Resets all of a spy's the tracking variables so that it can be used again.\n *\n * @example\n * spyOn(foo, 'bar');\n *\n * foo.bar();\n *\n * expect(foo.bar.callCount).toEqual(1);\n *\n * foo.bar.reset();\n *\n * expect(foo.bar.callCount).toEqual(0);\n */\njasmine.Spy.prototype.reset = function() {\n this.wasCalled = false;\n this.callCount = 0;\n this.argsForCall = [];\n this.calls = [];\n this.mostRecentCall = {};\n};\n\njasmine.createSpy = function(name) {\n\n var spyObj = function() {\n spyObj.wasCalled = true;\n spyObj.callCount++;\n var args = jasmine.util.argsToArray(arguments);\n spyObj.mostRecentCall.object = this;\n spyObj.mostRecentCall.args = args;\n spyObj.argsForCall.push(args);\n spyObj.calls.push({object: this, args: args});\n return spyObj.plan.apply(this, arguments);\n };\n\n var spy = new jasmine.Spy(name);\n\n for (var prop in spy) {\n spyObj[prop] = spy[prop];\n }\n\n spyObj.reset();\n\n return spyObj;\n};\n\n/**\n * Determines whether an object is a spy.\n *\n * @param {jasmine.Spy|Object} putativeSpy\n * @returns {Boolean}\n */\njasmine.isSpy = function(putativeSpy) {\n return putativeSpy && putativeSpy.isSpy;\n};\n\n/**\n * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something\n * large in one call.\n *\n * @param {String} baseName name of spy class\n * @param {Array} methodNames array of names of methods to make spies\n */\njasmine.createSpyObj = function(baseName, methodNames) {\n if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {\n throw new Error('createSpyObj requires a non-empty array of method names to create spies for');\n }\n var obj = {};\n for (var i = 0; i < methodNames.length; i++) {\n obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);\n }\n return obj;\n};\n\n/**\n * All parameters are pretty-printed and concatenated together, then written to the current spec's output.\n *\n * Be careful not to leave calls to jasmine.log in production code.\n */\njasmine.log = function() {\n var spec = jasmine.getEnv().currentSpec;\n spec.log.apply(spec, arguments);\n};\n\n/**\n * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.\n *\n * @example\n * // spy example\n * var foo = {\n * not: function(bool) { return !bool; }\n * }\n * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops\n *\n * @see jasmine.createSpy\n * @param obj\n * @param methodName\n * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods\n */\nvar spyOn = function(obj, methodName) {\n return jasmine.getEnv().currentSpec.spyOn(obj, methodName);\n};\nexports.spyOn = spyOn;\n\n/**\n * Creates a Jasmine spec that will be added to the current suite.\n *\n * // TODO: pending tests\n *\n * @example\n * it('should be true', function() {\n * expect(true).toEqual(true);\n * });\n *\n * @param {String} desc description of this specification\n * @param {Function} func defines the preconditions and expectations of the spec\n */\nvar it = function(desc, func) {\n return jasmine.getEnv().it(desc, func);\n};\nexports.it = it;\n\n/**\n * Creates a disabled Jasmine spec.\n *\n * A convenience method that allows existing specs to be disabled temporarily during development.\n *\n * @param {String} desc description of this specification\n * @param {Function} func defines the preconditions and expectations of the spec\n */\nvar xit = function(desc, func) {\n return jasmine.getEnv().xit(desc, func);\n};\nexports.xit = xit;\n\n/**\n * Starts a chain for a Jasmine expectation.\n *\n * It is passed an Object that is the actual value and should chain to one of the many\n * jasmine.Matchers functions.\n *\n * @param {Object} actual Actual value to test against and expected value\n * @return {jasmine.Matchers}\n */\nvar expect = function(actual) {\n return jasmine.getEnv().currentSpec.expect(actual);\n};\nexports.expect = expect;\n\n/**\n * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.\n *\n * @param {Function} func Function that defines part of a jasmine spec.\n */\nvar runs = function(func) {\n jasmine.getEnv().currentSpec.runs(func);\n};\nexports.runs = runs;\n\n/**\n * Waits a fixed time period before moving to the next block.\n *\n * @deprecated Use waitsFor() instead\n * @param {Number} timeout milliseconds to wait\n */\nvar waits = function(timeout) {\n jasmine.getEnv().currentSpec.waits(timeout);\n};\nexports.waits = waits;\n\n/**\n * Waits for the latchFunction to return true before proceeding to the next block.\n *\n * @param {Function} latchFunction\n * @param {String} optional_timeoutMessage\n * @param {Number} optional_timeout\n */\nvar waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {\n jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);\n};\nexports.waitsFor = waitsFor;\n\n/**\n * A function that is called before each spec in a suite.\n *\n * Used for spec setup, including validating assumptions.\n *\n * @param {Function} beforeEachFunction\n */\nvar beforeEach = function(beforeEachFunction) {\n jasmine.getEnv().beforeEach(beforeEachFunction);\n};\nexports.beforeEach = beforeEach;\n\n/**\n * A function that is called after each spec in a suite.\n *\n * Used for restoring any state that is hijacked during spec execution.\n *\n * @param {Function} afterEachFunction\n */\nvar afterEach = function(afterEachFunction) {\n jasmine.getEnv().afterEach(afterEachFunction);\n};\nexports.afterEach = afterEach;\n\n/**\n * Defines a suite of specifications.\n *\n * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared\n * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization\n * of setup in some tests.\n *\n * @example\n * // TODO: a simple suite\n *\n * // TODO: a simple suite with a nested describe block\n *\n * @param {String} description A string, usually the class under test.\n * @param {Function} specDefinitions function that defines several specs.\n */\nvar describe = function(description, specDefinitions) {\n return jasmine.getEnv().describe(description, specDefinitions);\n};\nexports.describe = describe;\n\n/**\n * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.\n *\n * @param {String} description A string, usually the class under test.\n * @param {Function} specDefinitions function that defines several specs.\n */\nvar xdescribe = function(description, specDefinitions) {\n return jasmine.getEnv().xdescribe(description, specDefinitions);\n};\nexports.xdescribe = xdescribe;\n\n\n// Provide the XMLHttpRequest class for IE 5.x-6.x:\njasmine.XmlHttpRequest = (typeof XMLHttpRequest == \"undefined\") ? function() {\n function tryIt(f) {\n try {\n return f();\n } catch(e) {\n }\n return null;\n }\n\n var xhr = tryIt(function() {\n return new ActiveXObject(\"Msxml2.XMLHTTP.6.0\");\n }) ||\n tryIt(function() {\n return new ActiveXObject(\"Msxml2.XMLHTTP.3.0\");\n }) ||\n tryIt(function() {\n return new ActiveXObject(\"Msxml2.XMLHTTP\");\n }) ||\n tryIt(function() {\n return new ActiveXObject(\"Microsoft.XMLHTTP\");\n });\n\n if (!xhr) throw new Error(\"This browser does not support XMLHttpRequest.\");\n\n return xhr;\n} : XMLHttpRequest;\n/**\n * @namespace\n */\njasmine.util = {};\n\n/**\n * Declare that a child class inherit it's prototype from the parent class.\n *\n * @private\n * @param {Function} childClass\n * @param {Function} parentClass\n */\njasmine.util.inherit = function(childClass, parentClass) {\n /**\n * @private\n */\n var subclass = function() {\n };\n subclass.prototype = parentClass.prototype;\n childClass.prototype = new subclass();\n};\n\njasmine.util.formatException = function(e) {\n var lineNumber;\n if (e.line) {\n lineNumber = e.line;\n }\n else if (e.lineNumber) {\n lineNumber = e.lineNumber;\n }\n\n var file;\n\n if (e.sourceURL) {\n file = e.sourceURL;\n }\n else if (e.fileName) {\n file = e.fileName;\n }\n\n var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();\n\n if (file && lineNumber) {\n message += ' in ' + file + ' (line ' + lineNumber + ')';\n }\n\n return message;\n};\n\njasmine.util.htmlEscape = function(str) {\n if (!str) return str;\n return str.replace(/&/g, '&')\n .replace(//g, '>');\n};\n\njasmine.util.argsToArray = function(args) {\n var arrayOfArgs = [];\n for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);\n return arrayOfArgs;\n};\n\njasmine.util.extend = function(destination, source) {\n for (var property in source) destination[property] = source[property];\n return destination;\n};\n\n/**\n * Environment for Jasmine\n *\n * @constructor\n */\njasmine.Env = function() {\n this.currentSpec = null;\n this.currentSuite = null;\n this.currentRunner_ = new jasmine.Runner(this);\n\n this.reporter = new jasmine.MultiReporter();\n\n this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;\n this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;\n this.lastUpdate = 0;\n this.specFilter = function() {\n return true;\n };\n\n this.nextSpecId_ = 0;\n this.nextSuiteId_ = 0;\n this.equalityTesters_ = [];\n\n // wrap matchers\n this.matchersClass = function() {\n jasmine.Matchers.apply(this, arguments);\n };\n jasmine.util.inherit(this.matchersClass, jasmine.Matchers);\n\n jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);\n};\n\n\njasmine.Env.prototype.setTimeout = jasmine.setTimeout;\njasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;\njasmine.Env.prototype.setInterval = jasmine.setInterval;\njasmine.Env.prototype.clearInterval = jasmine.clearInterval;\n\n/**\n * @returns an object containing jasmine version build info, if set.\n */\njasmine.Env.prototype.version = function () {\n if (jasmine.version_) {\n return jasmine.version_;\n } else {\n throw new Error('Version not set');\n }\n};\n\n/**\n * @returns string containing jasmine version build info, if set.\n */\njasmine.Env.prototype.versionString = function() {\n if (!jasmine.version_) {\n return \"version unknown\";\n }\n\n var version = this.version();\n var versionString = version.major + \".\" + version.minor + \".\" + version.build;\n if (version.release_candidate) {\n versionString += \".rc\" + version.release_candidate;\n }\n versionString += \" revision \" + version.revision;\n return versionString;\n};\n\n/**\n * @returns a sequential integer starting at 0\n */\njasmine.Env.prototype.nextSpecId = function () {\n return this.nextSpecId_++;\n};\n\n/**\n * @returns a sequential integer starting at 0\n */\njasmine.Env.prototype.nextSuiteId = function () {\n return this.nextSuiteId_++;\n};\n\n/**\n * Register a reporter to receive status updates from Jasmine.\n * @param {jasmine.Reporter} reporter An object which will receive status updates.\n */\njasmine.Env.prototype.addReporter = function(reporter) {\n this.reporter.addReporter(reporter);\n};\n\njasmine.Env.prototype.execute = function() {\n this.currentRunner_.execute();\n};\n\njasmine.Env.prototype.describe = function(description, specDefinitions) {\n var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);\n\n var parentSuite = this.currentSuite;\n if (parentSuite) {\n parentSuite.add(suite);\n } else {\n this.currentRunner_.add(suite);\n }\n\n this.currentSuite = suite;\n\n var declarationError = null;\n try {\n specDefinitions.call(suite);\n } catch(e) {\n declarationError = e;\n }\n\n if (declarationError) {\n this.it(\"encountered a declaration exception\", function() {\n throw declarationError;\n });\n }\n\n this.currentSuite = parentSuite;\n\n return suite;\n};\n\njasmine.Env.prototype.beforeEach = function(beforeEachFunction) {\n if (this.currentSuite) {\n this.currentSuite.beforeEach(beforeEachFunction);\n } else {\n this.currentRunner_.beforeEach(beforeEachFunction);\n }\n};\n\njasmine.Env.prototype.currentRunner = function () {\n return this.currentRunner_;\n};\n\njasmine.Env.prototype.afterEach = function(afterEachFunction) {\n if (this.currentSuite) {\n this.currentSuite.afterEach(afterEachFunction);\n } else {\n this.currentRunner_.afterEach(afterEachFunction);\n }\n\n};\n\njasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {\n return {\n execute: function() {\n }\n };\n};\n\njasmine.Env.prototype.it = function(description, func) {\n var spec = new jasmine.Spec(this, this.currentSuite, description);\n this.currentSuite.add(spec);\n this.currentSpec = spec;\n\n if (func) {\n spec.runs(func);\n }\n\n return spec;\n};\n\njasmine.Env.prototype.xit = function(desc, func) {\n var spec = this.it(desc, func);\n spec.results_.skipped = true;\n spec.runs = function() {};\n return spec;\n};\n\njasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {\n if (a.source != b.source)\n mismatchValues.push(\"expected pattern /\" + b.source + \"/ is not equal to the pattern /\" + a.source + \"/\");\n\n if (a.ignoreCase != b.ignoreCase)\n mismatchValues.push(\"expected modifier i was\" + (b.ignoreCase ? \" \" : \" not \") + \"set and does not equal the origin modifier\");\n\n if (a.global != b.global)\n mismatchValues.push(\"expected modifier g was\" + (b.global ? \" \" : \" not \") + \"set and does not equal the origin modifier\");\n\n if (a.multiline != b.multiline)\n mismatchValues.push(\"expected modifier m was\" + (b.multiline ? \" \" : \" not \") + \"set and does not equal the origin modifier\");\n\n if (a.sticky != b.sticky)\n mismatchValues.push(\"expected modifier y was\" + (b.sticky ? \" \" : \" not \") + \"set and does not equal the origin modifier\");\n\n return (mismatchValues.length === 0);\n};\n\njasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {\n if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {\n return true;\n }\n\n a.__Jasmine_been_here_before__ = b;\n b.__Jasmine_been_here_before__ = a;\n\n var hasKey = function(obj, keyName) {\n return obj !== null && obj[keyName] !== jasmine.undefined;\n };\n\n for (var property in b) {\n if (!hasKey(a, property) && hasKey(b, property)) {\n mismatchKeys.push(\"expected has key '\" + property + \"', but missing from actual.\");\n }\n }\n for (property in a) {\n if (!hasKey(b, property) && hasKey(a, property)) {\n mismatchKeys.push(\"expected missing key '\" + property + \"', but present in actual.\");\n }\n }\n for (property in b) {\n if (property == '__Jasmine_been_here_before__') continue;\n if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {\n mismatchValues.push(\"'\" + property + \"' was '\" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + \"' in expected, but was '\" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + \"' in actual.\");\n }\n }\n\n if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {\n mismatchValues.push(\"arrays were not the same length\");\n }\n\n delete a.__Jasmine_been_here_before__;\n delete b.__Jasmine_been_here_before__;\n return (mismatchKeys.length === 0 && mismatchValues.length === 0);\n};\n\njasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {\n mismatchKeys = mismatchKeys || [];\n mismatchValues = mismatchValues || [];\n\n for (var i = 0; i < this.equalityTesters_.length; i++) {\n var equalityTester = this.equalityTesters_[i];\n var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);\n if (result !== jasmine.undefined) return result;\n }\n\n if (a === b) return true;\n\n if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {\n return (a == jasmine.undefined && b == jasmine.undefined);\n }\n\n if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {\n return a === b;\n }\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() == b.getTime();\n }\n\n if (a.jasmineMatches) {\n return a.jasmineMatches(b);\n }\n\n if (b.jasmineMatches) {\n return b.jasmineMatches(a);\n }\n\n if (a instanceof jasmine.Matchers.ObjectContaining) {\n return a.matches(b);\n }\n\n if (b instanceof jasmine.Matchers.ObjectContaining) {\n return b.matches(a);\n }\n\n if (jasmine.isString_(a) && jasmine.isString_(b)) {\n return (a == b);\n }\n\n if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {\n return (a == b);\n }\n\n if (a instanceof RegExp && b instanceof RegExp) {\n return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);\n }\n\n if (typeof a === \"object\" && typeof b === \"object\") {\n return this.compareObjects_(a, b, mismatchKeys, mismatchValues);\n }\n\n //Straight check\n return (a === b);\n};\n\njasmine.Env.prototype.contains_ = function(haystack, needle) {\n if (jasmine.isArray_(haystack)) {\n for (var i = 0; i < haystack.length; i++) {\n if (this.equals_(haystack[i], needle)) return true;\n }\n return false;\n }\n return haystack.indexOf(needle) >= 0;\n};\n\njasmine.Env.prototype.addEqualityTester = function(equalityTester) {\n this.equalityTesters_.push(equalityTester);\n};\n/** No-op base class for Jasmine reporters.\n *\n * @constructor\n */\njasmine.Reporter = function() {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportRunnerStarting = function(runner) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportRunnerResults = function(runner) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportSuiteResults = function(suite) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportSpecStarting = function(spec) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportSpecResults = function(spec) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.log = function(str) {\n};\n\n/**\n * Blocks are functions with executable code that make up a spec.\n *\n * @constructor\n * @param {jasmine.Env} env\n * @param {Function} func\n * @param {jasmine.Spec} spec\n */\njasmine.Block = function(env, func, spec) {\n this.env = env;\n this.func = func;\n this.spec = spec;\n};\n\njasmine.Block.prototype.execute = function(onComplete) {\n if (!jasmine.CATCH_EXCEPTIONS) {\n this.func.apply(this.spec);\n }\n else {\n try {\n this.func.apply(this.spec);\n } catch (e) {\n this.spec.fail(e);\n }\n }\n onComplete();\n};\n/** JavaScript API reporter.\n *\n * @constructor\n */\njasmine.JsApiReporter = function() {\n this.started = false;\n this.finished = false;\n this.suites_ = [];\n this.results_ = {};\n};\n\njasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {\n this.started = true;\n var suites = runner.topLevelSuites();\n for (var i = 0; i < suites.length; i++) {\n var suite = suites[i];\n this.suites_.push(this.summarize_(suite));\n }\n};\n\njasmine.JsApiReporter.prototype.suites = function() {\n return this.suites_;\n};\n\njasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {\n var isSuite = suiteOrSpec instanceof jasmine.Suite;\n var summary = {\n id: suiteOrSpec.id,\n name: suiteOrSpec.description,\n type: isSuite ? 'suite' : 'spec',\n children: []\n };\n \n if (isSuite) {\n var children = suiteOrSpec.children();\n for (var i = 0; i < children.length; i++) {\n summary.children.push(this.summarize_(children[i]));\n }\n }\n return summary;\n};\n\njasmine.JsApiReporter.prototype.results = function() {\n return this.results_;\n};\n\njasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {\n return this.results_[specId];\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {\n this.finished = true;\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {\n this.results_[spec.id] = {\n messages: spec.results().getItems(),\n result: spec.results().failedCount > 0 ? \"failed\" : \"passed\"\n };\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.log = function(str) {\n};\n\njasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){\n var results = {};\n for (var i = 0; i < specIds.length; i++) {\n var specId = specIds[i];\n results[specId] = this.summarizeResult_(this.results_[specId]);\n }\n return results;\n};\n\njasmine.JsApiReporter.prototype.summarizeResult_ = function(result){\n var summaryMessages = [];\n var messagesLength = result.messages.length;\n for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {\n var resultMessage = result.messages[messageIndex];\n summaryMessages.push({\n text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,\n passed: resultMessage.passed ? resultMessage.passed() : true,\n type: resultMessage.type,\n message: resultMessage.message,\n trace: {\n stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined\n }\n });\n }\n\n return {\n result : result.result,\n messages : summaryMessages\n };\n};\n\n/**\n * @constructor\n * @param {jasmine.Env} env\n * @param actual\n * @param {jasmine.Spec} spec\n */\njasmine.Matchers = function(env, actual, spec, opt_isNot) {\n this.env = env;\n this.actual = actual;\n this.spec = spec;\n this.isNot = opt_isNot || false;\n this.reportWasCalled_ = false;\n};\n\n// todo: @deprecated as of Jasmine 0.11, remove soon [xw]\njasmine.Matchers.pp = function(str) {\n throw new Error(\"jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!\");\n};\n\n// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]\njasmine.Matchers.prototype.report = function(result, failing_message, details) {\n throw new Error(\"As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs\");\n};\n\njasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {\n for (var methodName in prototype) {\n if (methodName == 'report') continue;\n var orig = prototype[methodName];\n matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);\n }\n};\n\njasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {\n return function() {\n var matcherArgs = jasmine.util.argsToArray(arguments);\n var result = matcherFunction.apply(this, arguments);\n\n if (this.isNot) {\n result = !result;\n }\n\n if (this.reportWasCalled_) return result;\n\n var message;\n if (!result) {\n if (this.message) {\n message = this.message.apply(this, arguments);\n if (jasmine.isArray_(message)) {\n message = message[this.isNot ? 1 : 0];\n }\n } else {\n var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });\n message = \"Expected \" + jasmine.pp(this.actual) + (this.isNot ? \" not \" : \" \") + englishyPredicate;\n if (matcherArgs.length > 0) {\n for (var i = 0; i < matcherArgs.length; i++) {\n if (i > 0) message += \",\";\n message += \" \" + jasmine.pp(matcherArgs[i]);\n }\n }\n message += \".\";\n }\n }\n var expectationResult = new jasmine.ExpectationResult({\n matcherName: matcherName,\n passed: result,\n expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],\n actual: this.actual,\n message: message\n });\n this.spec.addMatcherResult(expectationResult);\n return jasmine.undefined;\n };\n};\n\n\n\n\n/**\n * toBe: compares the actual to the expected using ===\n * @param expected\n */\njasmine.Matchers.prototype.toBe = function(expected) {\n return this.actual === expected;\n};\n\n/**\n * toNotBe: compares the actual to the expected using !==\n * @param expected\n * @deprecated as of 1.0. Use not.toBe() instead.\n */\njasmine.Matchers.prototype.toNotBe = function(expected) {\n return this.actual !== expected;\n};\n\n/**\n * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.\n *\n * @param expected\n */\njasmine.Matchers.prototype.toEqual = function(expected) {\n return this.env.equals_(this.actual, expected);\n};\n\n/**\n * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual\n * @param expected\n * @deprecated as of 1.0. Use not.toEqual() instead.\n */\njasmine.Matchers.prototype.toNotEqual = function(expected) {\n return !this.env.equals_(this.actual, expected);\n};\n\n/**\n * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes\n * a pattern or a String.\n *\n * @param expected\n */\njasmine.Matchers.prototype.toMatch = function(expected) {\n return new RegExp(expected).test(this.actual);\n};\n\n/**\n * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch\n * @param expected\n * @deprecated as of 1.0. Use not.toMatch() instead.\n */\njasmine.Matchers.prototype.toNotMatch = function(expected) {\n return !(new RegExp(expected).test(this.actual));\n};\n\n/**\n * Matcher that compares the actual to jasmine.undefined.\n */\njasmine.Matchers.prototype.toBeDefined = function() {\n return (this.actual !== jasmine.undefined);\n};\n\n/**\n * Matcher that compares the actual to jasmine.undefined.\n */\njasmine.Matchers.prototype.toBeUndefined = function() {\n return (this.actual === jasmine.undefined);\n};\n\n/**\n * Matcher that compares the actual to null.\n */\njasmine.Matchers.prototype.toBeNull = function() {\n return (this.actual === null);\n};\n\n/**\n * Matcher that compares the actual to NaN.\n */\njasmine.Matchers.prototype.toBeNaN = function() {\n\tthis.message = function() {\n\t\treturn [ \"Expected \" + jasmine.pp(this.actual) + \" to be NaN.\" ];\n\t};\n\n\treturn (this.actual !== this.actual);\n};\n\n/**\n * Matcher that boolean not-nots the actual.\n */\njasmine.Matchers.prototype.toBeTruthy = function() {\n return !!this.actual;\n};\n\n\n/**\n * Matcher that boolean nots the actual.\n */\njasmine.Matchers.prototype.toBeFalsy = function() {\n return !this.actual;\n};\n\n\n/**\n * Matcher that checks to see if the actual, a Jasmine spy, was called.\n */\njasmine.Matchers.prototype.toHaveBeenCalled = function() {\n if (arguments.length > 0) {\n throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');\n }\n\n if (!jasmine.isSpy(this.actual)) {\n throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n }\n\n this.message = function() {\n return [\n \"Expected spy \" + this.actual.identity + \" to have been called.\",\n \"Expected spy \" + this.actual.identity + \" not to have been called.\"\n ];\n };\n\n return this.actual.wasCalled;\n};\n\n/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */\njasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;\n\n/**\n * Matcher that checks to see if the actual, a Jasmine spy, was not called.\n *\n * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead\n */\njasmine.Matchers.prototype.wasNotCalled = function() {\n if (arguments.length > 0) {\n throw new Error('wasNotCalled does not take arguments');\n }\n\n if (!jasmine.isSpy(this.actual)) {\n throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n }\n\n this.message = function() {\n return [\n \"Expected spy \" + this.actual.identity + \" to not have been called.\",\n \"Expected spy \" + this.actual.identity + \" to have been called.\"\n ];\n };\n\n return !this.actual.wasCalled;\n};\n\n/**\n * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.\n *\n * @example\n *\n */\njasmine.Matchers.prototype.toHaveBeenCalledWith = function() {\n var expectedArgs = jasmine.util.argsToArray(arguments);\n if (!jasmine.isSpy(this.actual)) {\n throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n }\n this.message = function() {\n var invertedMessage = \"Expected spy \" + this.actual.identity + \" not to have been called with \" + jasmine.pp(expectedArgs) + \" but it was.\";\n var positiveMessage = \"\";\n if (this.actual.callCount === 0) {\n positiveMessage = \"Expected spy \" + this.actual.identity + \" to have been called with \" + jasmine.pp(expectedArgs) + \" but it was never called.\";\n } else {\n positiveMessage = \"Expected spy \" + this.actual.identity + \" to have been called with \" + jasmine.pp(expectedArgs) + \" but actual calls were \" + jasmine.pp(this.actual.argsForCall).replace(/^\\[ | \\]$/g, '')\n }\n return [positiveMessage, invertedMessage];\n };\n\n return this.env.contains_(this.actual.argsForCall, expectedArgs);\n};\n\n/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */\njasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;\n\n/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */\njasmine.Matchers.prototype.wasNotCalledWith = function() {\n var expectedArgs = jasmine.util.argsToArray(arguments);\n if (!jasmine.isSpy(this.actual)) {\n throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n }\n\n this.message = function() {\n return [\n \"Expected spy not to have been called with \" + jasmine.pp(expectedArgs) + \" but it was\",\n \"Expected spy to have been called with \" + jasmine.pp(expectedArgs) + \" but it was\"\n ];\n };\n\n return !this.env.contains_(this.actual.argsForCall, expectedArgs);\n};\n\n/**\n * Matcher that checks that the expected item is an element in the actual Array.\n *\n * @param {Object} expected\n */\njasmine.Matchers.prototype.toContain = function(expected) {\n return this.env.contains_(this.actual, expected);\n};\n\n/**\n * Matcher that checks that the expected item is NOT an element in the actual Array.\n *\n * @param {Object} expected\n * @deprecated as of 1.0. Use not.toContain() instead.\n */\njasmine.Matchers.prototype.toNotContain = function(expected) {\n return !this.env.contains_(this.actual, expected);\n};\n\njasmine.Matchers.prototype.toBeLessThan = function(expected) {\n return this.actual < expected;\n};\n\njasmine.Matchers.prototype.toBeGreaterThan = function(expected) {\n return this.actual > expected;\n};\n\n/**\n * Matcher that checks that the expected item is equal to the actual item\n * up to a given level of decimal precision (default 2).\n *\n * @param {Number} expected\n * @param {Number} precision, as number of decimal places\n */\njasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {\n if (!(precision === 0)) {\n precision = precision || 2;\n }\n return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);\n};\n\n/**\n * Matcher that checks that the expected exception was thrown by the actual.\n *\n * @param {String} [expected]\n */\njasmine.Matchers.prototype.toThrow = function(expected) {\n var result = false;\n var exception;\n if (typeof this.actual != 'function') {\n throw new Error('Actual is not a function');\n }\n try {\n this.actual();\n } catch (e) {\n exception = e;\n }\n if (exception) {\n result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));\n }\n\n var not = this.isNot ? \"not \" : \"\";\n\n this.message = function() {\n if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {\n return [\"Expected function \" + not + \"to throw\", expected ? expected.message || expected : \"an exception\", \", but it threw\", exception.message || exception].join(' ');\n } else {\n return \"Expected function to throw an exception.\";\n }\n };\n\n return result;\n};\n\njasmine.Matchers.Any = function(expectedClass) {\n this.expectedClass = expectedClass;\n};\n\njasmine.Matchers.Any.prototype.jasmineMatches = function(other) {\n if (this.expectedClass == String) {\n return typeof other == 'string' || other instanceof String;\n }\n\n if (this.expectedClass == Number) {\n return typeof other == 'number' || other instanceof Number;\n }\n\n if (this.expectedClass == Function) {\n return typeof other == 'function' || other instanceof Function;\n }\n\n if (this.expectedClass == Object) {\n return typeof other == 'object';\n }\n\n return other instanceof this.expectedClass;\n};\n\njasmine.Matchers.Any.prototype.jasmineToString = function() {\n return '';\n};\n\njasmine.Matchers.ObjectContaining = function (sample) {\n this.sample = sample;\n};\n\njasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {\n mismatchKeys = mismatchKeys || [];\n mismatchValues = mismatchValues || [];\n\n var env = jasmine.getEnv();\n\n var hasKey = function(obj, keyName) {\n return obj != null && obj[keyName] !== jasmine.undefined;\n };\n\n for (var property in this.sample) {\n if (!hasKey(other, property) && hasKey(this.sample, property)) {\n mismatchKeys.push(\"expected has key '\" + property + \"', but missing from actual.\");\n }\n else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {\n mismatchValues.push(\"'\" + property + \"' was '\" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + \"' in expected, but was '\" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + \"' in actual.\");\n }\n }\n\n return (mismatchKeys.length === 0 && mismatchValues.length === 0);\n};\n\njasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {\n return \"\";\n};\n// Mock setTimeout, clearTimeout\n// Contributed by Pivotal Computer Systems, www.pivotalsf.com\n\njasmine.FakeTimer = function() {\n this.reset();\n\n var self = this;\n self.setTimeout = function(funcToCall, millis) {\n self.timeoutsMade++;\n self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);\n return self.timeoutsMade;\n };\n\n self.setInterval = function(funcToCall, millis) {\n self.timeoutsMade++;\n self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);\n return self.timeoutsMade;\n };\n\n self.clearTimeout = function(timeoutKey) {\n self.scheduledFunctions[timeoutKey] = jasmine.undefined;\n };\n\n self.clearInterval = function(timeoutKey) {\n self.scheduledFunctions[timeoutKey] = jasmine.undefined;\n };\n\n};\n\njasmine.FakeTimer.prototype.reset = function() {\n this.timeoutsMade = 0;\n this.scheduledFunctions = {};\n this.nowMillis = 0;\n};\n\njasmine.FakeTimer.prototype.tick = function(millis) {\n var oldMillis = this.nowMillis;\n var newMillis = oldMillis + millis;\n this.runFunctionsWithinRange(oldMillis, newMillis);\n this.nowMillis = newMillis;\n};\n\njasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {\n var scheduledFunc;\n var funcsToRun = [];\n for (var timeoutKey in this.scheduledFunctions) {\n scheduledFunc = this.scheduledFunctions[timeoutKey];\n if (scheduledFunc != jasmine.undefined &&\n scheduledFunc.runAtMillis >= oldMillis &&\n scheduledFunc.runAtMillis <= nowMillis) {\n funcsToRun.push(scheduledFunc);\n this.scheduledFunctions[timeoutKey] = jasmine.undefined;\n }\n }\n\n if (funcsToRun.length > 0) {\n funcsToRun.sort(function(a, b) {\n return a.runAtMillis - b.runAtMillis;\n });\n for (var i = 0; i < funcsToRun.length; ++i) {\n try {\n var funcToRun = funcsToRun[i];\n this.nowMillis = funcToRun.runAtMillis;\n funcToRun.funcToCall();\n if (funcToRun.recurring) {\n this.scheduleFunction(funcToRun.timeoutKey,\n funcToRun.funcToCall,\n funcToRun.millis,\n true);\n }\n } catch(e) {\n }\n }\n this.runFunctionsWithinRange(oldMillis, nowMillis);\n }\n};\n\njasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {\n this.scheduledFunctions[timeoutKey] = {\n runAtMillis: this.nowMillis + millis,\n funcToCall: funcToCall,\n recurring: recurring,\n timeoutKey: timeoutKey,\n millis: millis\n };\n};\n\n/**\n * @namespace\n */\njasmine.Clock = {\n defaultFakeTimer: new jasmine.FakeTimer(),\n\n reset: function() {\n jasmine.Clock.assertInstalled();\n jasmine.Clock.defaultFakeTimer.reset();\n },\n\n tick: function(millis) {\n jasmine.Clock.assertInstalled();\n jasmine.Clock.defaultFakeTimer.tick(millis);\n },\n\n runFunctionsWithinRange: function(oldMillis, nowMillis) {\n jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);\n },\n\n scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {\n jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);\n },\n\n useMock: function() {\n if (!jasmine.Clock.isInstalled()) {\n var spec = jasmine.getEnv().currentSpec;\n spec.after(jasmine.Clock.uninstallMock);\n\n jasmine.Clock.installMock();\n }\n },\n\n installMock: function() {\n jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;\n },\n\n uninstallMock: function() {\n jasmine.Clock.assertInstalled();\n jasmine.Clock.installed = jasmine.Clock.real;\n },\n\n real: {\n setTimeout: jasmine.getGlobal().setTimeout,\n clearTimeout: jasmine.getGlobal().clearTimeout,\n setInterval: jasmine.getGlobal().setInterval,\n clearInterval: jasmine.getGlobal().clearInterval\n },\n\n assertInstalled: function() {\n if (!jasmine.Clock.isInstalled()) {\n throw new Error(\"Mock clock is not installed, use jasmine.Clock.useMock()\");\n }\n },\n\n isInstalled: function() {\n return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;\n },\n\n installed: null\n};\njasmine.Clock.installed = jasmine.Clock.real;\n\n//else for IE support\njasmine.getGlobal().setTimeout = function(funcToCall, millis) {\n if (jasmine.Clock.installed.setTimeout.apply) {\n return jasmine.Clock.installed.setTimeout.apply(this, arguments);\n } else {\n return jasmine.Clock.installed.setTimeout(funcToCall, millis);\n }\n};\n\njasmine.getGlobal().setInterval = function(funcToCall, millis) {\n if (jasmine.Clock.installed.setInterval.apply) {\n return jasmine.Clock.installed.setInterval.apply(this, arguments);\n } else {\n return jasmine.Clock.installed.setInterval(funcToCall, millis);\n }\n};\n\njasmine.getGlobal().clearTimeout = function(timeoutKey) {\n if (jasmine.Clock.installed.clearTimeout.apply) {\n return jasmine.Clock.installed.clearTimeout.apply(this, arguments);\n } else {\n return jasmine.Clock.installed.clearTimeout(timeoutKey);\n }\n};\n\njasmine.getGlobal().clearInterval = function(timeoutKey) {\n if (jasmine.Clock.installed.clearTimeout.apply) {\n return jasmine.Clock.installed.clearInterval.apply(this, arguments);\n } else {\n return jasmine.Clock.installed.clearInterval(timeoutKey);\n }\n};\n\n/**\n * @constructor\n */\njasmine.MultiReporter = function() {\n this.subReporters_ = [];\n};\njasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);\n\njasmine.MultiReporter.prototype.addReporter = function(reporter) {\n this.subReporters_.push(reporter);\n};\n\n(function() {\n var functionNames = [\n \"reportRunnerStarting\",\n \"reportRunnerResults\",\n \"reportSuiteResults\",\n \"reportSpecStarting\",\n \"reportSpecResults\",\n \"log\"\n ];\n for (var i = 0; i < functionNames.length; i++) {\n var functionName = functionNames[i];\n jasmine.MultiReporter.prototype[functionName] = (function(functionName) {\n return function() {\n for (var j = 0; j < this.subReporters_.length; j++) {\n var subReporter = this.subReporters_[j];\n if (subReporter[functionName]) {\n subReporter[functionName].apply(subReporter, arguments);\n }\n }\n };\n })(functionName);\n }\n})();\n/**\n * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults\n *\n * @constructor\n */\njasmine.NestedResults = function() {\n /**\n * The total count of results\n */\n this.totalCount = 0;\n /**\n * Number of passed results\n */\n this.passedCount = 0;\n /**\n * Number of failed results\n */\n this.failedCount = 0;\n /**\n * Was this suite/spec skipped?\n */\n this.skipped = false;\n /**\n * @ignore\n */\n this.items_ = [];\n};\n\n/**\n * Roll up the result counts.\n *\n * @param result\n */\njasmine.NestedResults.prototype.rollupCounts = function(result) {\n this.totalCount += result.totalCount;\n this.passedCount += result.passedCount;\n this.failedCount += result.failedCount;\n};\n\n/**\n * Adds a log message.\n * @param values Array of message parts which will be concatenated later.\n */\njasmine.NestedResults.prototype.log = function(values) {\n this.items_.push(new jasmine.MessageResult(values));\n};\n\n/**\n * Getter for the results: message & results.\n */\njasmine.NestedResults.prototype.getItems = function() {\n return this.items_;\n};\n\n/**\n * Adds a result, tracking counts (total, passed, & failed)\n * @param {jasmine.ExpectationResult|jasmine.NestedResults} result\n */\njasmine.NestedResults.prototype.addResult = function(result) {\n if (result.type != 'log') {\n if (result.items_) {\n this.rollupCounts(result);\n } else {\n this.totalCount++;\n if (result.passed()) {\n this.passedCount++;\n } else {\n this.failedCount++;\n }\n }\n }\n this.items_.push(result);\n};\n\n/**\n * @returns {Boolean} True if everything below passed\n */\njasmine.NestedResults.prototype.passed = function() {\n return this.passedCount === this.totalCount;\n};\n/**\n * Base class for pretty printing for expectation results.\n */\njasmine.PrettyPrinter = function() {\n this.ppNestLevel_ = 0;\n};\n\n/**\n * Formats a value in a nice, human-readable string.\n *\n * @param value\n */\njasmine.PrettyPrinter.prototype.format = function(value) {\n this.ppNestLevel_++;\n try {\n if (value === jasmine.undefined) {\n this.emitScalar('undefined');\n } else if (value === null) {\n this.emitScalar('null');\n } else if (value === jasmine.getGlobal()) {\n this.emitScalar('');\n } else if (value.jasmineToString) {\n this.emitScalar(value.jasmineToString());\n } else if (typeof value === 'string') {\n this.emitString(value);\n } else if (jasmine.isSpy(value)) {\n this.emitScalar(\"spy on \" + value.identity);\n } else if (value instanceof RegExp) {\n this.emitScalar(value.toString());\n } else if (typeof value === 'function') {\n this.emitScalar('Function');\n } else if (typeof value.nodeType === 'number') {\n this.emitScalar('HTMLNode');\n } else if (value instanceof Date) {\n this.emitScalar('Date(' + value + ')');\n } else if (value.__Jasmine_been_here_before__) {\n this.emitScalar('');\n } else if (jasmine.isArray_(value) || typeof value == 'object') {\n value.__Jasmine_been_here_before__ = true;\n if (jasmine.isArray_(value)) {\n this.emitArray(value);\n } else {\n this.emitObject(value);\n }\n delete value.__Jasmine_been_here_before__;\n } else {\n this.emitScalar(value.toString());\n }\n } finally {\n this.ppNestLevel_--;\n }\n};\n\njasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {\n for (var property in obj) {\n if (!obj.hasOwnProperty(property)) continue;\n if (property == '__Jasmine_been_here_before__') continue;\n fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && \n obj.__lookupGetter__(property) !== null) : false);\n }\n};\n\njasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;\njasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;\njasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;\njasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;\n\njasmine.StringPrettyPrinter = function() {\n jasmine.PrettyPrinter.call(this);\n\n this.string = '';\n};\njasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);\n\njasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {\n this.append(value);\n};\n\njasmine.StringPrettyPrinter.prototype.emitString = function(value) {\n this.append(\"'\" + value + \"'\");\n};\n\njasmine.StringPrettyPrinter.prototype.emitArray = function(array) {\n if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {\n this.append(\"Array\");\n return;\n }\n\n this.append('[ ');\n for (var i = 0; i < array.length; i++) {\n if (i > 0) {\n this.append(', ');\n }\n this.format(array[i]);\n }\n this.append(' ]');\n};\n\njasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {\n if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {\n this.append(\"Object\");\n return;\n }\n\n var self = this;\n this.append('{ ');\n var first = true;\n\n this.iterateObject(obj, function(property, isGetter) {\n if (first) {\n first = false;\n } else {\n self.append(', ');\n }\n\n self.append(property);\n self.append(' : ');\n if (isGetter) {\n self.append('');\n } else {\n self.format(obj[property]);\n }\n });\n\n this.append(' }');\n};\n\njasmine.StringPrettyPrinter.prototype.append = function(value) {\n this.string += value;\n};\njasmine.Queue = function(env) {\n this.env = env;\n\n // parallel to blocks. each true value in this array means the block will\n // get executed even if we abort\n this.ensured = [];\n this.blocks = [];\n this.running = false;\n this.index = 0;\n this.offset = 0;\n this.abort = false;\n};\n\njasmine.Queue.prototype.addBefore = function(block, ensure) {\n if (ensure === jasmine.undefined) {\n ensure = false;\n }\n\n this.blocks.unshift(block);\n this.ensured.unshift(ensure);\n};\n\njasmine.Queue.prototype.add = function(block, ensure) {\n if (ensure === jasmine.undefined) {\n ensure = false;\n }\n\n this.blocks.push(block);\n this.ensured.push(ensure);\n};\n\njasmine.Queue.prototype.insertNext = function(block, ensure) {\n if (ensure === jasmine.undefined) {\n ensure = false;\n }\n\n this.ensured.splice((this.index + this.offset + 1), 0, ensure);\n this.blocks.splice((this.index + this.offset + 1), 0, block);\n this.offset++;\n};\n\njasmine.Queue.prototype.start = function(onComplete) {\n this.running = true;\n this.onComplete = onComplete;\n this.next_();\n};\n\njasmine.Queue.prototype.isRunning = function() {\n return this.running;\n};\n\njasmine.Queue.LOOP_DONT_RECURSE = true;\n\njasmine.Queue.prototype.next_ = function() {\n var self = this;\n var goAgain = true;\n\n while (goAgain) {\n goAgain = false;\n \n if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {\n var calledSynchronously = true;\n var completedSynchronously = false;\n\n var onComplete = function () {\n if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {\n completedSynchronously = true;\n return;\n }\n\n if (self.blocks[self.index].abort) {\n self.abort = true;\n }\n\n self.offset = 0;\n self.index++;\n\n var now = new Date().getTime();\n if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {\n self.env.lastUpdate = now;\n self.env.setTimeout(function() {\n self.next_();\n }, 0);\n } else {\n if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {\n goAgain = true;\n } else {\n self.next_();\n }\n }\n };\n self.blocks[self.index].execute(onComplete);\n\n calledSynchronously = false;\n if (completedSynchronously) {\n onComplete();\n }\n \n } else {\n self.running = false;\n if (self.onComplete) {\n self.onComplete();\n }\n }\n }\n};\n\njasmine.Queue.prototype.results = function() {\n var results = new jasmine.NestedResults();\n for (var i = 0; i < this.blocks.length; i++) {\n if (this.blocks[i].results) {\n results.addResult(this.blocks[i].results());\n }\n }\n return results;\n};\n\n\n/**\n * Runner\n *\n * @constructor\n * @param {jasmine.Env} env\n */\njasmine.Runner = function(env) {\n var self = this;\n self.env = env;\n self.queue = new jasmine.Queue(env);\n self.before_ = [];\n self.after_ = [];\n self.suites_ = [];\n};\n\njasmine.Runner.prototype.execute = function() {\n var self = this;\n if (self.env.reporter.reportRunnerStarting) {\n self.env.reporter.reportRunnerStarting(this);\n }\n self.queue.start(function () {\n self.finishCallback();\n });\n};\n\njasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {\n beforeEachFunction.typeName = 'beforeEach';\n this.before_.splice(0,0,beforeEachFunction);\n};\n\njasmine.Runner.prototype.afterEach = function(afterEachFunction) {\n afterEachFunction.typeName = 'afterEach';\n this.after_.splice(0,0,afterEachFunction);\n};\n\n\njasmine.Runner.prototype.finishCallback = function() {\n this.env.reporter.reportRunnerResults(this);\n};\n\njasmine.Runner.prototype.addSuite = function(suite) {\n this.suites_.push(suite);\n};\n\njasmine.Runner.prototype.add = function(block) {\n if (block instanceof jasmine.Suite) {\n this.addSuite(block);\n }\n this.queue.add(block);\n};\n\njasmine.Runner.prototype.specs = function () {\n var suites = this.suites();\n var specs = [];\n for (var i = 0; i < suites.length; i++) {\n specs = specs.concat(suites[i].specs());\n }\n return specs;\n};\n\njasmine.Runner.prototype.suites = function() {\n return this.suites_;\n};\n\njasmine.Runner.prototype.topLevelSuites = function() {\n var topLevelSuites = [];\n for (var i = 0; i < this.suites_.length; i++) {\n if (!this.suites_[i].parentSuite) {\n topLevelSuites.push(this.suites_[i]);\n }\n }\n return topLevelSuites;\n};\n\njasmine.Runner.prototype.results = function() {\n return this.queue.results();\n};\n/**\n * Internal representation of a Jasmine specification, or test.\n *\n * @constructor\n * @param {jasmine.Env} env\n * @param {jasmine.Suite} suite\n * @param {String} description\n */\njasmine.Spec = function(env, suite, description) {\n if (!env) {\n throw new Error('jasmine.Env() required');\n }\n if (!suite) {\n throw new Error('jasmine.Suite() required');\n }\n var spec = this;\n spec.id = env.nextSpecId ? env.nextSpecId() : null;\n spec.env = env;\n spec.suite = suite;\n spec.description = description;\n spec.queue = new jasmine.Queue(env);\n\n spec.afterCallbacks = [];\n spec.spies_ = [];\n\n spec.results_ = new jasmine.NestedResults();\n spec.results_.description = description;\n spec.matchersClass = null;\n};\n\njasmine.Spec.prototype.getFullName = function() {\n return this.suite.getFullName() + ' ' + this.description + '.';\n};\n\n\njasmine.Spec.prototype.results = function() {\n return this.results_;\n};\n\n/**\n * All parameters are pretty-printed and concatenated together, then written to the spec's output.\n *\n * Be careful not to leave calls to jasmine.log in production code.\n */\njasmine.Spec.prototype.log = function() {\n return this.results_.log(arguments);\n};\n\njasmine.Spec.prototype.runs = function (func) {\n var block = new jasmine.Block(this.env, func, this);\n this.addToQueue(block);\n return this;\n};\n\njasmine.Spec.prototype.addToQueue = function (block) {\n if (this.queue.isRunning()) {\n this.queue.insertNext(block);\n } else {\n this.queue.add(block);\n }\n};\n\n/**\n * @param {jasmine.ExpectationResult} result\n */\njasmine.Spec.prototype.addMatcherResult = function(result) {\n this.results_.addResult(result);\n};\n\njasmine.Spec.prototype.expect = function(actual) {\n var positive = new (this.getMatchersClass_())(this.env, actual, this);\n positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);\n return positive;\n};\n\n/**\n * Waits a fixed time period before moving to the next block.\n *\n * @deprecated Use waitsFor() instead\n * @param {Number} timeout milliseconds to wait\n */\njasmine.Spec.prototype.waits = function(timeout) {\n var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);\n this.addToQueue(waitsFunc);\n return this;\n};\n\n/**\n * Waits for the latchFunction to return true before proceeding to the next block.\n *\n * @param {Function} latchFunction\n * @param {String} optional_timeoutMessage\n * @param {Number} optional_timeout\n */\njasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {\n var latchFunction_ = null;\n var optional_timeoutMessage_ = null;\n var optional_timeout_ = null;\n\n for (var i = 0; i < arguments.length; i++) {\n var arg = arguments[i];\n switch (typeof arg) {\n case 'function':\n latchFunction_ = arg;\n break;\n case 'string':\n optional_timeoutMessage_ = arg;\n break;\n case 'number':\n optional_timeout_ = arg;\n break;\n }\n }\n\n var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);\n this.addToQueue(waitsForFunc);\n return this;\n};\n\njasmine.Spec.prototype.fail = function (e) {\n var expectationResult = new jasmine.ExpectationResult({\n passed: false,\n message: e ? jasmine.util.formatException(e) : 'Exception',\n trace: { stack: e.stack }\n });\n this.results_.addResult(expectationResult);\n};\n\njasmine.Spec.prototype.getMatchersClass_ = function() {\n return this.matchersClass || this.env.matchersClass;\n};\n\njasmine.Spec.prototype.addMatchers = function(matchersPrototype) {\n var parent = this.getMatchersClass_();\n var newMatchersClass = function() {\n parent.apply(this, arguments);\n };\n jasmine.util.inherit(newMatchersClass, parent);\n jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);\n this.matchersClass = newMatchersClass;\n};\n\njasmine.Spec.prototype.finishCallback = function() {\n this.env.reporter.reportSpecResults(this);\n};\n\njasmine.Spec.prototype.finish = function(onComplete) {\n this.removeAllSpies();\n this.finishCallback();\n if (onComplete) {\n onComplete();\n }\n};\n\njasmine.Spec.prototype.after = function(doAfter) {\n if (this.queue.isRunning()) {\n this.queue.add(new jasmine.Block(this.env, doAfter, this), true);\n } else {\n this.afterCallbacks.unshift(doAfter);\n }\n};\n\njasmine.Spec.prototype.execute = function(onComplete) {\n var spec = this;\n if (!spec.env.specFilter(spec)) {\n spec.results_.skipped = true;\n spec.finish(onComplete);\n return;\n }\n\n this.env.reporter.reportSpecStarting(this);\n\n spec.env.currentSpec = spec;\n\n spec.addBeforesAndAftersToQueue();\n\n spec.queue.start(function () {\n spec.finish(onComplete);\n });\n};\n\njasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {\n var runner = this.env.currentRunner();\n var i;\n\n for (var suite = this.suite; suite; suite = suite.parentSuite) {\n for (i = 0; i < suite.before_.length; i++) {\n this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));\n }\n }\n for (i = 0; i < runner.before_.length; i++) {\n this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));\n }\n for (i = 0; i < this.afterCallbacks.length; i++) {\n this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);\n }\n for (suite = this.suite; suite; suite = suite.parentSuite) {\n for (i = 0; i < suite.after_.length; i++) {\n this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);\n }\n }\n for (i = 0; i < runner.after_.length; i++) {\n this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);\n }\n};\n\njasmine.Spec.prototype.explodes = function() {\n throw 'explodes function should not have been called';\n};\n\njasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {\n if (obj == jasmine.undefined) {\n throw \"spyOn could not find an object to spy upon for \" + methodName + \"()\";\n }\n\n if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {\n throw methodName + '() method does not exist';\n }\n\n if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {\n throw new Error(methodName + ' has already been spied upon');\n }\n\n var spyObj = jasmine.createSpy(methodName);\n\n this.spies_.push(spyObj);\n spyObj.baseObj = obj;\n spyObj.methodName = methodName;\n spyObj.originalValue = obj[methodName];\n\n obj[methodName] = spyObj;\n\n return spyObj;\n};\n\njasmine.Spec.prototype.removeAllSpies = function() {\n for (var i = 0; i < this.spies_.length; i++) {\n var spy = this.spies_[i];\n spy.baseObj[spy.methodName] = spy.originalValue;\n }\n this.spies_ = [];\n};\n\n/**\n * Internal representation of a Jasmine suite.\n *\n * @constructor\n * @param {jasmine.Env} env\n * @param {String} description\n * @param {Function} specDefinitions\n * @param {jasmine.Suite} parentSuite\n */\njasmine.Suite = function(env, description, specDefinitions, parentSuite) {\n var self = this;\n self.id = env.nextSuiteId ? env.nextSuiteId() : null;\n self.description = description;\n self.queue = new jasmine.Queue(env);\n self.parentSuite = parentSuite;\n self.env = env;\n self.before_ = [];\n self.after_ = [];\n self.children_ = [];\n self.suites_ = [];\n self.specs_ = [];\n};\n\njasmine.Suite.prototype.getFullName = function() {\n var fullName = this.description;\n for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {\n fullName = parentSuite.description + ' ' + fullName;\n }\n return fullName;\n};\n\njasmine.Suite.prototype.finish = function(onComplete) {\n this.env.reporter.reportSuiteResults(this);\n this.finished = true;\n if (typeof(onComplete) == 'function') {\n onComplete();\n }\n};\n\njasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {\n beforeEachFunction.typeName = 'beforeEach';\n this.before_.unshift(beforeEachFunction);\n};\n\njasmine.Suite.prototype.afterEach = function(afterEachFunction) {\n afterEachFunction.typeName = 'afterEach';\n this.after_.unshift(afterEachFunction);\n};\n\njasmine.Suite.prototype.results = function() {\n return this.queue.results();\n};\n\njasmine.Suite.prototype.add = function(suiteOrSpec) {\n this.children_.push(suiteOrSpec);\n if (suiteOrSpec instanceof jasmine.Suite) {\n this.suites_.push(suiteOrSpec);\n this.env.currentRunner().addSuite(suiteOrSpec);\n } else {\n this.specs_.push(suiteOrSpec);\n }\n this.queue.add(suiteOrSpec);\n};\n\njasmine.Suite.prototype.specs = function() {\n return this.specs_;\n};\n\njasmine.Suite.prototype.suites = function() {\n return this.suites_;\n};\n\njasmine.Suite.prototype.children = function() {\n return this.children_;\n};\n\njasmine.Suite.prototype.execute = function(onComplete) {\n var self = this;\n this.queue.start(function () {\n self.finish(onComplete);\n });\n};\njasmine.WaitsBlock = function(env, timeout, spec) {\n this.timeout = timeout;\n jasmine.Block.call(this, env, null, spec);\n};\n\njasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);\n\njasmine.WaitsBlock.prototype.execute = function (onComplete) {\n if (jasmine.VERBOSE) {\n this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');\n }\n this.env.setTimeout(function () {\n onComplete();\n }, this.timeout);\n};\n/**\n * A block which waits for some condition to become true, with timeout.\n *\n * @constructor\n * @extends jasmine.Block\n * @param {jasmine.Env} env The Jasmine environment.\n * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.\n * @param {Function} latchFunction A function which returns true when the desired condition has been met.\n * @param {String} message The message to display if the desired condition hasn't been met within the given time period.\n * @param {jasmine.Spec} spec The Jasmine spec.\n */\njasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {\n this.timeout = timeout || env.defaultTimeoutInterval;\n this.latchFunction = latchFunction;\n this.message = message;\n this.totalTimeSpentWaitingForLatch = 0;\n jasmine.Block.call(this, env, null, spec);\n};\njasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);\n\njasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;\n\njasmine.WaitsForBlock.prototype.execute = function(onComplete) {\n if (jasmine.VERBOSE) {\n this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));\n }\n var latchFunctionResult;\n try {\n latchFunctionResult = this.latchFunction.apply(this.spec);\n } catch (e) {\n this.spec.fail(e);\n onComplete();\n return;\n }\n\n if (latchFunctionResult) {\n onComplete();\n } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {\n var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');\n this.spec.fail({\n name: 'timeout',\n message: message\n });\n\n this.abort = true;\n onComplete();\n } else {\n this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;\n var self = this;\n this.env.setTimeout(function() {\n self.execute(onComplete);\n }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);\n }\n};\n\njasmine.version_= {\n \"major\": 1,\n \"minor\": 3,\n \"build\": 1,\n \"revision\": 1354556913\n};\n", -"all":"require(\"./phantom\");\nrequire(\"./console\");\n\n// TODO Also bundle jasmine.css here.\nvar jasmine = require(\"./jasmine\");\nrequire(\"./jasmine-html\");\nrequire(\"./jasmine-support\");\n\nrequire(\"./HtmlReporter\");\nrequire(\"./PrintReporter\");\nrequire(\"./ReporterView\");\nrequire(\"./SpecView\");\nrequire(\"./SuiteView\");\n\nvar env = jasmine.getEnv();\nenv.addReporter(new jasmine.HtmlReporter);\nenv.addReporter(new jasmine.PrintReporter);\n\nfunction exposeFrom(obj) {\n obj.spyOn = jasmine.spyOn;\n obj.it = jasmine.it;\n obj.xit = jasmine.xit;\n obj.expect = jasmine.expect;\n obj.runs = jasmine.runs;\n obj.waits = jasmine.waits;\n obj.waitsFor = jasmine.waitsFor;\n obj.beforeEach = jasmine.beforeEach;\n obj.afterEach = jasmine.afterEach;\n obj.describe = jasmine.describe;\n obj.xdescribe = jasmine.xdescribe;\n obj.jasmine = jasmine;\n return obj;\n}\njasmine.exposeFrom = exposeFrom;\nvar global = Function(\"return this\")();\nexposeFrom(global);\n\nmodule.exports = jasmine;\n", -"phantom":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * This module provides a bridge from content-land to phantom-land via the\n * window.callPhantom interface.\n */\n\nvar console = require(\"./console\");\nvar global = Function(\"return this\")();\n\nif (global.callPhantom) {\n // Phantom's onConsoleMessage support is lacking (only one argument\n // supported, and it must be a string), so we use callPhantom to\n // forward console messages instead.\n console.addListener(function(method, args) {\n global.callPhantom({\n type: \"console\",\n method: method,\n args: args\n });\n });\n\n exports.exit = function(code) {\n global.callPhantom({\n type: \"exit\",\n code: code\n });\n };\n\n} else {\n exports.exit = function() {};\n}\n", -"console":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * This module allows interception of console.* method calls, so that\n * listeners other than the native console object can consume logged\n * messages.\n */\n\nvar global = Function(\"return this\")();\nvar Ap = Array.prototype;\nvar slice = Ap.slice;\n\nvar nativeConsole;\nif (\"console\" in global) {\n var gc = global.console;\n try { delete global.console } catch (ignored) {}\n nativeConsole = global.console || gc;\n global.console = gc;\n}\n\n// Provide a reliable console interface in all browsers.\nglobal.console = exports;\n\nfunction makeLogger(method) {\n var logger = exports[method] = function() {\n var args = slice.call(arguments);\n listeners.forEach(function(listener) {\n listener(method, args, logger);\n });\n };\n}\n\nmakeLogger(\"info\");\nmakeLogger(\"log\");\nmakeLogger(\"debug\");\nmakeLogger(\"warn\");\nmakeLogger(\"error\");\nmakeLogger(\"dir\");\nmakeLogger(\"dirxml\");\nmakeLogger(\"trace\");\nmakeLogger(\"assert\");\nmakeLogger(\"count\");\nmakeLogger(\"markTimeline\");\nmakeLogger(\"profile\");\nmakeLogger(\"profileEnd\");\nmakeLogger(\"time\");\nmakeLogger(\"timeEnd\");\nmakeLogger(\"timeStamp\");\nmakeLogger(\"group\");\nmakeLogger(\"groupCollapsed\");\nmakeLogger(\"groupEnd\");\nmakeLogger(\"clear\");\n\nvar listeners = [];\nfunction addListener(listener) {\n listeners.push(listener);\n}\nexports.addListener = addListener\n\nfunction clean(arg) {\n if (typeof arg === \"string\") {\n // Remove any xterm-color escape sequences.\n // TODO Display colors in console if possible.\n arg = arg.replace(/\\033\\[\\d+m/g, \"\");\n }\n return arg;\n}\n\nif (nativeConsole) {\n // If present, the native console object becomes a listener just like\n // any other.\n addListener(function(method, args) {\n var method = nativeConsole[method];\n if (method) {\n method.apply(nativeConsole, args.map(clean));\n } else {\n // Ignore this call.\n }\n });\n}\n", -"jasmine-html":"var jasmine = require(\"./jasmine\");\n\njasmine.HtmlReporterHelpers = {};\n\njasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {\n var el = document.createElement(type);\n\n for (var i = 2; i < arguments.length; i++) {\n var child = arguments[i];\n\n if (typeof child === 'string') {\n el.appendChild(document.createTextNode(child));\n } else {\n if (child) {\n el.appendChild(child);\n }\n }\n }\n\n for (var attr in attrs) {\n if (attr == \"className\") {\n el[attr] = attrs[attr];\n } else {\n el.setAttribute(attr, attrs[attr]);\n }\n }\n\n return el;\n};\n\njasmine.HtmlReporterHelpers.getSpecStatus = function(child) {\n var results = child.results();\n var status = results.passed() ? 'passed' : 'failed';\n if (results.skipped) {\n status = 'skipped';\n }\n\n return status;\n};\n\njasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {\n var parentDiv = this.dom.summary;\n var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';\n var parent = child[parentSuite];\n\n if (parent) {\n if (typeof this.views.suites[parent.id] == 'undefined') {\n this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);\n }\n parentDiv = this.views.suites[parent.id].element;\n }\n\n parentDiv.appendChild(childElement);\n};\n\n\njasmine.HtmlReporterHelpers.addHelpers = function(ctor) {\n for(var fn in jasmine.HtmlReporterHelpers) {\n ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];\n }\n};\n\njasmine.HtmlReporter = function(_doc) {\n var self = this;\n var doc = _doc || window.document;\n\n var reporterView;\n\n var dom = {};\n\n // Jasmine Reporter Public Interface\n self.logRunningSpecs = false;\n\n self.reportRunnerStarting = function(runner) {\n var specs = runner.specs() || [];\n\n if (specs.length == 0) {\n return;\n }\n\n createReporterDom(runner.env.versionString());\n doc.body.appendChild(dom.reporter);\n setExceptionHandling();\n\n reporterView = new jasmine.HtmlReporter.ReporterView(dom);\n reporterView.addSpecs(specs, self.specFilter);\n };\n\n self.reportRunnerResults = function(runner) {\n reporterView && reporterView.complete();\n };\n\n self.reportSuiteResults = function(suite) {\n reporterView.suiteComplete(suite);\n };\n\n self.reportSpecStarting = function(spec) {\n if (self.logRunningSpecs) {\n self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');\n }\n };\n\n self.reportSpecResults = function(spec) {\n reporterView.specComplete(spec);\n };\n\n self.log = function() {\n var console = jasmine.getGlobal().console;\n if (console && console.log) {\n if (console.log.apply) {\n console.log.apply(console, arguments);\n } else {\n console.log(arguments); // ie fix: console.log.apply doesn't exist on ie\n }\n }\n };\n\n self.specFilter = function(spec) {\n if (!focusedSpecName()) {\n return true;\n }\n\n return spec.getFullName().indexOf(focusedSpecName()) === 0;\n };\n\n return self;\n\n function focusedSpecName() {\n var specName;\n\n (function memoizeFocusedSpec() {\n if (specName) {\n return;\n }\n\n var paramMap = [];\n var params = jasmine.HtmlReporter.parameters(doc);\n\n for (var i = 0; i < params.length; i++) {\n var p = params[i].split('=');\n paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);\n }\n\n specName = paramMap.spec;\n })();\n\n return specName;\n }\n\n function createReporterDom(version) {\n dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },\n dom.banner = self.createDom('div', { className: 'banner' },\n self.createDom('span', { className: 'title' }, \"Jasmine \"),\n self.createDom('span', { className: 'version' }, version)),\n\n dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),\n dom.alert = self.createDom('div', {className: 'alert'},\n self.createDom('span', { className: 'exceptions' },\n self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),\n self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),\n dom.results = self.createDom('div', {className: 'results'},\n dom.summary = self.createDom('div', { className: 'summary' }),\n dom.details = self.createDom('div', { id: 'details' }))\n );\n }\n\n function noTryCatch() {\n return window.location.search.match(/catch=false/);\n }\n\n function searchWithCatch() {\n var params = jasmine.HtmlReporter.parameters(window.document);\n var removed = false;\n var i = 0;\n\n while (!removed && i < params.length) {\n if (params[i].match(/catch=/)) {\n params.splice(i, 1);\n removed = true;\n }\n i++;\n }\n if (jasmine.CATCH_EXCEPTIONS) {\n params.push(\"catch=false\");\n }\n\n return params.join(\"&\");\n }\n\n function setExceptionHandling() {\n var chxCatch = document.getElementById('no_try_catch');\n\n if (noTryCatch()) {\n chxCatch.setAttribute('checked', true);\n jasmine.CATCH_EXCEPTIONS = false;\n }\n chxCatch.onclick = function() {\n window.location.search = searchWithCatch();\n };\n }\n};\njasmine.HtmlReporter.parameters = function(doc) {\n var paramStr = doc.location.search.substring(1);\n var params = [];\n\n if (paramStr.length > 0) {\n params = paramStr.split('&');\n }\n return params;\n}\njasmine.HtmlReporter.sectionLink = function(sectionName) {\n var link = '?';\n var params = [];\n\n if (sectionName) {\n params.push('spec=' + encodeURIComponent(sectionName));\n }\n if (!jasmine.CATCH_EXCEPTIONS) {\n params.push(\"catch=false\");\n }\n if (params.length > 0) {\n link += params.join(\"&\");\n }\n\n return link;\n};\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);\njasmine.HtmlReporter.ReporterView = function(dom) {\n this.startedAt = new Date();\n this.runningSpecCount = 0;\n this.completeSpecCount = 0;\n this.passedCount = 0;\n this.failedCount = 0;\n this.skippedCount = 0;\n\n this.createResultsMenu = function() {\n this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},\n this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: \"#\"}, '0 specs'),\n ' | ',\n this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: \"#\"}, '0 failing'));\n\n this.summaryMenuItem.onclick = function() {\n dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');\n };\n\n this.detailsMenuItem.onclick = function() {\n showDetails();\n };\n };\n\n this.addSpecs = function(specs, specFilter) {\n this.totalSpecCount = specs.length;\n\n this.views = {\n specs: {},\n suites: {}\n };\n\n for (var i = 0; i < specs.length; i++) {\n var spec = specs[i];\n this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);\n if (specFilter(spec)) {\n this.runningSpecCount++;\n }\n }\n };\n\n this.specComplete = function(spec) {\n this.completeSpecCount++;\n\n if (isUndefined(this.views.specs[spec.id])) {\n this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);\n }\n\n var specView = this.views.specs[spec.id];\n\n switch (specView.status()) {\n case 'passed':\n this.passedCount++;\n break;\n\n case 'failed':\n this.failedCount++;\n break;\n\n case 'skipped':\n this.skippedCount++;\n break;\n }\n\n specView.refresh();\n this.refresh();\n };\n\n this.suiteComplete = function(suite) {\n var suiteView = this.views.suites[suite.id];\n if (isUndefined(suiteView)) {\n return;\n }\n suiteView.refresh();\n };\n\n this.refresh = function() {\n\n if (isUndefined(this.resultsMenu)) {\n this.createResultsMenu();\n }\n\n // currently running UI\n if (isUndefined(this.runningAlert)) {\n this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: \"runningAlert bar\" });\n dom.alert.appendChild(this.runningAlert);\n }\n this.runningAlert.innerHTML = \"Running \" + this.completeSpecCount + \" of \" + specPluralizedFor(this.totalSpecCount);\n\n // skipped specs UI\n if (isUndefined(this.skippedAlert)) {\n this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: \"skippedAlert bar\" });\n }\n\n this.skippedAlert.innerHTML = \"Skipping \" + this.skippedCount + \" of \" + specPluralizedFor(this.totalSpecCount) + \" - run all\";\n\n if (this.skippedCount === 1 && isDefined(dom.alert)) {\n dom.alert.appendChild(this.skippedAlert);\n }\n\n // passing specs UI\n if (isUndefined(this.passedAlert)) {\n this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: \"passingAlert bar\" });\n }\n this.passedAlert.innerHTML = \"Passing \" + specPluralizedFor(this.passedCount);\n\n // failing specs UI\n if (isUndefined(this.failedAlert)) {\n this.failedAlert = this.createDom('span', {href: \"?\", className: \"failingAlert bar\"});\n }\n this.failedAlert.innerHTML = \"Failing \" + specPluralizedFor(this.failedCount);\n\n if (this.failedCount === 1 && isDefined(dom.alert)) {\n dom.alert.appendChild(this.failedAlert);\n dom.alert.appendChild(this.resultsMenu);\n }\n\n // summary info\n this.summaryMenuItem.innerHTML = \"\" + specPluralizedFor(this.runningSpecCount);\n this.detailsMenuItem.innerHTML = \"\" + this.failedCount + \" failing\";\n };\n\n this.complete = function() {\n dom.alert.removeChild(this.runningAlert);\n\n this.skippedAlert.innerHTML = \"Ran \" + this.runningSpecCount + \" of \" + specPluralizedFor(this.totalSpecCount) + \" - run all\";\n\n if (this.failedCount === 0) {\n dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, \"Passing \" + specPluralizedFor(this.passedCount)));\n } else {\n showDetails();\n }\n\n dom.banner.appendChild(this.createDom('span', {className: 'duration'}, \"finished in \" + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + \"s\"));\n };\n\n return this;\n\n function showDetails() {\n if (dom.reporter.className.search(/showDetails/) === -1) {\n dom.reporter.className += \" showDetails\";\n }\n }\n\n function isUndefined(obj) {\n return typeof obj === 'undefined';\n }\n\n function isDefined(obj) {\n return !isUndefined(obj);\n }\n\n function specPluralizedFor(count) {\n var str = count + \" spec\";\n if (count > 1) {\n str += \"s\"\n }\n return str;\n }\n\n};\n\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);\n\n\njasmine.HtmlReporter.SpecView = function(spec, dom, views) {\n this.spec = spec;\n this.dom = dom;\n this.views = views;\n\n this.symbol = this.createDom('li', { className: 'pending' });\n this.dom.symbolSummary.appendChild(this.symbol);\n\n this.summary = this.createDom('div', { className: 'specSummary' },\n this.createDom('a', {\n className: 'description',\n href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),\n title: this.spec.getFullName()\n }, this.spec.description)\n );\n\n this.detail = this.createDom('div', { className: 'specDetail' },\n this.createDom('a', {\n className: 'description',\n href: '?spec=' + encodeURIComponent(this.spec.getFullName()),\n title: this.spec.getFullName()\n }, this.spec.getFullName())\n );\n};\n\njasmine.HtmlReporter.SpecView.prototype.status = function() {\n return this.getSpecStatus(this.spec);\n};\n\njasmine.HtmlReporter.SpecView.prototype.refresh = function() {\n this.symbol.className = this.status();\n\n switch (this.status()) {\n case 'skipped':\n break;\n\n case 'passed':\n this.appendSummaryToSuiteDiv();\n break;\n\n case 'failed':\n this.appendSummaryToSuiteDiv();\n this.appendFailureDetail();\n break;\n }\n};\n\njasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {\n this.summary.className += ' ' + this.status();\n this.appendToSummary(this.spec, this.summary);\n};\n\njasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {\n this.detail.className += ' ' + this.status();\n\n var resultItems = this.spec.results().getItems();\n var messagesDiv = this.createDom('div', { className: 'messages' });\n\n for (var i = 0; i < resultItems.length; i++) {\n var result = resultItems[i];\n\n if (result.type == 'log') {\n messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));\n } else if (result.type == 'expect' && result.passed && !result.passed()) {\n messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));\n\n if (result.trace.stack) {\n messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));\n }\n }\n }\n\n if (messagesDiv.childNodes.length > 0) {\n this.detail.appendChild(messagesDiv);\n this.dom.details.appendChild(this.detail);\n }\n};\n\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {\n this.suite = suite;\n this.dom = dom;\n this.views = views;\n\n this.element = this.createDom('div', { className: 'suite' },\n this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)\n );\n\n this.appendToSummary(this.suite, this.element);\n};\n\njasmine.HtmlReporter.SuiteView.prototype.status = function() {\n return this.getSpecStatus(this.suite);\n};\n\njasmine.HtmlReporter.SuiteView.prototype.refresh = function() {\n this.element.className += \" \" + this.status();\n};\n\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);\n\n/* @deprecated Use jasmine.HtmlReporter instead\n */\njasmine.TrivialReporter = function(doc) {\n this.document = doc || document;\n this.suiteDivs = {};\n this.logRunningSpecs = false;\n};\n\njasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {\n var el = document.createElement(type);\n\n for (var i = 2; i < arguments.length; i++) {\n var child = arguments[i];\n\n if (typeof child === 'string') {\n el.appendChild(document.createTextNode(child));\n } else {\n if (child) { el.appendChild(child); }\n }\n }\n\n for (var attr in attrs) {\n if (attr == \"className\") {\n el[attr] = attrs[attr];\n } else {\n el.setAttribute(attr, attrs[attr]);\n }\n }\n\n return el;\n};\n\njasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {\n var showPassed, showSkipped;\n\n this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },\n this.createDom('div', { className: 'banner' },\n this.createDom('div', { className: 'logo' },\n this.createDom('span', { className: 'title' }, \"Jasmine\"),\n this.createDom('span', { className: 'version' }, runner.env.versionString())),\n this.createDom('div', { className: 'options' },\n \"Show \",\n showPassed = this.createDom('input', { id: \"__jasmine_TrivialReporter_showPassed__\", type: 'checkbox' }),\n this.createDom('label', { \"for\": \"__jasmine_TrivialReporter_showPassed__\" }, \" passed \"),\n showSkipped = this.createDom('input', { id: \"__jasmine_TrivialReporter_showSkipped__\", type: 'checkbox' }),\n this.createDom('label', { \"for\": \"__jasmine_TrivialReporter_showSkipped__\" }, \" skipped\")\n )\n ),\n\n this.runnerDiv = this.createDom('div', { className: 'runner running' },\n this.createDom('a', { className: 'run_spec', href: '?' }, \"run all\"),\n this.runnerMessageSpan = this.createDom('span', {}, \"Running...\"),\n this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, \"\"))\n );\n\n this.document.body.appendChild(this.outerDiv);\n\n var suites = runner.suites();\n for (var i = 0; i < suites.length; i++) {\n var suite = suites[i];\n var suiteDiv = this.createDom('div', { className: 'suite' },\n this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, \"run\"),\n this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));\n this.suiteDivs[suite.id] = suiteDiv;\n var parentDiv = this.outerDiv;\n if (suite.parentSuite) {\n parentDiv = this.suiteDivs[suite.parentSuite.id];\n }\n parentDiv.appendChild(suiteDiv);\n }\n\n this.startedAt = new Date();\n\n var self = this;\n showPassed.onclick = function(evt) {\n if (showPassed.checked) {\n self.outerDiv.className += ' show-passed';\n } else {\n self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');\n }\n };\n\n showSkipped.onclick = function(evt) {\n if (showSkipped.checked) {\n self.outerDiv.className += ' show-skipped';\n } else {\n self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');\n }\n };\n};\n\njasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {\n var results = runner.results();\n var className = (results.failedCount > 0) ? \"runner failed\" : \"runner passed\";\n this.runnerDiv.setAttribute(\"class\", className);\n //do it twice for IE\n this.runnerDiv.setAttribute(\"className\", className);\n var specs = runner.specs();\n var specCount = 0;\n for (var i = 0; i < specs.length; i++) {\n if (this.specFilter(specs[i])) {\n specCount++;\n }\n }\n var message = \"\" + specCount + \" spec\" + (specCount == 1 ? \"\" : \"s\" ) + \", \" + results.failedCount + \" failure\" + ((results.failedCount == 1) ? \"\" : \"s\");\n message += \" in \" + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + \"s\";\n this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);\n\n this.finishedAtSpan.appendChild(document.createTextNode(\"Finished at \" + new Date().toString()));\n};\n\njasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {\n var results = suite.results();\n var status = results.passed() ? 'passed' : 'failed';\n if (results.totalCount === 0) { // todo: change this to check results.skipped\n status = 'skipped';\n }\n this.suiteDivs[suite.id].className += \" \" + status;\n};\n\njasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {\n if (this.logRunningSpecs) {\n this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');\n }\n};\n\njasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {\n var results = spec.results();\n var status = results.passed() ? 'passed' : 'failed';\n if (results.skipped) {\n status = 'skipped';\n }\n var specDiv = this.createDom('div', { className: 'spec ' + status },\n this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, \"run\"),\n this.createDom('a', {\n className: 'description',\n href: '?spec=' + encodeURIComponent(spec.getFullName()),\n title: spec.getFullName()\n }, spec.description));\n\n\n var resultItems = results.getItems();\n var messagesDiv = this.createDom('div', { className: 'messages' });\n for (var i = 0; i < resultItems.length; i++) {\n var result = resultItems[i];\n\n if (result.type == 'log') {\n messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));\n } else if (result.type == 'expect' && result.passed && !result.passed()) {\n messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));\n\n if (result.trace.stack) {\n messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));\n }\n }\n }\n\n if (messagesDiv.childNodes.length > 0) {\n specDiv.appendChild(messagesDiv);\n }\n\n this.suiteDivs[spec.suite.id].appendChild(specDiv);\n};\n\njasmine.TrivialReporter.prototype.log = function() {\n var console = jasmine.getGlobal().console;\n if (console && console.log) {\n if (console.log.apply) {\n console.log.apply(console, arguments);\n } else {\n console.log(arguments); // ie fix: console.log.apply doesn't exist on ie\n }\n }\n};\n\njasmine.TrivialReporter.prototype.getLocation = function() {\n return this.document.location;\n};\n\njasmine.TrivialReporter.prototype.specFilter = function(spec) {\n var paramMap = {};\n var params = this.getLocation().search.substring(1).split('&');\n for (var i = 0; i < params.length; i++) {\n var p = params[i].split('=');\n paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);\n }\n\n if (!paramMap.spec) {\n return true;\n }\n return spec.getFullName().indexOf(paramMap.spec) === 0;\n};\n", -"jasmine-support":"var jasmine = require(\"./jasmine\");\nvar spec = false; // TODO\n\n// Add some matcher for mock functions\njasmine.getEnv().beforeEach(function() {\n this.addMatchers({\n toBeCalled: function() {\n if (this.actual.mock === undefined) {\n throw Error('toBeCalled() should be used on a mock function');\n }\n return this.actual.mock.calls.length !== 0;\n },\n\n lastCalledWith: function() {\n if (this.actual.mock === undefined) {\n throw Error('toBeCalled() should be used on a mock function');\n }\n var calls = this.actual.mock.calls;\n var args = Array.prototype.slice.call(arguments);\n return this.env.equals_(calls[calls.length - 1], args);\n },\n\n toBeCalledWith: function() {\n if (this.actual.mock === undefined) {\n throw Error('toBeCalled() should be used on a mock function');\n }\n var args = Array.prototype.slice.call(arguments);\n return this.actual.mock.calls.some(function(call) {\n return this.env.equals_(call, args);\n }.bind(this));\n }\n });\n});\n\nvar _it = jasmine.Env.prototype.it;\nvar _xit = jasmine.Env.prototype.xit;\njasmine.Env.prototype.it = function(desc, func) {\n // If spec is provided, only run matching specs\n if (!spec || desc.match(new RegExp(spec, 'i'))) {\n return _it.call(this, desc, func);\n } else {\n return this.xit(desc, func);\n }\n};\njasmine.Env.prototype.xit = function(desc, func) {\n if (typeof func == 'function') {\n var matches = func.toString().match(/.*\\W?expect\\(/g);\n if (matches) {\n this.reporter.subReporters_[0].skipCount += matches.length;\n this.reporter.subReporters_[0].totalCount += matches.length;\n }\n }\n return _xit.call(this, desc, func);\n}\n\n// Mainline Jasmine sets __Jasmine_been_here_before__ on each object to detect\n// cycles, but that doesn't work on frozen objects so we use a WeakMap instead.\n// We can only do this if if WeakMap is available, but if WeakMap is\n// unavailable, then objects probably can't be frozen anyway.\n\nif (typeof WeakMap !== \"undefined\") {\n var _comparedObjects = new WeakMap;\n\n jasmine.Env.prototype.compareObjects_ =\n function(a, b, mismatchKeys, mismatchValues) {\n if (_comparedObjects.get(a) === b && _comparedObjects.get(b) === a) {\n return true;\n }\n var areArrays = jasmine.isArray_(a) && jasmine.isArray_(b);\n\n _comparedObjects.set(a, b);\n _comparedObjects.set(b, a);\n\n var hasKey = function(obj, keyName) {\n return obj != null && obj[keyName] !== jasmine.undefined;\n };\n\n for (var property in b) {\n if (areArrays && typeof b[property] == 'function') {\n continue;\n }\n if (!hasKey(a, property) && hasKey(b, property)) {\n mismatchKeys.push(\n \"expected has key '\" + property + \"', but missing from actual.\"\n );\n }\n }\n for (property in a) {\n if (areArrays && typeof a[property] == 'function') {\n continue;\n }\n if (!hasKey(b, property) && hasKey(a, property)) {\n mismatchKeys.push(\n \"expected missing key '\" + property + \"', but present in actual.\"\n );\n }\n }\n for (property in b) {\n // The only different implementation from the original jasmine\n if (areArrays &&\n (typeof a[property] == 'function' ||\n typeof b[property] == 'function')) {\n continue;\n }\n if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues))\n {\n mismatchValues.push(\n \"'\" + property + \"' was '\" + (b[property] ?\n jasmine.util.htmlEscape(b[property].toString()) :\n b[property]) +\n \"' in expected, but was '\" + (a[property] ?\n jasmine.util.htmlEscape(a[property].toString()) :\n a[property]) + \"' in actual.\"\n );\n }\n }\n\n if (areArrays &&\n a.length != b.length) {\n mismatchValues.push(\"arrays were not the same length\");\n }\n\n _comparedObjects.delete(a);\n _comparedObjects.delete(b);\n return (mismatchKeys.length == 0 && mismatchValues.length == 0);\n };\n}\n", -"HtmlReporter":"var jasmine = require(\"./jasmine\");\n\nexports.HtmlReporter =\njasmine.HtmlReporter = function(_doc) {\n var self = this;\n var doc = _doc || window.document;\n\n var reporterView;\n\n var dom = {};\n\n // Jasmine Reporter Public Interface\n self.logRunningSpecs = false;\n\n self.reportRunnerStarting = function(runner) {\n var specs = runner.specs() || [];\n\n if (specs.length == 0) {\n return;\n }\n\n createReporterDom(runner.env.versionString());\n doc.body.appendChild(dom.reporter);\n setExceptionHandling();\n\n reporterView = new jasmine.HtmlReporter.ReporterView(dom);\n reporterView.addSpecs(specs, self.specFilter);\n };\n\n self.reportRunnerResults = function(runner) {\n reporterView && reporterView.complete();\n };\n\n self.reportSuiteResults = function(suite) {\n reporterView.suiteComplete(suite);\n };\n\n self.reportSpecStarting = function(spec) {\n if (self.logRunningSpecs) {\n self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');\n }\n };\n\n self.reportSpecResults = function(spec) {\n reporterView.specComplete(spec);\n };\n\n self.log = function() {\n var console = jasmine.getGlobal().console;\n if (console && console.log) {\n if (console.log.apply) {\n console.log.apply(console, arguments);\n } else {\n console.log(arguments); // ie fix: console.log.apply doesn't exist on ie\n }\n }\n };\n\n self.specFilter = function(spec) {\n if (!focusedSpecName()) {\n return true;\n }\n\n return spec.getFullName().indexOf(focusedSpecName()) === 0;\n };\n\n return self;\n\n function focusedSpecName() {\n var specName;\n\n (function memoizeFocusedSpec() {\n if (specName) {\n return;\n }\n\n var paramMap = [];\n var params = jasmine.HtmlReporter.parameters(doc);\n\n for (var i = 0; i < params.length; i++) {\n var p = params[i].split('=');\n paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);\n }\n\n specName = paramMap.spec;\n })();\n\n return specName;\n }\n\n function createReporterDom(version) {\n dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },\n dom.banner = self.createDom('div', { className: 'banner' },\n self.createDom('span', { className: 'title' }, \"Jasmine \"),\n self.createDom('span', { className: 'version' }, version)),\n\n dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),\n dom.alert = self.createDom('div', {className: 'alert'},\n self.createDom('span', { className: 'exceptions' },\n self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),\n self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),\n dom.results = self.createDom('div', {className: 'results'},\n dom.summary = self.createDom('div', { className: 'summary' }),\n dom.details = self.createDom('div', { id: 'details' }))\n );\n }\n\n function noTryCatch() {\n return window.location.search.match(/catch=false/);\n }\n\n function searchWithCatch() {\n var params = jasmine.HtmlReporter.parameters(window.document);\n var removed = false;\n var i = 0;\n\n while (!removed && i < params.length) {\n if (params[i].match(/catch=/)) {\n params.splice(i, 1);\n removed = true;\n }\n i++;\n }\n if (jasmine.CATCH_EXCEPTIONS) {\n params.push(\"catch=false\");\n }\n\n return params.join(\"&\");\n }\n\n function setExceptionHandling() {\n var chxCatch = document.getElementById('no_try_catch');\n\n if (noTryCatch()) {\n chxCatch.setAttribute('checked', true);\n jasmine.CATCH_EXCEPTIONS = false;\n }\n chxCatch.onclick = function() {\n window.location.search = searchWithCatch();\n };\n }\n};\njasmine.HtmlReporter.parameters = function(doc) {\n var paramStr = doc.location.search.substring(1);\n var params = [];\n\n if (paramStr.length > 0) {\n params = paramStr.split('&');\n }\n return params;\n}\njasmine.HtmlReporter.sectionLink = function(sectionName) {\n var link = '?';\n var params = [];\n\n if (sectionName) {\n params.push('spec=' + encodeURIComponent(sectionName));\n }\n if (!jasmine.CATCH_EXCEPTIONS) {\n params.push(\"catch=false\");\n }\n if (params.length > 0) {\n link += params.join(\"&\");\n }\n\n return link;\n};\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);\n", -"PrintReporter":"var jasmine = require(\"./jasmine\");\nvar diff = require('./diff');\n\nvar red = '\\u001b[1;41m';\nvar reset = '\\u001b[0m';\n\nfunction highlightDifferences(a, b) {\n var changes = diff.diffChars(a, b);\n\n var ret = {a: '', b: ''};\n var change;\n for (var i = 0, il = changes.length; i < il; i++) {\n change = changes[i];\n if (change.added) {\n ret.b += red + change.value + reset;\n } else if (change.removed) {\n ret.a += red + change.value + reset;\n } else {\n ret.a += change.value;\n ret.b += change.value;\n }\n }\n return ret;\n}\n\nfunction PrintReporter(name, root_directory) {\n this.skipCount = 0;\n this.failCount = 0;\n this.expectCount = 0;\n this.specCount = 0;\n this.name = name;\n this.rootDirectory = root_directory;\n}\nexports.PrintReporter =\njasmine.PrintReporter = PrintReporter;\n\nPrintReporter.prototype = new jasmine.Reporter();\n// Set verbose=true on the test instance to enable additional logging\nPrintReporter.prototype.verbose = false;\nPrintReporter.prototype._didSpecName = false;\n\nPrintReporter.prototype.reportSpecStarting = function(spec) {\n this._didSpecName = false;\n this._spec = spec;\n};\n\nPrintReporter.prototype.reportRunnerResults = function(runner) {\n // Don't print out the spec name at the end\n this._didSpecName = true;\n\n this.log([\n this.specCount + \" spec\",\n this.expectCount + \" expect\",\n this.skipCount + \" skip\",\n this.failCount + \" fail\"\n ].join(\" \"));\n\n require(\"./phantom\").exit(this.failCount);\n};\n\n\nPrintReporter.prototype.reportSuiteResults = function(suite) {\n var results = suite.results();\n if (this.verbose) {\n this.log('Suite \"' + suite.description + '\": ' +\n results.passedCount + '/' + results.totalCount + ' passed.');\n }\n\n // If suite is nested, only count the root suite\n if (!suite.parentSuite) {\n this.failCount += results.totalCount - results.passedCount;\n this.expectCount += results.totalCount;\n }\n};\n\nPrintReporter.prototype.reportSpecResults = function(spec) {\n if (this.verbose) {\n this.log('it... ' +\n spec.description + ': ' + (spec.results().passed() ? 'pass' : 'fail'));\n }\n\n var self = this;\n var results = spec.results();\n\n this.specCount += 1;\n\n if (results.skipped)\n this.skipCount += 1;\n\n results.getItems().forEach(function(result) {\n if (result.type == 'log') {\n self.log(result.toString());\n } else if (result.type == 'expect' && result.passed && !result.passed()) {\n var ppActual = jasmine.pp(result.actual);\n var ppExpected = jasmine.pp(result.expected);\n\n var colorDiff = highlightDifferences(ppActual, ppExpected);\n\n var message = result.message;\n message = message.replace(ppActual, colorDiff.a);\n message = message.replace(ppExpected, colorDiff.b);\n\n self.log(message);\n if (result.trace.stack) {\n self.log();\n result.trace.stack.split('\\n').forEach(function(stackFrame) {\n if (stackFrame.indexOf('/jasmine/lib/jasmine-core') > -1) {\n return;\n }\n if (this.rootDirectory) {\n stackFrame = stackFrame.replace(this.rootDirectory + '/', '');\n }\n self.log(' ' + stackFrame);\n }.bind(this));\n }\n }\n });\n};\n\nPrintReporter.prototype.log = function(str) {\n if (!this._didSpecName) {\n console.log('');\n console.log(\n this._spec.suite.description + ': it ' + this._spec.description);\n this._didSpecName = true;\n }\n console.log(str || '');\n};\n", -"ReporterView":"var jasmine = require(\"./jasmine\");\n\njasmine.HtmlReporter.ReporterView = function(dom) {\n this.startedAt = new Date();\n this.runningSpecCount = 0;\n this.completeSpecCount = 0;\n this.passedCount = 0;\n this.failedCount = 0;\n this.skippedCount = 0;\n\n this.createResultsMenu = function() {\n this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},\n this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: \"#\"}, '0 specs'),\n ' | ',\n this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: \"#\"}, '0 failing'));\n\n this.summaryMenuItem.onclick = function() {\n dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');\n };\n\n this.detailsMenuItem.onclick = function() {\n showDetails();\n };\n };\n\n this.addSpecs = function(specs, specFilter) {\n this.totalSpecCount = specs.length;\n\n this.views = {\n specs: {},\n suites: {}\n };\n\n for (var i = 0; i < specs.length; i++) {\n var spec = specs[i];\n this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);\n if (specFilter(spec)) {\n this.runningSpecCount++;\n }\n }\n };\n\n this.specComplete = function(spec) {\n this.completeSpecCount++;\n\n if (isUndefined(this.views.specs[spec.id])) {\n this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);\n }\n\n var specView = this.views.specs[spec.id];\n\n switch (specView.status()) {\n case 'passed':\n this.passedCount++;\n break;\n\n case 'failed':\n this.failedCount++;\n break;\n\n case 'skipped':\n this.skippedCount++;\n break;\n }\n\n specView.refresh();\n this.refresh();\n };\n\n this.suiteComplete = function(suite) {\n var suiteView = this.views.suites[suite.id];\n if (isUndefined(suiteView)) {\n return;\n }\n suiteView.refresh();\n };\n\n this.refresh = function() {\n\n if (isUndefined(this.resultsMenu)) {\n this.createResultsMenu();\n }\n\n // currently running UI\n if (isUndefined(this.runningAlert)) {\n this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: \"runningAlert bar\" });\n dom.alert.appendChild(this.runningAlert);\n }\n this.runningAlert.innerHTML = \"Running \" + this.completeSpecCount + \" of \" + specPluralizedFor(this.totalSpecCount);\n\n // skipped specs UI\n if (isUndefined(this.skippedAlert)) {\n this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: \"skippedAlert bar\" });\n }\n\n this.skippedAlert.innerHTML = \"Skipping \" + this.skippedCount + \" of \" + specPluralizedFor(this.totalSpecCount) + \" - run all\";\n\n if (this.skippedCount === 1 && isDefined(dom.alert)) {\n dom.alert.appendChild(this.skippedAlert);\n }\n\n // passing specs UI\n if (isUndefined(this.passedAlert)) {\n this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: \"passingAlert bar\" });\n }\n this.passedAlert.innerHTML = \"Passing \" + specPluralizedFor(this.passedCount);\n\n // failing specs UI\n if (isUndefined(this.failedAlert)) {\n this.failedAlert = this.createDom('span', {href: \"?\", className: \"failingAlert bar\"});\n }\n this.failedAlert.innerHTML = \"Failing \" + specPluralizedFor(this.failedCount);\n\n if (this.failedCount === 1 && isDefined(dom.alert)) {\n dom.alert.appendChild(this.failedAlert);\n dom.alert.appendChild(this.resultsMenu);\n }\n\n // summary info\n this.summaryMenuItem.innerHTML = \"\" + specPluralizedFor(this.runningSpecCount);\n this.detailsMenuItem.innerHTML = \"\" + this.failedCount + \" failing\";\n };\n\n this.complete = function() {\n dom.alert.removeChild(this.runningAlert);\n\n this.skippedAlert.innerHTML = \"Ran \" + this.runningSpecCount + \" of \" + specPluralizedFor(this.totalSpecCount) + \" - run all\";\n\n if (this.failedCount === 0) {\n dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, \"Passing \" + specPluralizedFor(this.passedCount)));\n } else {\n showDetails();\n }\n\n dom.banner.appendChild(this.createDom('span', {className: 'duration'}, \"finished in \" + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + \"s\"));\n };\n\n return this;\n\n function showDetails() {\n if (dom.reporter.className.search(/showDetails/) === -1) {\n dom.reporter.className += \" showDetails\";\n }\n }\n\n function isUndefined(obj) {\n return typeof obj === 'undefined';\n }\n\n function isDefined(obj) {\n return !isUndefined(obj);\n }\n\n function specPluralizedFor(count) {\n var str = count + \" spec\";\n if (count > 1) {\n str += \"s\"\n }\n return str;\n }\n\n};\n\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);\n\n\n", -"SpecView":"var jasmine = require(\"./jasmine\");\n\njasmine.HtmlReporter.SpecView = function(spec, dom, views) {\n this.spec = spec;\n this.dom = dom;\n this.views = views;\n\n this.symbol = this.createDom('li', { className: 'pending' });\n this.dom.symbolSummary.appendChild(this.symbol);\n\n this.summary = this.createDom('div', { className: 'specSummary' },\n this.createDom('a', {\n className: 'description',\n href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),\n title: this.spec.getFullName()\n }, this.spec.description)\n );\n\n this.detail = this.createDom('div', { className: 'specDetail' },\n this.createDom('a', {\n className: 'description',\n href: '?spec=' + encodeURIComponent(this.spec.getFullName()),\n title: this.spec.getFullName()\n }, this.spec.getFullName())\n );\n};\n\njasmine.HtmlReporter.SpecView.prototype.status = function() {\n return this.getSpecStatus(this.spec);\n};\n\njasmine.HtmlReporter.SpecView.prototype.refresh = function() {\n this.symbol.className = this.status();\n\n switch (this.status()) {\n case 'skipped':\n break;\n\n case 'passed':\n this.appendSummaryToSuiteDiv();\n break;\n\n case 'failed':\n this.appendSummaryToSuiteDiv();\n this.appendFailureDetail();\n break;\n }\n};\n\njasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {\n this.summary.className += ' ' + this.status();\n this.appendToSummary(this.spec, this.summary);\n};\n\njasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {\n this.detail.className += ' ' + this.status();\n\n var resultItems = this.spec.results().getItems();\n var messagesDiv = this.createDom('div', { className: 'messages' });\n\n for (var i = 0; i < resultItems.length; i++) {\n var result = resultItems[i];\n\n if (result.type == 'log') {\n messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));\n } else if (result.type == 'expect' && result.passed && !result.passed()) {\n messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));\n\n if (result.trace.stack) {\n messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));\n }\n }\n }\n\n if (messagesDiv.childNodes.length > 0) {\n this.detail.appendChild(messagesDiv);\n this.dom.details.appendChild(this.detail);\n }\n};\n\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);", -"SuiteView":"var jasmine = require(\"./jasmine\");\n\njasmine.HtmlReporter.SuiteView = function(suite, dom, views) {\n this.suite = suite;\n this.dom = dom;\n this.views = views;\n\n this.element = this.createDom('div', { className: 'suite' },\n this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)\n );\n\n this.appendToSummary(this.suite, this.element);\n};\n\njasmine.HtmlReporter.SuiteView.prototype.status = function() {\n return this.getSpecStatus(this.suite);\n};\n\njasmine.HtmlReporter.SuiteView.prototype.refresh = function() {\n this.element.className += \" \" + this.status();\n};\n\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);\n\n", -"diff":"/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n * \n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n * \n * JsDiff.diffCss: Diff targeted at CSS content\n * \n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\nvar JsDiff = (function() {\n function clonePath(path) {\n return { newPos: path.newPos, components: path.components.slice(0) };\n }\n function removeEmpty(array) {\n var ret = [];\n for (var i = 0; i < array.length; i++) {\n if (array[i]) {\n ret.push(array[i]);\n }\n }\n return ret;\n }\n function escapeHTML(s) {\n var n = s;\n n = n.replace(/&/g, \"&\");\n n = n.replace(//g, \">\");\n n = n.replace(/\"/g, \""\");\n\n return n;\n }\n\n var fbDiff = function(ignoreWhitespace) {\n this.ignoreWhitespace = ignoreWhitespace;\n };\n fbDiff.prototype = {\n diff: function(oldString, newString) {\n // Handle the identity case (this is due to unrolling editLength == 0\n if (newString == oldString) {\n return [{ value: newString }];\n }\n if (!newString) {\n return [{ value: oldString, removed: true }];\n }\n if (!oldString) {\n return [{ value: newString, added: true }];\n }\n\n newString = this.tokenize(newString);\n oldString = this.tokenize(oldString);\n\n var newLen = newString.length, oldLen = oldString.length;\n var maxEditLength = newLen + oldLen;\n var bestPath = [{ newPos: -1, components: [] }];\n\n // Seed editLength = 0\n var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {\n return bestPath[0].components;\n }\n\n for (var editLength = 1; editLength <= maxEditLength; editLength++) {\n for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {\n var basePath;\n var addPath = bestPath[diagonalPath-1],\n removePath = bestPath[diagonalPath+1];\n oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n if (addPath) {\n // No one else is going to attempt to use this value, clear it\n bestPath[diagonalPath-1] = undefined;\n }\n\n var canAdd = addPath && addPath.newPos+1 < newLen;\n var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n if (!canAdd && !canRemove) {\n bestPath[diagonalPath] = undefined;\n continue;\n }\n\n // Select the diagonal that we want to branch from. We select the prior\n // path whose position in the new string is the farthest from the origin\n // and does not pass the bounds of the diff graph\n if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n basePath = clonePath(removePath);\n this.pushComponent(basePath.components, oldString[oldPos], undefined, true);\n } else {\n basePath = clonePath(addPath);\n basePath.newPos++;\n this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);\n }\n\n var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);\n\n if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {\n return basePath.components;\n } else {\n bestPath[diagonalPath] = basePath;\n }\n }\n }\n },\n\n pushComponent: function(components, value, added, removed) {\n var last = components[components.length-1];\n if (last && last.added === added && last.removed === removed) {\n // We need to clone here as the component clone operation is just\n // as shallow array clone\n components[components.length-1] =\n {value: this.join(last.value, value), added: added, removed: removed };\n } else {\n components.push({value: value, added: added, removed: removed });\n }\n },\n extractCommon: function(basePath, newString, oldString, diagonalPath) {\n var newLen = newString.length,\n oldLen = oldString.length,\n newPos = basePath.newPos,\n oldPos = newPos - diagonalPath;\n while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {\n newPos++;\n oldPos++;\n\n this.pushComponent(basePath.components, newString[newPos], undefined, undefined);\n }\n basePath.newPos = newPos;\n return oldPos;\n },\n\n equals: function(left, right) {\n var reWhitespace = /\\S/;\n if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {\n return true;\n } else {\n return left == right;\n }\n },\n join: function(left, right) {\n return left + right;\n },\n tokenize: function(value) {\n return value;\n }\n };\n\n var CharDiff = new fbDiff();\n\n var WordDiff = new fbDiff(true);\n WordDiff.tokenize = function(value) {\n return removeEmpty(value.split(/(\\s+|\\b)/));\n };\n\n var CssDiff = new fbDiff(true);\n CssDiff.tokenize = function(value) {\n return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n };\n\n var LineDiff = new fbDiff();\n LineDiff.tokenize = function(value) {\n return value.split(/^/m);\n };\n\n return {\n diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },\n diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },\n diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },\n\n diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },\n\n createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n var ret = [];\n\n ret.push(\"Index: \" + fileName);\n ret.push(\"===================================================================\");\n ret.push(\"--- \" + fileName + (typeof oldHeader === \"undefined\" ? \"\" : \"\\t\" + oldHeader));\n ret.push(\"+++ \" + fileName + (typeof newHeader === \"undefined\" ? \"\" : \"\\t\" + newHeader));\n\n var diff = LineDiff.diff(oldStr, newStr);\n if (!diff[diff.length-1].value) {\n diff.pop(); // Remove trailing newline add\n }\n diff.push({value: \"\", lines: []}); // Append an empty value to make cleanup easier\n\n function contextLines(lines) {\n return lines.map(function(entry) { return ' ' + entry; });\n }\n function eofNL(curRange, i, current) {\n var last = diff[diff.length-2],\n isLast = i === diff.length-2,\n isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);\n\n // Figure out if this is the last line for the given file and missing NL\n if (!/\\n$/.test(current.value) && (isLast || isLastOfType)) {\n curRange.push('\\\\ No newline at end of file');\n }\n }\n\n var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n oldLine = 1, newLine = 1;\n for (var i = 0; i < diff.length; i++) {\n var current = diff[i],\n lines = current.lines || current.value.replace(/\\n$/, \"\").split(\"\\n\");\n current.lines = lines;\n\n if (current.added || current.removed) {\n if (!oldRangeStart) {\n var prev = diff[i-1];\n oldRangeStart = oldLine;\n newRangeStart = newLine;\n\n if (prev) {\n curRange = contextLines(prev.lines.slice(-4));\n oldRangeStart -= curRange.length;\n newRangeStart -= curRange.length;\n }\n }\n curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?\"+\":\"-\") + entry; }));\n eofNL(curRange, i, current);\n\n if (current.added) {\n newLine += lines.length;\n } else {\n oldLine += lines.length;\n }\n } else {\n if (oldRangeStart) {\n // Close out any changes that have been output (or join overlapping)\n if (lines.length <= 8 && i < diff.length-2) {\n // Overlapping\n curRange.push.apply(curRange, contextLines(lines));\n } else {\n // end the range and output\n var contextSize = Math.min(lines.length, 4);\n ret.push(\n \"@@ -\" + oldRangeStart + \",\" + (oldLine-oldRangeStart+contextSize)\n + \" +\" + newRangeStart + \",\" + (newLine-newRangeStart+contextSize)\n + \" @@\");\n ret.push.apply(ret, curRange);\n ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n if (lines.length <= 4) {\n eofNL(ret, i, current);\n }\n\n oldRangeStart = 0; newRangeStart = 0; curRange = [];\n }\n }\n oldLine += lines.length;\n newLine += lines.length;\n }\n }\n\n return ret.join('\\n') + '\\n';\n },\n\n applyPatch: function(oldStr, uniDiff) {\n var diffstr = uniDiff.split(\"\\n\");\n var diff = [];\n var remEOFNL = false,\n addEOFNL = false;\n\n for (var i = (diffstr[0][0]==\"I\"?4:0); i < diffstr.length; i++) {\n if(diffstr[i][0] == \"@\") {\n var meh = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n diff.unshift({\n start:meh[3],\n oldlength:meh[2],\n oldlines:[],\n newlength:meh[4],\n newlines:[]\n });\n } else if(diffstr[i][0] == '+') {\n diff[0].newlines.push(diffstr[i].substr(1));\n } else if(diffstr[i][0] == '-') {\n diff[0].oldlines.push(diffstr[i].substr(1));\n } else if(diffstr[i][0] == ' ') {\n diff[0].newlines.push(diffstr[i].substr(1));\n diff[0].oldlines.push(diffstr[i].substr(1));\n } else if(diffstr[i][0] == '\\\\') {\n if (diffstr[i-1][0] == '+') {\n remEOFNL = true;\n } else if(diffstr[i-1][0] == '-') {\n addEOFNL = true;\n }\n }\n }\n\n var str = oldStr.split(\"\\n\");\n for (var i = diff.length - 1; i >= 0; i--) {\n var d = diff[i];\n for (var j = 0; j < d.oldlength; j++) {\n if(str[d.start-1+j] != d.oldlines[j]) {\n return false;\n }\n }\n Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));\n }\n\n if (remEOFNL) {\n while (!str[str.length-1]) {\n str.pop();\n }\n } else if (addEOFNL) {\n str.push('');\n }\n return str.join('\\n');\n },\n\n convertChangesToXML: function(changes){\n var ret = [];\n for ( var i = 0; i < changes.length; i++) {\n var change = changes[i];\n if (change.added) {\n ret.push(\"\");\n } else if (change.removed) {\n ret.push(\"\");\n }\n\n ret.push(escapeHTML(change.value));\n\n if (change.added) {\n ret.push(\"\");\n } else if (change.removed) {\n ret.push(\"\");\n }\n }\n return ret.join(\"\");\n },\n\n // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n convertChangesToDMP: function(changes){\n var ret = [], change;\n for ( var i = 0; i < changes.length; i++) {\n change = changes[i];\n ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);\n }\n return ret;\n }\n };\n})();\n\nif (typeof module !== \"undefined\") {\n module.exports = JsDiff;\n}\n" -}); diff --git a/build/react-test.js b/build/react-test.js deleted file mode 100644 index 69e8742c21c33..0000000000000 --- a/build/react-test.js +++ /dev/null @@ -1,266 +0,0 @@ -//# sourceURL=populist/loader.js -(function(entries, sources) { - var modules = {}; - var hasOwn = modules.hasOwnProperty; - var global = Function("return this")(); - var doc = global.document; - var head = doc.documentElement.firstChild; - - function internalRequire(id) { - var module = getModule(id); - if (module && !hasOwn.call(module, "exports")) { - module(function(rid) { - return internalRequire(absolutize(id, rid)); - }, module.exports = {}, module, global); - - // If the module id has a non-null value in the entries object, - // define a global reference to its exports object. - var globalName = entries[id]; - if (globalName && hasOwn.call(entries, id)) - global[globalName] = module.exports; - } - - return module.exports; - } - - function getModule(id) { - if (!hasOwn.call(modules, id)) { - if (hasOwn.call(sources, id)) { - var name = "module$" + Math.random().toString(36).slice(2); - var script = doc.createElement("script"); - var code = "function " + name + "(require,exports,module,global){" + - sources[id] + "\n}\n//# sourceURL=" + id + ".js\n"; - script.setAttribute("type", "text/javascript"); - script.setAttribute("encoding", "utf8"); - script.appendChild(doc.createTextNode(code)); - head.appendChild(script); - modules[id] = global[name]; - } else { - throw new Error("Missing module: " + id); - } - } - - return modules[id]; - } - - var pathNormExp = /\/(\.?|[^\/]+\/\.\.)\//; - function absolutize(id, rid) { - if (rid.charAt(0) === ".") { - rid = "/" + id + "/../" + rid; - while (rid != (id = rid.replace(pathNormExp, "/"))) - rid = id; - rid = rid.replace(/^\//, ""); - } - return rid; - } - - // Eagerly require all identifiers that are keys of the entries object. - for (var id in entries) - if (hasOwn.call(entries, id)) - internalRequire(id); -})({"test/all":"harness"},{ -"test/all":"// This file exists both to give a single entry point for all the utility\n// modules in src/test and to specify an ordering on those modules, since\n// some still have implicit dependencies on others.\n\nrequire(\"./phantomjs-shims\");\nrequire(\"../ReactTestUtils\");\nrequire(\"../reactComponentExpect\");\nrequire(\"../mocks\");\nrequire(\"../mock-modules\");\nrequire(\"./mock-timers\");\n\nexports.enableTest = function(testID) {\n require(\"../\" + testID);\n};\n\nexports.removeNextSiblings = function(node) {\n var parent = node && node.parentNode;\n if (parent) {\n while (node.nextSibling) {\n parent.removeChild(node.nextSibling);\n }\n }\n};\n", -"addons/link/__tests__/LinkedStateMixin-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n/*jshint evil:true */\n\ndescribe('LinkedStateMixin', function() {\n var LinkedStateMixin;\n var React;\n var ReactLink;\n\n beforeEach(function() {\n LinkedStateMixin = require(\"../../../LinkedStateMixin\");\n React = require(\"../../../React\");\n ReactLink = require(\"../../../ReactLink\");\n });\n\n it('should create a ReactLink for state', function() {\n var Component = React.createClass({displayName: 'Component',\n mixins: [LinkedStateMixin],\n\n getInitialState: function() {\n return {value: 'initial value'};\n },\n\n render: function() {\n return React.DOM.span(null, \"value is \", this.state.value);\n }\n });\n var container = document.createElement('div');\n var component = React.renderComponent(Component(null ), container);\n var link = component.linkState('value');\n expect(component.state.value).toBe('initial value');\n expect(link.value).toBe('initial value');\n link.requestChange('new value');\n expect(component.state.value).toBe('new value');\n expect(component.linkState('value').value).toBe('new value');\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"addons/link/__tests__/LinkedStateMixin-test\", module);\n", -"addons/transitions/__tests__/ReactTransitionGroup-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React;\nvar ReactTransitionGroup;\nvar mocks;\n\n// Most of the real functionality is covered in other unit tests, this just\n// makes sure we're wired up correctly.\ndescribe('ReactTransitionGroup', function() {\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactTransitionGroup = require(\"../../../ReactTransitionGroup\");\n mocks = require(\"../../../mocks\");\n });\n\n it('should warn after time with no transitionend', function() {\n var container;\n var a;\n\n container = document.createElement('div');\n a = React.renderComponent(\n ReactTransitionGroup( {transitionName:\"yolo\"}, \n React.DOM.span( {key:\"one\", id:\"one\"} )\n ),\n container\n );\n expect(a.getDOMNode().childNodes.length).toBe(1);\n\n setTimeout.mock.calls.length = 0;\n\n React.renderComponent(\n ReactTransitionGroup( {transitionName:\"yolo\"}, \n React.DOM.span( {key:\"two\", id:\"two\"} )\n ),\n container\n );\n expect(a.getDOMNode().childNodes.length).toBe(2);\n expect(a.getDOMNode().childNodes[0].id).toBe('two');\n expect(a.getDOMNode().childNodes[1].id).toBe('one');\n\n console.warn = mocks.getMockFunction();\n setTimeout.mock.calls[2][0]();\n\n expect(a.getDOMNode().childNodes.length).toBe(2);\n expect(console.warn.mock.calls.length).toBe(1);\n });\n\n it('should keep both sets of DOM nodes around', function() {\n var container = document.createElement('div');\n var a = React.renderComponent(\n ReactTransitionGroup( {transitionName:\"yolo\"}, \n React.DOM.span( {key:\"one\", id:\"one\"} )\n ),\n container\n );\n expect(a.getDOMNode().childNodes.length).toBe(1);\n React.renderComponent(\n ReactTransitionGroup( {transitionName:\"yolo\"}, \n React.DOM.span( {key:\"two\", id:\"two\"} )\n ),\n container\n );\n expect(a.getDOMNode().childNodes.length).toBe(2);\n expect(a.getDOMNode().childNodes[0].id).toBe('two');\n expect(a.getDOMNode().childNodes[1].id).toBe('one');\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"addons/transitions/__tests__/ReactTransitionGroup-test\", module);\n", -"addons/transitions/__tests__/ReactTransitionKeySet-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React;\nvar ReactTransitionKeySet;\n\ndescribe('ReactTransitionKeySet', function() {\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactTransitionKeySet = require(\"../../../ReactTransitionKeySet\");\n });\n\n it('should support getChildMapping', function() {\n var oneone = React.DOM.div( {key:\"oneone\"} );\n var onetwo = React.DOM.div( {key:\"onetwo\"} );\n var one = React.DOM.div( {key:\"one\"}, oneone,onetwo);\n var two = React.DOM.div( {key:\"two\"} );\n var component = React.DOM.div(null, one,two);\n expect(ReactTransitionKeySet.getChildMapping(component.props.children))\n .toEqual({\n '{one}': one,\n '{two}': two\n });\n });\n\n it('should support getKeySet', function() {\n var oneone = React.DOM.div( {key:\"oneone\"} );\n var onetwo = React.DOM.div( {key:\"onetwo\"} );\n var one = React.DOM.div( {key:\"one\"}, oneone,onetwo);\n var two = React.DOM.div( {key:\"two\"} );\n var component = React.DOM.div(null, one,two);\n expect(ReactTransitionKeySet.getKeySet(component.props.children)).toEqual({\n '{one}': true,\n '{two}': true\n });\n });\n\n it('should support mergeKeySets for adding keys', function() {\n var prev = {\n one: true,\n two: true\n };\n var next = {\n one: true,\n two: true,\n three: true\n };\n expect(ReactTransitionKeySet.mergeKeySets(prev, next)).toEqual({\n one: true,\n two: true,\n three: true\n });\n });\n\n it('should support mergeKeySets for removing keys', function() {\n var prev = {\n one: true,\n two: true,\n three: true\n };\n var next = {\n one: true,\n two: true\n };\n expect(ReactTransitionKeySet.mergeKeySets(prev, next)).toEqual({\n one: true,\n two: true,\n three: true\n });\n });\n\n it('should support mergeKeySets for adding and removing', function() {\n var prev = {\n one: true,\n two: true,\n three: true\n };\n var next = {\n one: true,\n two: true,\n four: true\n };\n expect(ReactTransitionKeySet.mergeKeySets(prev, next)).toEqual({\n one: true,\n two: true,\n three: true,\n four: true\n });\n });\n\n it('should reconcile overlapping insertions and deletions', function() {\n var prev = {\n one: true,\n two: true,\n four: true,\n five: true\n };\n var next = {\n one: true,\n two: true,\n three: true,\n five: true\n };\n expect(ReactTransitionKeySet.mergeKeySets(prev, next)).toEqual({\n one: true,\n two: true,\n three: true,\n four: true,\n five: true\n });\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"addons/transitions/__tests__/ReactTransitionKeySet-test\", module);\n", -"addons/transitions/__tests__/ReactTransitionableChild-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React;\nvar ReactTransitionableChild;\n\nvar mocks = require(\"../../../mocks\");\n\ndescribe('ReactTransitionableChild', function() {\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactTransitionableChild = require(\"../../../ReactTransitionableChild\");\n });\n\n it('should keep the DOM node around', function() {\n var container = document.createElement('div');\n var ac = React.renderComponent(\n ReactTransitionableChild(null, React.DOM.span( {id:\"test\"} )),\n container\n );\n expect(ac.getDOMNode().id).toBe('test');\n ac = React.renderComponent(ReactTransitionableChild(null ), container);\n expect(ac.getDOMNode().id).toBe('test');\n });\n\n it('should manage enter css classes correctly', function() {\n var runNextTick = mocks.getMockFunction();\n var container = document.createElement('div');\n var ac = React.renderComponent(\n ReactTransitionableChild(\n {runNextTick:runNextTick,\n name:\"myanim\",\n enter:true}, \n React.DOM.span( {id:\"test\"} )\n ),\n container\n );\n expect(ac.getDOMNode().id).toBe('test');\n expect(ac.getDOMNode().className.trim()).toBe('myanim-enter');\n expect(runNextTick.mock.calls.length).toBe(1);\n runNextTick.mock.calls[0][0]();\n expect(ac.getDOMNode().className.trim()).toBe(\n 'myanim-enter myanim-enter-active'\n );\n expect(runNextTick.mock.calls.length).toBe(1);\n });\n\n it('should manage leave css classes correctly', function() {\n var runNextTick = mocks.getMockFunction();\n var container = document.createElement('div');\n var ac = React.renderComponent(\n ReactTransitionableChild(\n {runNextTick:runNextTick,\n name:\"myanim\",\n enter:true,\n leave:true}, \n React.DOM.span( {id:\"test\"} )\n ),\n container\n );\n runNextTick.mock.calls[0][0]();\n expect(ac.getDOMNode().className.trim()).toBe(\n 'myanim-enter myanim-enter-active'\n );\n\n // TODO: we should just trigger the CSS animation end event to\n // clean these up\n ac.getDOMNode().className = '';\n React.renderComponent(\n ReactTransitionableChild(\n {runNextTick:runNextTick,\n name:\"myanim\",\n enter:true,\n leave:true}\n ),\n container\n );\n expect(ac.getDOMNode().className.trim()).toBe('myanim-leave');\n expect(runNextTick.mock.calls.length).toBe(2);\n runNextTick.mock.calls[1][0]();\n expect(ac.getDOMNode().className.trim()).toBe(\n 'myanim-leave myanim-leave-active'\n );\n expect(runNextTick.mock.calls.length).toBe(2);\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"addons/transitions/__tests__/ReactTransitionableChild-test\", module);\n", -"core/__tests__/ReactBind-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n/*global global:true*/\n\"use strict\";\n\nvar mocks = require(\"../../mocks\");\nvar React = require(\"../../React\");\nvar ReactDoNotBindDeprecated = require(\"../../ReactDoNotBindDeprecated\");\nvar ReactTestUtils = require(\"../../ReactTestUtils\");\nvar reactComponentExpect = require(\"../../reactComponentExpect\");\n\n// TODO: Test render and all stock methods.\ndescribe('autobinding', function() {\n\n it('Holds reference to instance', function() {\n\n var mouseDidEnter = mocks.getMockFunction();\n var mouseDidLeave = mocks.getMockFunction();\n var mouseDidClick = mocks.getMockFunction();\n\n var TestBindComponent = React.createClass({displayName: 'TestBindComponent',\n getInitialState: function() {\n return {something: 'hi'};\n },\n onMouseEnter: ReactDoNotBindDeprecated.doNotBind(mouseDidEnter),\n onMouseLeave: ReactDoNotBindDeprecated.doNotBind(mouseDidLeave),\n onClick: mouseDidClick,\n\n // auto binding only occurs on top level functions in class defs.\n badIdeas: {\n badBind: function() {\n this.state.something;\n }\n },\n\n render: function() {\n return (\n React.DOM.div(\n {onMouseEnter:this.onMouseEnter.bind(this),\n onMouseLeave:this.onMouseLeave,\n onClick:this.onClick}\n )\n );\n }\n });\n\n var instance1 = TestBindComponent(null );\n ReactTestUtils.renderIntoDocument(instance1);\n var rendered1 = reactComponentExpect(instance1)\n .expectRenderedChild()\n .instance();\n\n var instance2 = TestBindComponent(null );\n ReactTestUtils.renderIntoDocument(instance2);\n var rendered2 = reactComponentExpect(instance2)\n .expectRenderedChild()\n .instance();\n\n expect(function() {\n var badIdea = instance1.badIdeas.badBind;\n badIdea();\n }).toThrow();\n\n expect(instance1.onMouseEnter).toBe(instance2.onMouseEnter);\n expect(instance1.onMouseLeave).toBe(instance2.onMouseLeave);\n expect(instance1.onClick).not.toBe(instance2.onClick);\n\n ReactTestUtils.Simulate.click(rendered1);\n expect(mouseDidClick.mock.instances.length).toBe(1);\n expect(mouseDidClick.mock.instances[0]).toBe(instance1);\n\n ReactTestUtils.Simulate.click(rendered2);\n expect(mouseDidClick.mock.instances.length).toBe(2);\n expect(mouseDidClick.mock.instances[1]).toBe(instance2);\n\n ReactTestUtils.Simulate.mouseOver(rendered1);\n expect(mouseDidEnter.mock.instances.length).toBe(1);\n expect(mouseDidEnter.mock.instances[0]).toBe(instance1);\n\n ReactTestUtils.Simulate.mouseOver(rendered2);\n expect(mouseDidEnter.mock.instances.length).toBe(2);\n expect(mouseDidEnter.mock.instances[1]).toBe(instance2);\n\n ReactTestUtils.Simulate.mouseOut(rendered1);\n expect(mouseDidLeave.mock.instances.length).toBe(1);\n expect(mouseDidLeave.mock.instances[0]).toBe(global);\n\n ReactTestUtils.Simulate.mouseOut(rendered2);\n expect(mouseDidLeave.mock.instances.length).toBe(2);\n expect(mouseDidLeave.mock.instances[1]).toBe(global);\n });\n\n it('works with mixins', function() {\n var mouseDidClick = mocks.getMockFunction();\n\n var TestMixin = {\n onClick: mouseDidClick\n };\n\n var TestBindComponent = React.createClass({displayName: 'TestBindComponent',\n mixins: [TestMixin],\n\n render: function() {\n return React.DOM.div( {onClick:this.onClick} );\n }\n });\n\n var instance1 = TestBindComponent(null );\n ReactTestUtils.renderIntoDocument(instance1);\n var rendered1 = reactComponentExpect(instance1)\n .expectRenderedChild()\n .instance();\n\n ReactTestUtils.Simulate.click(rendered1);\n expect(mouseDidClick.mock.instances.length).toBe(1);\n expect(mouseDidClick.mock.instances[0]).toBe(instance1);\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactBind-test\", module);\n", -"core/__tests__/ReactComponent-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React;\nvar ReactTestUtils;\n\nvar reactComponentExpect;\n\ndescribe('ReactComponent', function() {\n beforeEach(function() {\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n reactComponentExpect = require(\"../../reactComponentExpect\");\n });\n\n it('should throw on invalid render targets', function() {\n var container = document.createElement('div');\n // jQuery objects are basically arrays; people often pass them in by mistake\n expect(function() {\n React.renderComponent(React.DOM.div(null), [container]);\n }).toThrow(\n 'Invariant Violation: prepareEnvironmentForDOM(...): Target container ' +\n 'is not a DOM element.'\n );\n\n expect(function() {\n React.renderComponent(React.DOM.div(null), null);\n }).toThrow(\n 'Invariant Violation: prepareEnvironmentForDOM(...): Target container ' +\n 'is not a DOM element.'\n );\n });\n\n it('should throw when supplying a ref outside of render method', function() {\n var instance = React.DOM.div( {ref:\"badDiv\"} );\n expect(function() {\n ReactTestUtils.renderIntoDocument(instance);\n }).toThrow();\n });\n\n it('should throw when attempting to hijack a ref', function() {\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n var child = this.props.child;\n this.attachRef('test', child);\n return child;\n }\n });\n\n var instance = Component( {child:React.DOM.span(null )} );\n\n expect(function() {\n ReactTestUtils.renderIntoDocument(instance);\n }).toThrow(\n 'Invariant Violation: attachRef(test, ...): Only a component\\'s owner ' +\n 'can store a ref to it.'\n );\n });\n\n it('should support refs on owned components', function() {\n var inner, outer;\n\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n inner = React.DOM.div( {ref:\"inner\"} );\n outer = React.DOM.div( {ref:\"outer\"}, inner);\n return outer;\n },\n componentDidMount: function() {\n expect(this.refs.inner).toEqual(inner);\n expect(this.refs.outer).toEqual(outer);\n }\n });\n\n var instance = Component( {child:React.DOM.span(null )} );\n ReactTestUtils.renderIntoDocument(instance);\n });\n\n it('should not have refs on unmounted components', function() {\n var Parent = React.createClass({displayName: 'Parent',\n render: function() {\n return Child(null, React.DOM.div( {ref:\"test\"} ));\n },\n componentDidMount: function() {\n expect(this.refs && this.refs.test).toEqual(undefined);\n }\n });\n var Child = React.createClass({displayName: 'Child',\n render: function() {\n return React.DOM.div(null );\n }\n });\n\n var instance = Parent( {child:React.DOM.span(null )} );\n ReactTestUtils.renderIntoDocument(instance);\n });\n\n it('should correctly determine if a component is mounted', function() {\n var Component = React.createClass({displayName: 'Component',\n componentWillMount: function() {\n expect(this.isMounted()).toBeFalsy();\n },\n componentDidMount: function() {\n expect(this.isMounted()).toBeTruthy();\n },\n render: function() {\n return React.DOM.div(null);\n }\n });\n\n var instance = Component(null );\n\n expect(instance.isMounted()).toBeFalsy();\n ReactTestUtils.renderIntoDocument(instance);\n expect(instance.isMounted()).toBeTruthy();\n });\n\n it('should know its simple mount depth', function() {\n var Owner = React.createClass({displayName: 'Owner',\n render: function() {\n return Child( {ref:\"child\"} );\n }\n });\n\n var Child = React.createClass({displayName: 'Child',\n render: function() {\n return React.DOM.div(null );\n }\n });\n\n var instance = Owner(null );\n ReactTestUtils.renderIntoDocument(instance);\n expect(instance._mountDepth).toBe(0);\n expect(instance.refs.child._mountDepth).toBe(1);\n });\n\n it('should know its (complicated) mount depth', function() {\n var Box = React.createClass({displayName: 'Box',\n render: function() {\n return React.DOM.div( {ref:\"boxDiv\"}, this.props.children);\n }\n });\n\n var Child = React.createClass({displayName: 'Child',\n render: function() {\n return React.DOM.span( {ref:\"span\"}, \"child\");\n }\n });\n\n var Switcher = React.createClass({displayName: 'Switcher',\n getInitialState: function() {\n return {tabKey: 'hello'};\n },\n\n render: function() {\n var child = this.props.children;\n\n return (\n Box( {ref:\"box\"}, \n React.DOM.div(\n {ref:\"switcherDiv\",\n style:{\n display: this.state.tabKey === child.key ? '' : 'none'\n }}, \n child\n )\n )\n );\n }\n });\n\n var App = React.createClass({displayName: 'App',\n render: function() {\n return (\n Switcher( {ref:\"switcher\"}, \n Child( {key:\"hello\", ref:\"child\"} )\n )\n );\n }\n });\n\n var root = App(null );\n ReactTestUtils.renderIntoDocument(root);\n\n expect(root._mountDepth).toBe(0);\n expect(root.refs.switcher._mountDepth).toBe(1);\n expect(root.refs.switcher.refs.box._mountDepth).toBe(2);\n expect(root.refs.switcher.refs.switcherDiv._mountDepth).toBe(4);\n expect(root.refs.child._mountDepth).toBe(5);\n expect(root.refs.switcher.refs.box.refs.boxDiv._mountDepth).toBe(3);\n expect(root.refs.child.refs.span._mountDepth).toBe(6);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactComponent-test\", module);\n", -"core/__tests__/ReactComponentLifeCycle-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React;\nvar ReactTestUtils;\nvar ReactComponent;\nvar ReactCompositeComponent;\nvar ComponentLifeCycle;\nvar CompositeComponentLifeCycle;\n\nvar clone = function(o) {\n return JSON.parse(JSON.stringify(o));\n};\n\n\nvar GET_INIT_STATE_RETURN_VAL = {\n hasWillMountCompleted: false,\n hasRenderCompleted: false,\n hasDidMountCompleted: false,\n hasWillUnmountCompleted: false\n};\n\nvar INIT_RENDER_STATE = {\n hasWillMountCompleted: true,\n hasRenderCompleted: false,\n hasDidMountCompleted: false,\n hasWillUnmountCompleted: false\n};\n\nvar DID_MOUNT_STATE = {\n hasWillMountCompleted: true,\n hasRenderCompleted: true,\n hasDidMountCompleted: false,\n hasWillUnmountCompleted: false\n};\n\nvar NEXT_RENDER_STATE = {\n hasWillMountCompleted: true,\n hasRenderCompleted: true,\n hasDidMountCompleted: true,\n hasWillUnmountCompleted: false\n};\n\nvar WILL_UNMOUNT_STATE = {\n hasWillMountCompleted: true,\n hasDidMountCompleted: true,\n hasRenderCompleted: true,\n hasWillUnmountCompleted: false\n};\n\nvar POST_WILL_UNMOUNT_STATE = {\n hasWillMountCompleted: true,\n hasDidMountCompleted: true,\n hasRenderCompleted: true,\n hasWillUnmountCompleted: true\n};\n\n/**\n * TODO: We should make any setState calls fail in\n * `getInitialState` and `componentWillMount`. They will usually fail\n * anyways because `this._renderedComponent` is empty, however, if a component\n * is *reused*, then that won't be the case and things will appear to work in\n * some cases. Better to just block all updates in initialization.\n */\ndescribe('ReactComponentLifeCycle', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n ReactComponent = require(\"../../ReactComponent\");\n ReactCompositeComponent = require(\"../../ReactCompositeComponent\");\n ComponentLifeCycle = ReactComponent.LifeCycle;\n CompositeComponentLifeCycle = ReactCompositeComponent.LifeCycle;\n });\n\n it('should scrub state when reinitialized using getInitialState', function() {\n var StatefulComponent = React.createClass({displayName: 'StatefulComponent',\n getInitialState: function() {\n return { };\n },\n addAnotherField: function() {\n this.setState({\n aField: 'asdf'\n });\n },\n render: function() {\n return (\n React.DOM.div(null )\n );\n }\n });\n var instance = StatefulComponent(null );\n ReactTestUtils.renderIntoDocument(instance);\n instance.addAnotherField();\n expect(instance.state.aField).toBe('asdf');\n instance.unmountComponent();\n ReactTestUtils.renderIntoDocument(instance);\n expect(typeof instance.state.aField).toBe('undefined');\n });\n\n /**\n * If a state update triggers rerendering that in turn fires an onDOMReady,\n * that second onDOMReady should not fail.\n */\n it('it should fire onDOMReady when already in onDOMReady', function() {\n\n var _testJournal = [];\n\n var Child = React.createClass({displayName: 'Child',\n componentDidMount: function() {\n _testJournal.push('Child:onDOMReady');\n },\n render: function() {\n return React.DOM.div(null );\n }\n });\n\n var SwitcherParent = React.createClass({displayName: 'SwitcherParent',\n getInitialState: function() {\n _testJournal.push('SwitcherParent:getInitialState');\n return {showHasOnDOMReadyComponent: false};\n },\n componentDidMount: function() {\n _testJournal.push('SwitcherParent:onDOMReady');\n this.switchIt();\n },\n switchIt: function() {\n this.setState({showHasOnDOMReadyComponent: true});\n },\n render: function() {\n return (\n React.DOM.div(null, \n this.state.showHasOnDOMReadyComponent ?\n Child(null ) :\n React.DOM.div(null )\n )\n );\n }\n });\n\n var instance = SwitcherParent(null );\n ReactTestUtils.renderIntoDocument(instance);\n expect(_testJournal).toEqual([\n 'SwitcherParent:getInitialState',\n 'SwitcherParent:onDOMReady',\n 'Child:onDOMReady'\n ]);\n });\n\n\n it('should scrub state when re-initialized', function() {\n var StatefulComponent = React.createClass({displayName: 'StatefulComponent',\n addAnotherField: function() {\n this.setState({\n aField: 'asdf'\n });\n },\n render: function() {\n return (\n React.DOM.div(null )\n );\n }\n });\n var instance = StatefulComponent(null );\n ReactTestUtils.renderIntoDocument(instance);\n instance.addAnotherField();\n expect(instance.state.aField).toBe('asdf');\n instance.unmountComponent();\n ReactTestUtils.renderIntoDocument(instance);\n expect(instance.state).toBe(null);\n });\n\n // You could assign state here, but not access members of it, unless you\n // had provided a getInitialState method.\n it('throws when accessing state in componentWillMount', function() {\n var StatefulComponent = React.createClass({displayName: 'StatefulComponent',\n componentWillMount: function() {\n this.state.yada;\n },\n render: function() {\n return (\n React.DOM.div(null )\n );\n }\n });\n var instance = StatefulComponent(null );\n expect(function() {\n ReactTestUtils.renderIntoDocument(instance);\n }).toThrow();\n });\n\n it('should allow update state inside of componentWillMount', function() {\n var StatefulComponent = React.createClass({displayName: 'StatefulComponent',\n componentWillMount: function() {\n this.setState({stateField: 'something'});\n },\n render: function() {\n return (\n React.DOM.div(null )\n );\n }\n });\n var instance = StatefulComponent(null );\n expect(function() {\n ReactTestUtils.renderIntoDocument(instance);\n }).not.toThrow();\n });\n\n it('should allow update state inside of getInitialState', function() {\n var StatefulComponent = React.createClass({displayName: 'StatefulComponent',\n getInitialState: function() {\n this.setState({stateField: 'something'});\n\n return {stateField: 'somethingelse'};\n },\n render: function() {\n return (\n React.DOM.div(null )\n );\n }\n });\n var instance = StatefulComponent(null );\n expect(function() {\n ReactTestUtils.renderIntoDocument(instance);\n }).not.toThrow();\n\n // The return value of getInitialState overrides anything from setState\n expect(instance.state.stateField).toEqual('somethingelse');\n });\n\n\n it('should carry through each of the phases of setup', function() {\n var LifeCycleComponent = React.createClass({displayName: 'LifeCycleComponent',\n getInitialState: function() {\n this._testJournal = {};\n var initState = {\n hasWillMountCompleted: false,\n hasDidMountCompleted: false,\n hasRenderCompleted: false,\n hasWillUnmountCompleted: false\n };\n this._testJournal.returnedFromGetInitialState = clone(initState);\n this._testJournal.lifeCycleAtStartOfGetInitialState =\n this._lifeCycleState;\n this._testJournal.compositeLifeCycleAtStartOfGetInitialState =\n this._compositeLifeCycleState;\n return initState;\n },\n\n componentWillMount: function() {\n this._testJournal.stateAtStartOfWillMount = clone(this.state);\n this._testJournal.lifeCycleAtStartOfWillMount =\n this._lifeCycleState;\n this._testJournal.compositeLifeCycleAtStartOfWillMount =\n this._compositeLifeCycleState;\n this.state.hasWillMountCompleted = true;\n },\n\n componentDidMount: function() {\n this._testJournal.stateAtStartOfDidMount = clone(this.state);\n this._testJournal.lifeCycleAtStartOfDidMount =\n this._lifeCycleState;\n this.setState({hasDidMountCompleted: true});\n },\n\n render: function() {\n var isInitialRender = !this.state.hasRenderCompleted;\n if (isInitialRender) {\n this._testJournal.stateInInitialRender = clone(this.state);\n this._testJournal.lifeCycleInInitialRender = this._lifeCycleState;\n this._testJournal.compositeLifeCycleInInitialRender =\n this._compositeLifeCycleState;\n } else {\n this._testJournal.stateInLaterRender = clone(this.state);\n this._testJournal.lifeCycleInLaterRender = this._lifeCycleState;\n }\n // you would *NEVER* do anything like this in real code!\n this.state.hasRenderCompleted = true;\n return (\n React.DOM.div( {ref:\"theDiv\"}, \n \" I am the inner DIV \"\n )\n );\n },\n\n componentWillUnmount: function() {\n this._testJournal.stateAtStartOfWillUnmount = clone(this.state);\n this._testJournal.lifeCycleAtStartOfWillUnmount =\n this._lifeCycleState;\n this.state.hasWillUnmountCompleted = true;\n }\n });\n\n // A component that is merely \"constructed\" (as in \"constructor\") but not\n // yet initialized, or rendered.\n //\n var instance = LifeCycleComponent(null );\n expect(instance._lifeCycleState).toBe(ComponentLifeCycle.UNMOUNTED);\n ReactTestUtils.renderIntoDocument(instance);\n\n // getInitialState\n expect(instance._testJournal.returnedFromGetInitialState).toEqual(\n GET_INIT_STATE_RETURN_VAL\n );\n expect(instance._testJournal.lifeCycleAtStartOfGetInitialState)\n .toBe(ComponentLifeCycle.MOUNTED);\n expect(instance._testJournal.compositeLifeCycleAtStartOfGetInitialState)\n .toBe(CompositeComponentLifeCycle.MOUNTING);\n\n // componentWillMount\n expect(instance._testJournal.stateAtStartOfWillMount).toEqual(\n instance._testJournal.returnedFromGetInitialState\n );\n expect(instance._testJournal.lifeCycleAtStartOfWillMount)\n .toBe(ComponentLifeCycle.MOUNTED);\n expect(instance._testJournal.compositeLifeCycleAtStartOfWillMount)\n .toBe(CompositeComponentLifeCycle.MOUNTING);\n\n // componentDidMount\n expect(instance._testJournal.stateAtStartOfDidMount)\n .toEqual(DID_MOUNT_STATE);\n expect(instance._testJournal.lifeCycleAtStartOfDidMount).toBe(\n ComponentLifeCycle.MOUNTED\n );\n\n // render\n expect(instance._testJournal.stateInInitialRender)\n .toEqual(INIT_RENDER_STATE);\n expect(instance._testJournal.lifeCycleInInitialRender).toBe(\n ComponentLifeCycle.MOUNTED\n );\n expect(instance._testJournal.compositeLifeCycleInInitialRender).toBe(\n CompositeComponentLifeCycle.MOUNTING\n );\n\n expect(instance._lifeCycleState).toBe(ComponentLifeCycle.MOUNTED);\n\n // Now *update the component*\n instance.forceUpdate();\n\n // render 2nd time\n expect(instance._testJournal.stateInLaterRender)\n .toEqual(NEXT_RENDER_STATE);\n expect(instance._testJournal.lifeCycleInLaterRender).toBe(\n ComponentLifeCycle.MOUNTED\n );\n\n expect(instance._lifeCycleState).toBe(ComponentLifeCycle.MOUNTED);\n\n // Now *unmountComponent*\n instance.unmountComponent();\n\n expect(instance._testJournal.stateAtStartOfWillUnmount)\n .toEqual(WILL_UNMOUNT_STATE);\n // componentWillUnmount called right before unmount.\n expect(instance._testJournal.lifeCycleAtStartOfWillUnmount).toBe(\n ComponentLifeCycle.MOUNTED\n );\n\n // But the current lifecycle of the component is unmounted.\n expect(instance._lifeCycleState).toBe(ComponentLifeCycle.UNMOUNTED);\n expect(instance.state).toEqual(POST_WILL_UNMOUNT_STATE);\n });\n\n it('should throw when calling setProps() on an owned component', function() {\n /**\n * calls setProps in an componentDidMount.\n */\n var PropsUpdaterInOnDOMReady = React.createClass({displayName: 'PropsUpdaterInOnDOMReady',\n componentDidMount: function() {\n this.refs.theSimpleComponent.setProps({\n value: this.props.valueToUseInOnDOMReady\n });\n },\n render: function() {\n return (\n React.DOM.input(\n {value:this.props.valueToUseInitially,\n ref:\"theSimpleComponent\"}\n )\n );\n }\n });\n var instance =\n PropsUpdaterInOnDOMReady(\n {valueToUseInitially:\"hello\",\n valueToUseInOnDOMReady:\"goodbye\"}\n );\n expect(ReactTestUtils.renderIntoDocument.bind(ReactTestUtils, instance))\n .toThrow();\n });\n\n it('should throw when calling setProps() on an unmounted component',\n function() {\n var PropsToUpdate = React.createClass({displayName: 'PropsToUpdate',\n render: function() {\n return (\n React.DOM.input(\n {value:this.props.value,\n ref:\"theSimpleComponent\"}\n )\n );\n }\n });\n var instance = PropsToUpdate( {value:\"hello\"} );\n expect(function() {\n instance.setProps({value: \"goodbye\"});\n }).toThrow(\n 'Invariant Violation: replaceProps(...): Can only update a ' +\n 'mounted component.'\n );\n });\n\n it('should allow state updates in componentDidMount', function() {\n /**\n * calls setState in an componentDidMount.\n */\n var SetStateInComponentDidMount = React.createClass({displayName: 'SetStateInComponentDidMount',\n getInitialState: function() {\n return {\n stateField: this.props.valueToUseInitially\n };\n },\n componentDidMount: function() {\n this.setState({stateField: this.props.valueToUseInOnDOMReady});\n },\n render: function() {\n return (React.DOM.div(null));\n }\n });\n var instance =\n SetStateInComponentDidMount(\n {valueToUseInitially:\"hello\",\n valueToUseInOnDOMReady:\"goodbye\"}\n );\n ReactTestUtils.renderIntoDocument(instance);\n expect(instance.state.stateField).toBe('goodbye');\n });\n\n it('should call nested lifecycle methods in the right order', function() {\n var log;\n var logger = function(msg) {\n return function() {\n // return true for shouldComponentUpdate\n log.push(msg);\n return true;\n };\n };\n var Outer = React.createClass({displayName: 'Outer',\n render: function() {\n return React.DOM.div(null, Inner( {x:this.props.x} ));\n },\n componentWillMount: logger('outer componentWillMount'),\n componentDidMount: logger('outer componentDidMount'),\n componentWillReceiveProps: logger('outer componentWillReceiveProps'),\n shouldComponentUpdate: logger('outer shouldComponentUpdate'),\n componentWillUpdate: logger('outer componentWillUpdate'),\n componentDidUpdate: logger('outer componentDidUpdate'),\n componentWillUnmount: logger('outer componentWillUnmount')\n });\n var Inner = React.createClass({displayName: 'Inner',\n render: function() {\n return React.DOM.span(null, this.props.x);\n },\n componentWillMount: logger('inner componentWillMount'),\n componentDidMount: logger('inner componentDidMount'),\n componentWillReceiveProps: logger('inner componentWillReceiveProps'),\n shouldComponentUpdate: logger('inner shouldComponentUpdate'),\n componentWillUpdate: logger('inner componentWillUpdate'),\n componentDidUpdate: logger('inner componentDidUpdate'),\n componentWillUnmount: logger('inner componentWillUnmount')\n });\n var instance;\n\n log = [];\n instance = ReactTestUtils.renderIntoDocument(Outer( {x:17} ));\n expect(log).toEqual([\n 'outer componentWillMount',\n 'inner componentWillMount',\n 'inner componentDidMount',\n 'outer componentDidMount'\n ]);\n\n log = [];\n instance.setProps({x: 42});\n expect(log).toEqual([\n 'outer componentWillReceiveProps',\n 'outer shouldComponentUpdate',\n 'outer componentWillUpdate',\n 'inner componentWillReceiveProps',\n 'inner shouldComponentUpdate',\n 'inner componentWillUpdate',\n 'inner componentDidUpdate',\n 'outer componentDidUpdate'\n ]);\n\n log = [];\n instance.unmountComponent();\n expect(log).toEqual([\n 'outer componentWillUnmount',\n 'inner componentWillUnmount'\n ]);\n });\n});\n\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactComponentLifeCycle-test\", module);\n", -"core/__tests__/ReactCompositeComponent-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar MorphingComponent;\nvar ChildUpdates;\nvar React;\nvar ReactCurrentOwner;\nvar ReactPropTypes;\nvar ReactTestUtils;\nvar ReactMount;\nvar ReactDoNotBindDeprecated;\n\nvar cx;\nvar reactComponentExpect;\nvar mocks;\n\ndescribe('ReactCompositeComponent', function() {\n\n beforeEach(function() {\n cx = require(\"../../cx\");\n mocks = require(\"../../mocks\");\n\n reactComponentExpect = require(\"../../reactComponentExpect\");\n React = require(\"../../React\");\n ReactCurrentOwner = require(\"../../ReactCurrentOwner\");\n ReactDoNotBindDeprecated = require(\"../../ReactDoNotBindDeprecated\");\n ReactPropTypes = require(\"../../ReactPropTypes\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n ReactMount = require(\"../../ReactMount\");\n\n MorphingComponent = React.createClass({\n getInitialState: function() {\n return {activated: false};\n },\n\n _toggleActivatedState: function() {\n this.setState({activated: !this.state.activated});\n },\n\n render: function() {\n var toggleActivatedState = this._toggleActivatedState;\n return !this.state.activated ?\n React.DOM.a( {ref:\"x\", onClick:toggleActivatedState} ) :\n React.DOM.b( {ref:\"x\", onClick:toggleActivatedState} );\n }\n });\n\n /**\n * We'll use this to ensure that an old version is not cached when it is\n * reallocated again.\n */\n ChildUpdates = React.createClass({\n getAnchorID: function() {\n return this.refs.anch._rootNodeID;\n },\n render: function() {\n var className = cx({'anchorClass': this.props.anchorClassOn});\n return this.props.renderAnchor ?\n React.DOM.a( {ref:\"anch\", className:className}) :\n React.DOM.b(null);\n }\n });\n });\n\n it('should support rendering to different child types over time', function() {\n var instance = MorphingComponent(null );\n ReactTestUtils.renderIntoDocument(instance);\n\n reactComponentExpect(instance)\n .expectRenderedChild()\n .toBeDOMComponentWithTag('a');\n\n instance._toggleActivatedState();\n reactComponentExpect(instance)\n .expectRenderedChild()\n .toBeDOMComponentWithTag('b');\n\n instance._toggleActivatedState();\n reactComponentExpect(instance)\n .expectRenderedChild()\n .toBeDOMComponentWithTag('a');\n });\n\n it('should react to state changes from callbacks', function() {\n var instance = MorphingComponent(null );\n ReactTestUtils.renderIntoDocument(instance);\n\n var renderedChild = reactComponentExpect(instance)\n .expectRenderedChild()\n .instance();\n\n ReactTestUtils.Simulate.click(renderedChild);\n reactComponentExpect(instance)\n .expectRenderedChild()\n .toBeDOMComponentWithTag('b');\n });\n\n it('should rewire refs when rendering to different child types', function() {\n var instance = MorphingComponent(null );\n ReactTestUtils.renderIntoDocument(instance);\n\n reactComponentExpect(instance.refs.x).toBeDOMComponentWithTag('a');\n instance._toggleActivatedState();\n reactComponentExpect(instance.refs.x).toBeDOMComponentWithTag('b');\n instance._toggleActivatedState();\n reactComponentExpect(instance.refs.x).toBeDOMComponentWithTag('a');\n });\n\n it('should not cache old DOM nodes when switching constructors', function() {\n var instance = ChildUpdates( {renderAnchor:true, anchorClassOn:false});\n ReactTestUtils.renderIntoDocument(instance);\n instance.setProps({anchorClassOn: true}); // Warm any cache\n instance.setProps({renderAnchor: false}); // Clear out the anchor\n // rerender\n instance.setProps({renderAnchor: true, anchorClassOn: false});\n var anchorID = instance.getAnchorID();\n var actualDOMAnchorNode = ReactMount.getNode(anchorID);\n expect(actualDOMAnchorNode.className).toBe('');\n });\n\n it('should auto bind methods and values correctly', function() {\n spyOn(console, 'warn');\n\n var ComponentClass = React.createClass({displayName: 'ComponentClass',\n getInitialState: function() {\n return {valueToReturn: 'hi'};\n },\n methodToBeExplicitlyBound: function() {\n return this;\n },\n methodAutoBound: function() {\n return this;\n },\n methodExplicitlyNotBound: ReactDoNotBindDeprecated.doNotBind(function() {\n return this;\n }),\n render: function() {\n return React.DOM.div(null );\n }\n });\n var instance = ComponentClass(null );\n\n // These are controversial assertions for now, they just exist\n // because existing code depends on these assumptions.\n expect(function() {\n instance.methodToBeExplicitlyBound.bind(instance)();\n }).not.toThrow();\n expect(function() {\n instance.methodAutoBound();\n }).not.toThrow();\n expect(function() {\n instance.methodExplicitlyNotBound();\n }).not.toThrow();\n\n // Next, prove that once mounted, the scope is bound correctly to the actual\n // component.\n ReactTestUtils.renderIntoDocument(instance);\n expect(console.warn.argsForCall.length).toBe(0);\n var explicitlyBound = instance.methodToBeExplicitlyBound.bind(instance);\n expect(console.warn.argsForCall.length).toBe(1);\n var autoBound = instance.methodAutoBound;\n var explicitlyNotBound = instance.methodExplicitlyNotBound;\n\n var context = {};\n expect(explicitlyBound.call(context)).toBe(instance);\n expect(autoBound.call(context)).toBe(instance);\n expect(explicitlyNotBound.call(context)).toBe(context);\n\n expect(explicitlyBound.call(instance)).toBe(instance);\n expect(autoBound.call(instance)).toBe(instance);\n expect(explicitlyNotBound.call(instance)).toBe(instance);\n\n });\n\n it('should use default values for undefined props', function() {\n var Component = React.createClass({displayName: 'Component',\n getDefaultProps: function() {\n return {key: 'testKey'};\n },\n render: function() {\n return React.DOM.span(null );\n }\n });\n\n var instance1 = Component(null );\n ReactTestUtils.renderIntoDocument(instance1);\n reactComponentExpect(instance1).scalarPropsEqual({key: 'testKey'});\n\n var instance2 = Component( {key:undefined} );\n ReactTestUtils.renderIntoDocument(instance2);\n reactComponentExpect(instance2).scalarPropsEqual({key: 'testKey'});\n\n var instance3 = Component( {key:null} );\n ReactTestUtils.renderIntoDocument(instance3);\n reactComponentExpect(instance3).scalarPropsEqual({key: null});\n });\n\n it('should normalize props with default values', function() {\n var Component = React.createClass({displayName: 'Component',\n propTypes: {key: ReactPropTypes.string.isRequired},\n getDefaultProps: function() {\n return {key: 'testKey'};\n },\n getInitialState: function() {\n return {key: this.props.key + 'State'};\n },\n render: function() {\n return React.DOM.span(null, this.props.key);\n }\n });\n\n var instance = Component(null );\n ReactTestUtils.renderIntoDocument(instance);\n reactComponentExpect(instance).scalarPropsEqual({key: 'testKey'});\n reactComponentExpect(instance).scalarStateEqual({key: 'testKeyState'});\n\n expect(function() {\n ReactTestUtils.renderIntoDocument(Component( {key:null} ));\n }).toThrow(\n 'Invariant Violation: Required prop `key` was not specified in ' +\n '`Component`.'\n );\n });\n\n it('should check default prop values', function() {\n var Component = React.createClass({displayName: 'Component',\n propTypes: {key: ReactPropTypes.string.isRequired},\n getDefaultProps: function() {\n return {key: null};\n },\n render: function() {\n return React.DOM.span(null, this.props.key);\n }\n });\n\n var instance = Component(null );\n expect(function() {\n ReactTestUtils.renderIntoDocument(instance);\n }).toThrow(\n 'Invariant Violation: Required prop `key` was not specified in ' +\n '`Component`.'\n );\n });\n\n it('should check declared prop types', function() {\n var Component = React.createClass({displayName: 'Component',\n propTypes: {\n key: ReactPropTypes.string.isRequired\n },\n render: function() {\n return React.DOM.span(null, this.props.key);\n }\n });\n\n expect(function() {\n ReactTestUtils.renderIntoDocument(Component(null ));\n }).toThrow(\n 'Invariant Violation: Required prop `key` was not specified in ' +\n '`Component`.'\n );\n\n expect(function() {\n ReactTestUtils.renderIntoDocument(Component( {key:42} ));\n }).toThrow(\n 'Invariant Violation: Invalid prop `key` of type `number` supplied to ' +\n '`Component`, expected `string`.'\n );\n\n expect(function() {\n ReactTestUtils.renderIntoDocument(Component( {key:\"string\"} ));\n }).not.toThrow();\n });\n\n it('should not allow `forceUpdate` on unmounted components', function() {\n var container = document.createElement('div');\n document.documentElement.appendChild(container);\n\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n return React.DOM.div(null );\n }\n });\n\n var instance = Component(null );\n expect(function() {\n instance.forceUpdate();\n }).toThrow(\n 'Invariant Violation: forceUpdate(...): Can only force an update on ' +\n 'mounted or mounting components.'\n );\n\n React.renderComponent(instance, container);\n expect(function() {\n instance.forceUpdate();\n }).not.toThrow();\n\n React.unmountComponentAtNode(container);\n expect(function() {\n instance.forceUpdate();\n }).toThrow(\n 'Invariant Violation: forceUpdate(...): Can only force an update on ' +\n 'mounted or mounting components.'\n );\n });\n\n it('should cleanup even if render() fatals', function() {\n var BadComponent = React.createClass({displayName: 'BadComponent',\n render: function() {\n throw new Error();\n }\n });\n var instance = BadComponent(null );\n\n expect(ReactCurrentOwner.current).toBe(null);\n\n expect(function() {\n ReactTestUtils.renderIntoDocument(instance);\n }).toThrow();\n\n expect(ReactCurrentOwner.current).toBe(null);\n });\n\n it('should support mixins with getInitialState()', function() {\n var Mixin = {\n getInitialState: function() {\n return {mixin: true};\n }\n };\n var Component = React.createClass({displayName: 'Component',\n mixins: [Mixin],\n getInitialState: function() {\n return {component: true};\n },\n render: function() {\n return React.DOM.span(null );\n }\n });\n var instance = Component(null );\n ReactTestUtils.renderIntoDocument(instance);\n expect(instance.state.component).toBe(true);\n expect(instance.state.mixin).toBe(true);\n });\n\n it('should throw with conflicting getInitialState() methods', function() {\n var Mixin = {\n getInitialState: function() {\n return {x: true};\n }\n };\n var Component = React.createClass({displayName: 'Component',\n mixins: [Mixin],\n getInitialState: function() {\n return {x: true};\n },\n render: function() {\n return React.DOM.span(null );\n }\n });\n var instance = Component(null );\n expect(function() {\n ReactTestUtils.renderIntoDocument(instance);\n }).toThrow(\n 'Invariant Violation: mergeObjectsWithNoDuplicateKeys(): ' +\n 'Tried to merge two objects with the same key: x'\n );\n });\n\n it('should throw with bad getInitialState() return values', function() {\n var Mixin = {\n getInitialState: function() {\n return null;\n }\n };\n var Component = React.createClass({displayName: 'Component',\n mixins: [Mixin],\n getInitialState: function() {\n return {x: true};\n },\n render: function() {\n return React.DOM.span(null );\n }\n });\n var instance = Component(null );\n expect(function() {\n ReactTestUtils.renderIntoDocument(instance);\n }).toThrow(\n 'Invariant Violation: mergeObjectsWithNoDuplicateKeys(): ' +\n 'Cannot merge non-objects'\n );\n });\n\n it('should detect valid CompositeComponent classes', function() {\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n return React.DOM.div(null);\n }\n });\n\n expect(React.isValidClass(Component)).toBe(true);\n });\n\n it('should detect invalid CompositeComponent classes', function() {\n var FnComponent = function() {\n return false;\n };\n\n var NullComponent = null;\n\n var TrickFnComponent = function() {\n return true;\n };\n TrickFnComponent.componentConstructor = true;\n\n expect(React.isValidClass(FnComponent)).toBe(false);\n expect(React.isValidClass(NullComponent)).toBe(false);\n expect(React.isValidClass(TrickFnComponent)).toBe(false);\n });\n\n it('should warn when mispelling shouldComponentUpdate', function() {\n var warn = console.warn;\n console.warn = mocks.getMockFunction();\n\n try {\n React.createClass({\n componentShouldUpdate: function() {\n return false;\n },\n render: function() {\n return React.DOM.div(null );\n }\n });\n expect(console.warn.mock.calls.length).toBe(1);\n expect(console.warn.mock.calls[0][0]).toBe(\n 'A component has a method called componentShouldUpdate(). Did you ' +\n 'mean shouldComponentUpdate()? The name is phrased as a question ' +\n 'because the function is expected to return a value.'\n );\n\n var NamedComponent = React.createClass({displayName: 'NamedComponent',\n componentShouldUpdate: function() {\n return false;\n },\n render: function() {\n return React.DOM.div(null );\n }\n });\n expect(console.warn.mock.calls.length).toBe(2);\n expect(console.warn.mock.calls[1][0]).toBe(\n 'NamedComponent has a method called componentShouldUpdate(). Did you ' +\n 'mean shouldComponentUpdate()? The name is phrased as a question ' +\n 'because the function is expected to return a value.'\n );\n\n NamedComponent(); // Shut up lint\n } catch (e) {\n throw e;\n } finally {\n console.warn = warn;\n }\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactCompositeComponent-test\", module);\n", -"core/__tests__/ReactCompositeComponentDOMMinimalism-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n// Requires\nvar React;\nvar ReactTestUtils;\nvar reactComponentExpect;\n\n// Test components\nvar LowerLevelComposite;\nvar MyCompositeComponent;\n\nvar expectSingleChildlessDiv;\n\n/**\n * Integration test, testing the combination of JSX with our unit of\n * abstraction, `ReactCompositeComponent` does not ever add superfluous DOM\n * nodes.\n */\ndescribe('ReactCompositeComponentDOMMinimalism', function() {\n\n beforeEach(function() {\n reactComponentExpect = require(\"../../reactComponentExpect\");\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n\n LowerLevelComposite = React.createClass({\n render: function() {\n return (\n React.DOM.div(null, \n this.props.children\n )\n );\n }\n });\n\n MyCompositeComponent = React.createClass({\n render: function() {\n return (\n LowerLevelComposite(null, \n this.props.children\n )\n );\n }\n });\n\n expectSingleChildlessDiv = function(instance) {\n reactComponentExpect(instance)\n .expectRenderedChild()\n .toBeCompositeComponentWithType(LowerLevelComposite)\n .expectRenderedChild()\n .toBeDOMComponentWithTag('div')\n .toBeDOMComponentWithNoChildren();\n };\n });\n\n it('should not render extra nodes for non-interpolated text', function() {\n var instance = (\n MyCompositeComponent(null, \n \" A string child \"\n )\n );\n ReactTestUtils.renderIntoDocument(instance);\n expectSingleChildlessDiv(instance);\n });\n\n it('should not render extra nodes for non-interpolated text', function() {\n var instance = (\n MyCompositeComponent(null, \n 'Interpolated String Child'\n )\n );\n ReactTestUtils.renderIntoDocument(instance);\n expectSingleChildlessDiv(instance);\n });\n\n it('should not render extra nodes for non-interpolated text', function() {\n var instance = (\n MyCompositeComponent(null, \n React.DOM.ul(null, \n \" This text causes no children in ul, just innerHTML \"\n )\n )\n );\n ReactTestUtils.renderIntoDocument(instance);\n reactComponentExpect(instance)\n .expectRenderedChild()\n .toBeCompositeComponentWithType(LowerLevelComposite)\n .expectRenderedChild()\n .toBeDOMComponentWithTag('div')\n .toBeDOMComponentWithChildCount(1)\n .expectRenderedChildAt(0)\n .toBeDOMComponentWithTag('ul')\n .toBeDOMComponentWithNoChildren();\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactCompositeComponentDOMMinimalism-test\", module);\n", -"core/__tests__/ReactCompositeComponentMixin-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar mocks = require(\"../../mocks\");\n\nvar React;\nvar ReactTestUtils;\nvar reactComponentExpect;\n\nvar TestComponent;\nvar TestComponentWithPropTypes;\nvar mixinPropValidator;\nvar componentPropValidator;\n\ndescribe('ReactCompositeComponent-mixin', function() {\n\n beforeEach(function() {\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n reactComponentExpect = require(\"../../reactComponentExpect\");\n mixinPropValidator = mocks.getMockFunction();\n componentPropValidator = mocks.getMockFunction();\n\n var MixinA = {\n componentDidMount: function() {\n this.props.listener('MixinA didMount');\n }\n };\n\n var MixinB = {\n mixins: [MixinA],\n componentDidMount: function() {\n this.props.listener('MixinB didMount');\n }\n };\n\n var MixinC = {\n componentDidMount: function() {\n this.props.listener('MixinC didMount');\n }\n };\n\n var MixinD = {\n propTypes: {\n value: mixinPropValidator\n }\n };\n\n TestComponent = React.createClass({\n mixins: [MixinB, MixinC, MixinD],\n\n componentDidMount: function() {\n this.props.listener('Component didMount');\n },\n\n render: function() {\n return React.DOM.div(null );\n }\n });\n\n TestComponentWithPropTypes = React.createClass({\n mixins: [MixinD],\n propTypes: {\n value: componentPropValidator\n },\n render: function() {\n return React.DOM.div(null );\n }\n });\n });\n\n it('should support chaining delegate functions', function() {\n var listener = mocks.getMockFunction();\n var instance = TestComponent( {listener:listener} );\n ReactTestUtils.renderIntoDocument(instance);\n\n expect(listener.mock.calls).toEqual([\n ['MixinA didMount'],\n ['MixinB didMount'],\n ['MixinC didMount'],\n ['Component didMount']\n ]);\n });\n\n it('should validate prop types via mixins', function() {\n expect(TestComponent.componentConstructor.propTypes).toBeDefined();\n expect(TestComponent.componentConstructor.propTypes.value)\n .toBe(mixinPropValidator);\n });\n\n it('should override mixin prop types with class prop types', function() {\n // Sanity check...\n expect(componentPropValidator).toNotBe(mixinPropValidator);\n // Actually check...\n expect(TestComponentWithPropTypes.componentConstructor.propTypes)\n .toBeDefined();\n expect(TestComponentWithPropTypes.componentConstructor.propTypes.value)\n .toNotBe(mixinPropValidator);\n expect(TestComponentWithPropTypes.componentConstructor.propTypes.value)\n .toBe(componentPropValidator);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactCompositeComponentMixin-test\", module);\n", -"core/__tests__/ReactCompositeComponentSpec-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar mocks = require(\"../../mocks\");\n\nvar React;\nvar ReactTestUtils;\nvar reactComponentExpect;\n\ndescribe('ReactCompositeComponent-spec', function() {\n\n beforeEach(function() {\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n reactComponentExpect = require(\"../../reactComponentExpect\");\n });\n\n it('should throw when `render` is not specified', function() {\n expect(function() {\n React.createClass({});\n }).toThrow(\n 'Invariant Violation: createClass(...): Class specification must ' +\n 'implement a `render` method.'\n );\n });\n\n it('should copy `displayName` onto the Constructor', function() {\n var TestComponent = React.createClass({displayName: 'TestComponent',\n render: function() {\n return React.DOM.div(null );\n }\n });\n\n expect(TestComponent.componentConstructor.displayName)\n .toBe('TestComponent');\n });\n\n it('should copy prop types onto the Constructor', function() {\n var propValidator = mocks.getMockFunction();\n var TestComponent = React.createClass({displayName: 'TestComponent',\n propTypes: {\n value: propValidator\n },\n render: function() {\n return React.DOM.div(null );\n }\n });\n\n expect(TestComponent.componentConstructor.propTypes).toBeDefined();\n expect(TestComponent.componentConstructor.propTypes.value)\n .toBe(propValidator);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactCompositeComponentSpec-test\", module);\n", -"core/__tests__/ReactCompositeComponentState-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar mocks = require(\"../../mocks\");\n\nvar React;\nvar ReactTestUtils;\nvar reactComponentExpect;\n\nvar TestComponent;\n\ndescribe('ReactCompositeComponent-state', function() {\n\n beforeEach(function() {\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n reactComponentExpect = require(\"../../reactComponentExpect\");\n\n TestComponent = React.createClass({\n peekAtState: function(from, state) {\n if (state) {\n this.props.stateListener(from, state && state.color);\n } else {\n this.props.stateListener(\n from,\n this.state && this.state.color,\n this._pendingState && this._pendingState.color\n );\n }\n },\n\n setFavoriteColor: function(nextColor) {\n this.setState({color: nextColor});\n },\n\n getInitialState: function() {\n this.peekAtState('getInitialState');\n return {color: 'red'};\n },\n\n render: function() {\n this.peekAtState('render');\n return React.DOM.div(null, this.state.color);\n },\n\n componentWillMount: function() {\n this.peekAtState('componentWillMount-start');\n this.setState({color: 'sunrise'});\n this.peekAtState('componentWillMount-after-sunrise');\n this.setState({color: 'orange'});\n this.peekAtState('componentWillMount-end');\n },\n\n componentDidMount: function() {\n this.peekAtState('componentDidMount-start');\n this.setState({color: 'yellow'});\n this.peekAtState('componentDidMount-end');\n },\n\n componentWillReceiveProps: function(newProps) {\n this.peekAtState('componentWillReceiveProps-start');\n if (newProps.nextColor) {\n this.setState({color: newProps.nextColor});\n }\n this.peekAtState('componentWillReceiveProps-end');\n },\n\n shouldComponentUpdate: function(nextProps, nextState) {\n this.peekAtState('shouldComponentUpdate-currentState');\n this.peekAtState('shouldComponentUpdate-nextState', nextState);\n return true;\n },\n\n componentWillUpdate: function(nextProps, nextState) {\n this.peekAtState('componentWillUpdate-currentState');\n this.peekAtState('componentWillUpdate-nextState', nextState);\n },\n\n componentDidUpdate: function(prevProps, prevState) {\n this.peekAtState('componentDidUpdate-currentState');\n this.peekAtState('componentDidUpdate-prevState', prevState);\n },\n\n componentWillUnmount: function() {\n this.peekAtState('componentWillUnmount');\n }\n });\n\n });\n\n it('should support setting state', function() {\n var stateListener = mocks.getMockFunction();\n var instance = TestComponent( {stateListener:stateListener} );\n ReactTestUtils.renderIntoDocument(instance);\n instance.setProps({nextColor: 'green'});\n instance.setFavoriteColor('blue');\n instance.forceUpdate();\n instance.unmountComponent();\n\n expect(stateListener.mock.calls).toEqual([\n // there is no state when getInitialState() is called\n [ 'getInitialState', null, null ],\n [ 'componentWillMount-start', 'red', null ],\n // setState() only enqueues a pending state.\n [ 'componentWillMount-after-sunrise', 'red', 'sunrise' ],\n [ 'componentWillMount-end', 'red', 'orange' ],\n // pending state has been applied\n [ 'render', 'orange', null ],\n [ 'componentDidMount-start', 'orange', null ],\n // componentDidMount() called setState({color:'yellow'}), currently this\n // occurs inline.\n // In a future where setState() is async, this test result will change.\n [ 'shouldComponentUpdate-currentState', 'orange', null ],\n [ 'shouldComponentUpdate-nextState', 'yellow' ],\n [ 'componentWillUpdate-currentState', 'orange', null ],\n [ 'componentWillUpdate-nextState', 'yellow' ],\n [ 'render', 'yellow', null ],\n [ 'componentDidUpdate-currentState', 'yellow', null ],\n [ 'componentDidUpdate-prevState', 'orange' ],\n // componentDidMount() finally closes.\n [ 'componentDidMount-end', 'yellow', null ],\n [ 'componentWillReceiveProps-start', 'yellow', null ],\n // setState({color:'green'}) only enqueues a pending state.\n [ 'componentWillReceiveProps-end', 'yellow', 'green' ],\n [ 'shouldComponentUpdate-currentState', 'yellow', null ],\n [ 'shouldComponentUpdate-nextState', 'green' ],\n [ 'componentWillUpdate-currentState', 'yellow', null ],\n [ 'componentWillUpdate-nextState', 'green' ],\n [ 'render', 'green', null ],\n [ 'componentDidUpdate-currentState', 'green', null ],\n [ 'componentDidUpdate-prevState', 'yellow' ],\n // setFavoriteColor('blue')\n [ 'shouldComponentUpdate-currentState', 'green', null ],\n [ 'shouldComponentUpdate-nextState', 'blue' ],\n [ 'componentWillUpdate-currentState', 'green', null ],\n [ 'componentWillUpdate-nextState', 'blue' ],\n [ 'render', 'blue', null ],\n [ 'componentDidUpdate-currentState', 'blue', null ],\n [ 'componentDidUpdate-prevState', 'green' ],\n // forceUpdate()\n [ 'componentWillUpdate-currentState', 'blue', null ],\n [ 'componentWillUpdate-nextState', 'blue' ],\n [ 'render', 'blue', null ],\n [ 'componentDidUpdate-currentState', 'blue', null ],\n [ 'componentDidUpdate-prevState', 'blue' ],\n // unmountComponent()\n // state is available within `componentWillUnmount()`\n [ 'componentWillUnmount', 'blue', null ]\n ]);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactCompositeComponentState-test\", module);\n", -"core/__tests__/ReactDOM-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar React = require(\"../../React\");\nvar ReactDOM = require(\"../../ReactDOM\");\nvar ReactMount = require(\"../../ReactMount\");\nvar ReactTestUtils = require(\"../../ReactTestUtils\");\n\ndescribe('ReactDOM', function() {\n // TODO: uncomment this test once we can run in phantom, which\n // supports real submit events.\n /*\n it('should bubble onSubmit', function() {\n var count = 0;\n var form;\n var Parent = React.createClass({\n handleSubmit: function() {\n count++;\n return false;\n },\n render: function() {\n return ;\n }\n });\n var Child = React.createClass({\n render: function() {\n return
;\n },\n componentDidMount: function(node) {\n form = node;\n }\n });\n var instance = ReactTestUtils.renderIntoDocument();\n form.submit();\n expect(count).toEqual(1);\n });\n */\n\n it(\"should allow children to be passed as an argument\", function() {\n var argDiv = ReactTestUtils.renderIntoDocument(\n ReactDOM.div(null, 'child')\n );\n var argNode = ReactMount.getNode(argDiv._rootNodeID);\n expect(argNode.innerHTML).toBe('child');\n });\n\n it(\"should overwrite props.children with children argument\", function() {\n var conflictDiv = ReactTestUtils.renderIntoDocument(\n ReactDOM.div({children: 'fakechild'}, 'child')\n );\n var conflictNode = ReactMount.getNode(conflictDiv._rootNodeID);\n expect(conflictNode.innerHTML).toBe('child');\n });\n\n /**\n * We need to make sure that updates occur to the actual node that's in the\n * DOM, instead of a stale cache.\n */\n it(\"should purge the DOM cache when removing nodes\", function() {\n var myDiv = ReactTestUtils.renderIntoDocument(\n React.DOM.div(null, {\n theDog: React.DOM.div( {className:\"dog\"} ),\n theBird: React.DOM.div( {className:\"bird\"} )\n })\n );\n // Warm the cache with theDog\n myDiv.setProps({\n children: {\n theDog: React.DOM.div( {className:\"dogbeforedelete\"} ),\n theBird: React.DOM.div( {className:\"bird\"} )\n }\n });\n // Remove theDog - this should purge the cache\n myDiv.setProps({\n children: {\n theBird: React.DOM.div( {className:\"bird\"} )\n }\n });\n // Now, put theDog back. It's now a different DOM node.\n myDiv.setProps({\n children: {\n theDog: React.DOM.div( {className:\"dog\"} ),\n theBird: React.DOM.div( {className:\"bird\"} )\n }\n });\n // Change the className of theDog. It will use the same element\n myDiv.setProps({\n children: {\n theDog: React.DOM.div( {className:\"bigdog\"} ),\n theBird: React.DOM.div( {className:\"bird\"} )\n }\n });\n var root = ReactMount.getNode(myDiv._rootNodeID);\n var dog = root.childNodes[0];\n expect(dog.className).toBe('bigdog');\n });\n\n it('should be a valid class', function() {\n expect(React.isValidClass(ReactDOM.div)).toBe(true);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactDOM-test\", module);\n", -"core/__tests__/ReactDOMComponent-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar mocks = require(\"../../mocks\");\n\ndescribe('ReactDOMComponent', function() {\n\n describe('updateDOM', function() {\n var React;\n var ReactTestUtils;\n var transaction;\n\n beforeEach(function() {\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n\n var ReactReconcileTransaction = require(\"../../ReactReconcileTransaction\");\n transaction = new ReactReconcileTransaction();\n });\n\n it(\"should handle className\", function() {\n var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:{}} ));\n\n stub.receiveProps({ className: 'foo' }, transaction);\n expect(stub.getDOMNode().className).toEqual('foo');\n stub.receiveProps({ className: 'bar' }, transaction);\n expect(stub.getDOMNode().className).toEqual('bar');\n stub.receiveProps({ className: null }, transaction);\n expect(stub.getDOMNode().className).toEqual('');\n });\n\n it(\"should gracefully handle various style value types\", function() {\n var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:{}} ));\n var stubStyle = stub.getDOMNode().style;\n\n // set initial style\n var setup = { display: 'block', left: '1', top: 2, fontFamily: 'Arial' };\n stub.receiveProps({ style: setup }, transaction);\n expect(stubStyle.display).toEqual('block');\n expect(stubStyle.left).toEqual('1px');\n expect(stubStyle.fontFamily).toEqual('Arial');\n\n // reset the style to their default state\n var reset = { display: '', left: null, top: false, fontFamily: true };\n stub.receiveProps({ style: reset }, transaction);\n expect(stubStyle.display).toEqual('');\n expect(stubStyle.left).toEqual('');\n expect(stubStyle.top).toEqual('');\n expect(stubStyle.fontFamily).toEqual('');\n });\n\n it(\"should update styles when mutating style object\", function() {\n var styles = { display: 'none', fontFamily: 'Arial', opacity: 0 };\n var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:styles} ));\n\n var stubStyle = stub.getDOMNode().style;\n stubStyle.display = styles.display;\n stubStyle.fontFamily = styles.fontFamily;\n\n styles.display = 'block';\n\n stub.receiveProps({ style: styles }, transaction);\n expect(stubStyle.display).toEqual('block');\n expect(stubStyle.fontFamily).toEqual('Arial');\n expect(stubStyle.opacity).toEqual('0');\n\n styles.fontFamily = 'Helvetica';\n\n stub.receiveProps({ style: styles }, transaction);\n expect(stubStyle.display).toEqual('block');\n expect(stubStyle.fontFamily).toEqual('Helvetica');\n expect(stubStyle.opacity).toEqual('0');\n\n styles.opacity = 0.5;\n\n stub.receiveProps({ style: styles }, transaction);\n expect(stubStyle.display).toEqual('block');\n expect(stubStyle.fontFamily).toEqual('Helvetica');\n expect(stubStyle.opacity).toEqual('0.5');\n });\n\n it(\"should update styles if initially null\", function() {\n var styles = null;\n var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:styles} ));\n\n var stubStyle = stub.getDOMNode().style;\n\n styles = {display: 'block'};\n\n stub.receiveProps({ style: styles }, transaction);\n expect(stubStyle.display).toEqual('block');\n });\n\n it(\"should remove attributes\", function() {\n var stub = ReactTestUtils.renderIntoDocument(React.DOM.img( {height:\"17\"} ));\n\n expect(stub.getDOMNode().hasAttribute('height')).toBe(true);\n stub.receiveProps({}, transaction);\n expect(stub.getDOMNode().hasAttribute('height')).toBe(false);\n });\n\n it(\"should remove properties\", function() {\n var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {className:\"monkey\"} ));\n\n expect(stub.getDOMNode().className).toEqual('monkey');\n stub.receiveProps({}, transaction);\n expect(stub.getDOMNode().className).toEqual('');\n });\n\n it(\"should clear a single style prop when changing 'style'\", function() {\n var styles = {display: 'none', color: 'red'};\n var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:styles} ));\n\n var stubStyle = stub.getDOMNode().style;\n\n styles = {color: 'green'};\n stub.receiveProps({ style: styles }, transaction);\n expect(stubStyle.display).toEqual('');\n expect(stubStyle.color).toEqual('green');\n });\n\n it(\"should clear all the styles when removing 'style'\", function() {\n var styles = {display: 'none', color: 'red'};\n var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {style:styles} ));\n\n var stubStyle = stub.getDOMNode().style;\n\n stub.receiveProps({}, transaction);\n expect(stubStyle.display).toEqual('');\n expect(stubStyle.color).toEqual('');\n });\n\n it(\"should empty element when removing innerHTML\", function() {\n var stub = ReactTestUtils.renderIntoDocument(\n React.DOM.div( {dangerouslySetInnerHTML:{__html: ':)'}} )\n );\n\n expect(stub.getDOMNode().innerHTML).toEqual(':)');\n stub.receiveProps({}, transaction);\n expect(stub.getDOMNode().innerHTML).toEqual('');\n });\n\n it(\"should transition from string content to innerHTML\", function() {\n var stub = ReactTestUtils.renderIntoDocument(\n React.DOM.div(null, \"hello\")\n );\n\n expect(stub.getDOMNode().innerHTML).toEqual('hello');\n stub.receiveProps(\n {dangerouslySetInnerHTML: {__html: 'goodbye'}},\n transaction\n );\n expect(stub.getDOMNode().innerHTML).toEqual('goodbye');\n });\n\n it(\"should transition from innerHTML to string content\", function() {\n var stub = ReactTestUtils.renderIntoDocument(\n React.DOM.div( {dangerouslySetInnerHTML:{__html: 'bonjour'}} )\n );\n\n expect(stub.getDOMNode().innerHTML).toEqual('bonjour');\n stub.receiveProps({children: 'adieu'}, transaction);\n expect(stub.getDOMNode().innerHTML).toEqual('adieu');\n });\n\n it(\"should not incur unnecessary DOM mutations\", function() {\n var stub = ReactTestUtils.renderIntoDocument(React.DOM.div( {value:\"\"} ));\n\n var node = stub.getDOMNode();\n var nodeValue = node.value;\n var nodeValueSetter = mocks.getMockFunction();\n Object.defineProperty(node, 'value', {\n get: function() {\n return nodeValue;\n },\n set: nodeValueSetter.mockImplementation(function(newValue) {\n nodeValue = newValue;\n })\n });\n\n stub.receiveProps({value: ''}, transaction);\n expect(nodeValueSetter.mock.calls.length).toBe(0);\n\n stub.receiveProps({}, transaction);\n expect(nodeValueSetter.mock.calls.length).toBe(1);\n });\n });\n\n describe('createOpenTagMarkup', function() {\n var genMarkup;\n\n function quoteRegexp(str) {\n return (str+'').replace(/([.?*+\\^$\\[\\]\\\\(){}|-])/g, \"\\\\$1\");\n }\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n\n var ReactDefaultInjection = require(\"../../ReactDefaultInjection\");\n ReactDefaultInjection.inject();\n\n var mixInto = require(\"../../mixInto\");\n var ReactDOMComponent = require(\"../../ReactDOMComponent\");\n\n var NodeStub = function(initialProps) {\n this.props = initialProps || {};\n this._rootNodeID = 'test';\n };\n mixInto(NodeStub, ReactDOMComponent.Mixin);\n\n genMarkup = function(props) {\n return (new NodeStub(props))._createOpenTagMarkup();\n };\n\n this.addMatchers({\n toHaveAttribute: function(attr, value) {\n var expected = '(?:^|\\\\s)' + attr + '=[\\\\\\'\"]';\n if (typeof value != 'undefined') {\n expected += quoteRegexp(value) + '[\\\\\\'\"]';\n }\n return this.actual.match(new RegExp(expected));\n }\n });\n });\n\n it(\"should generate the correct markup with className\", function() {\n expect(genMarkup({ className: 'a' })).toHaveAttribute('class', 'a');\n expect(genMarkup({ className: 'a b' })).toHaveAttribute('class', 'a b');\n expect(genMarkup({ className: '' })).toHaveAttribute('class', '');\n });\n });\n\n describe('createContentMarkup', function() {\n var genMarkup;\n\n function quoteRegexp(str) {\n return (str+'').replace(/([.?*+\\^$\\[\\]\\\\(){}|-])/g, \"\\\\$1\");\n }\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n\n var mixInto = require(\"../../mixInto\");\n var ReactDOMComponent = require(\"../../ReactDOMComponent\");\n var ReactReconcileTransaction = require(\"../../ReactReconcileTransaction\");\n\n var NodeStub = function(initialProps) {\n this.props = initialProps || {};\n this._rootNodeID = 'test';\n };\n mixInto(NodeStub, ReactDOMComponent.Mixin);\n\n genMarkup = function(props) {\n var transaction = new ReactReconcileTransaction();\n return (new NodeStub(props))._createContentMarkup(transaction);\n };\n\n this.addMatchers({\n toHaveInnerhtml: function(html) {\n var expected = '^' + quoteRegexp(html) + '$';\n return this.actual.match(new RegExp(expected));\n }\n });\n });\n\n it(\"should handle dangerouslySetInnerHTML\", function() {\n var innerHTML = {__html: 'testContent'};\n expect(\n genMarkup({ dangerouslySetInnerHTML: innerHTML })\n ).toHaveInnerhtml('testContent');\n });\n });\n\n describe('mountComponent', function() {\n var mountComponent;\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n\n var mixInto = require(\"../../mixInto\");\n var ReactComponent = require(\"../../ReactComponent\");\n var ReactMultiChild = require(\"../../ReactMultiChild\");\n var ReactDOMComponent = require(\"../../ReactDOMComponent\");\n var ReactReconcileTransaction = require(\"../../ReactReconcileTransaction\");\n\n var StubNativeComponent = function(initialProps) {\n ReactComponent.Mixin.construct.call(this, initialProps);\n };\n mixInto(StubNativeComponent, ReactComponent.Mixin);\n mixInto(StubNativeComponent, ReactDOMComponent.Mixin);\n mixInto(StubNativeComponent, ReactMultiChild.Mixin);\n\n mountComponent = function(props) {\n var transaction = new ReactReconcileTransaction();\n var stubComponent = new StubNativeComponent(props);\n return stubComponent.mountComponent('test', transaction, 0);\n };\n });\n\n it(\"should validate against multiple children props\", function() {\n expect(function() {\n mountComponent({ children: '', dangerouslySetInnerHTML: '' });\n }).toThrow(\n 'Invariant Violation: Can only set one of `children` or ' +\n '`props.dangerouslySetInnerHTML`.'\n );\n });\n\n it(\"should validate against invalid styles\", function() {\n expect(function() {\n mountComponent({ style: 'display: none' });\n }).toThrow(\n 'Invariant Violation: The `style` prop expects a mapping from style ' +\n 'properties to values, not a string.'\n );\n });\n });\n\n describe('unmountComponent', function() {\n it(\"should clean up listeners\", function() {\n var React = require(\"../../React\");\n var ReactEventEmitter = require(\"../../ReactEventEmitter\");\n var ReactMount = require(\"../../ReactMount\");\n\n var container = document.createElement('div');\n document.documentElement.appendChild(container);\n\n var callback = function() {};\n var instance = React.DOM.div( {onClick:callback} );\n React.renderComponent(instance, container);\n\n var rootNode = instance.getDOMNode();\n var rootNodeID = ReactMount.getID(rootNode);\n expect(\n ReactEventEmitter.getListener(rootNodeID, 'onClick')\n ).toBe(callback);\n\n React.unmountComponentAtNode(container);\n\n expect(\n ReactEventEmitter.getListener(rootNodeID, 'onClick')\n ).toBe(undefined);\n });\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactDOMComponent-test\", module);\n", -"core/__tests__/ReactDOMIDOperations-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\ndescribe('ReactDOMIDOperations', function() {\n var DOMPropertyOperations = require(\"../../DOMPropertyOperations\");\n var ReactDOMIDOperations = require(\"../../ReactDOMIDOperations\");\n var ReactMount = require(\"../../ReactMount\");\n var keyOf = require(\"../../keyOf\");\n\n it('should disallow updating special properties', function() {\n spyOn(ReactMount, \"getNode\");\n spyOn(DOMPropertyOperations, \"setValueForProperty\");\n\n expect(function() {\n ReactDOMIDOperations.updatePropertyByID(\n 'testID',\n keyOf({dangerouslySetInnerHTML: null}),\n {__html: 'testContent'}\n );\n }).toThrow();\n\n expect(\n ReactMount.getNode.argsForCall[0][0]\n ).toBe('testID');\n\n expect(\n DOMPropertyOperations.setValueForProperty.callCount\n ).toBe(0);\n });\n\n it('should update innerHTML and special-case whitespace', function() {\n var stubNode = document.createElement('div');\n spyOn(ReactMount, \"getNode\").andReturn(stubNode);\n\n ReactDOMIDOperations.updateInnerHTMLByID(\n 'testID',\n ' testContent'\n );\n\n expect(\n ReactMount.getNode.argsForCall[0][0]\n ).toBe('testID');\n\n expect(stubNode.innerHTML).toBe(' testContent');\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactDOMIDOperations-test\", module);\n", -"core/__tests__/ReactEventEmitter-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\")\n .dontMock('BrowserScroll')\n .dontMock('CallbackRegistry')\n .dontMock('EventPluginHub')\n .dontMock('ReactMount')\n .dontMock('ReactEventEmitter')\n .dontMock('ReactInstanceHandles')\n .dontMock('EventPluginHub')\n .dontMock('TapEventPlugin')\n .dontMock('TouchEventUtils')\n .dontMock('keyOf');\n\n\nvar keyOf = require(\"../../keyOf\");\nvar mocks = require(\"../../mocks\");\n\nvar EventPluginHub;\nvar ReactMount = require(\"../../ReactMount\");\nvar getID = ReactMount.getID;\nvar setID = ReactMount.setID;\nvar ReactEventEmitter;\nvar ReactTestUtils;\nvar TapEventPlugin;\n\nvar tapMoveThreshold;\nvar idCallOrder = [];\nvar recordID = function(id) {\n idCallOrder.push(id);\n};\nvar recordIDAndStopPropagation = function(id, event) {\n recordID(id);\n event.stopPropagation();\n};\nvar recordIDAndReturnFalse = function(id, event) {\n recordID(id);\n return false;\n};\nvar LISTENER = mocks.getMockFunction();\nvar ON_CLICK_KEY = keyOf({onClick: null});\nvar ON_TOUCH_TAP_KEY = keyOf({onTouchTap: null});\n\n\n/**\n * Since `ReactEventEmitter` is fairly well separated from the DOM, we can test\n * almost all of `ReactEventEmitter` without ever rendering anything in the DOM.\n * As long as we provide IDs that follow `React's` conventional id namespace\n * hierarchy. The only reason why we create these DOM nodes, is so that when we\n * feed them into `ReactEventEmitter` (through `ReactTestUtils`), the event\n * handlers may receive a DOM node to inspect.\n */\nvar CHILD = document.createElement('div');\nvar PARENT = document.createElement('div');\nvar GRANDPARENT = document.createElement('div');\nsetID(CHILD, '.reactRoot.[0].[0].[0]');\nsetID(PARENT, '.reactRoot.[0].[0]');\nsetID(GRANDPARENT, '.reactRoot.[0]');\n\nfunction registerSimpleTestHandler() {\n ReactEventEmitter.putListener(getID(CHILD), ON_CLICK_KEY, LISTENER);\n var listener = ReactEventEmitter.getListener(getID(CHILD), ON_CLICK_KEY);\n expect(listener).toEqual(LISTENER);\n return ReactEventEmitter.getListener(getID(CHILD), ON_CLICK_KEY);\n}\n\n\ndescribe('ReactEventEmitter', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n EventPluginHub = require(\"../../EventPluginHub\");\n TapEventPlugin = require(\"../../TapEventPlugin\");\n ReactMount = require(\"../../ReactMount\");\n getID = ReactMount.getID;\n setID = ReactMount.setID;\n ReactEventEmitter = require(\"../../ReactEventEmitter\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n idCallOrder = [];\n tapMoveThreshold = TapEventPlugin.tapMoveThreshold;\n ReactEventEmitter.ensureListening(false, document);\n EventPluginHub.injection.injectEventPluginsByName({\n TapEventPlugin: TapEventPlugin\n });\n });\n\n it('should store a listener correctly', function() {\n registerSimpleTestHandler();\n var listener = ReactEventEmitter.getListener(getID(CHILD), ON_CLICK_KEY);\n expect(listener).toBe(LISTENER);\n });\n\n it('should retrieve a listener correctly', function() {\n registerSimpleTestHandler();\n var listener = ReactEventEmitter.getListener(getID(CHILD), ON_CLICK_KEY);\n expect(listener).toEqual(LISTENER);\n });\n\n it('should clear all handlers when asked to', function() {\n registerSimpleTestHandler();\n ReactEventEmitter.deleteAllListeners(getID(CHILD));\n var listener = ReactEventEmitter.getListener(getID(CHILD), ON_CLICK_KEY);\n expect(listener).toBe(undefined);\n });\n\n it('should invoke a simple handler registered on a node', function() {\n registerSimpleTestHandler();\n ReactTestUtils.Simulate.click(CHILD);\n expect(LISTENER.mock.calls.length).toBe(1);\n });\n\n it('should not invoke handlers if ReactEventEmitter is disabled', function() {\n registerSimpleTestHandler();\n ReactEventEmitter.setEnabled(false);\n ReactTestUtils.Simulate.click(CHILD);\n expect(LISTENER.mock.calls.length).toBe(0);\n ReactEventEmitter.setEnabled(true);\n ReactTestUtils.Simulate.click(CHILD);\n expect(LISTENER.mock.calls.length).toBe(1);\n });\n\n it('should bubble simply', function() {\n ReactEventEmitter.putListener(\n getID(CHILD),\n ON_CLICK_KEY,\n recordID.bind(null, getID(CHILD))\n );\n ReactEventEmitter.putListener(\n getID(PARENT),\n ON_CLICK_KEY,\n recordID.bind(null, getID(PARENT))\n );\n ReactEventEmitter.putListener(\n getID(GRANDPARENT),\n ON_CLICK_KEY,\n recordID.bind(null, getID(GRANDPARENT))\n );\n ReactTestUtils.Simulate.click(CHILD);\n expect(idCallOrder.length).toBe(3);\n expect(idCallOrder[0]).toBe(getID(CHILD));\n expect(idCallOrder[1]).toBe(getID(PARENT));\n expect(idCallOrder[2]).toBe(getID(GRANDPARENT));\n });\n\n it('should support stopPropagation()', function() {\n ReactEventEmitter.putListener(\n getID(CHILD),\n ON_CLICK_KEY,\n recordID.bind(null, getID(CHILD))\n );\n ReactEventEmitter.putListener(\n getID(PARENT),\n ON_CLICK_KEY,\n recordIDAndStopPropagation.bind(null, getID(PARENT))\n );\n ReactEventEmitter.putListener(\n getID(GRANDPARENT),\n ON_CLICK_KEY,\n recordID.bind(null, getID(GRANDPARENT))\n );\n ReactTestUtils.Simulate.click(CHILD);\n expect(idCallOrder.length).toBe(2);\n expect(idCallOrder[0]).toBe(getID(CHILD));\n expect(idCallOrder[1]).toBe(getID(PARENT));\n });\n\n it('should stop after first dispatch if stopPropagation', function() {\n ReactEventEmitter.putListener(\n getID(CHILD),\n ON_CLICK_KEY,\n recordIDAndStopPropagation.bind(null, getID(CHILD))\n );\n ReactEventEmitter.putListener(\n getID(PARENT),\n ON_CLICK_KEY,\n recordID.bind(null, getID(PARENT))\n );\n ReactEventEmitter.putListener(\n getID(GRANDPARENT),\n ON_CLICK_KEY,\n recordID.bind(null, getID(GRANDPARENT))\n );\n ReactTestUtils.Simulate.click(CHILD);\n expect(idCallOrder.length).toBe(1);\n expect(idCallOrder[0]).toBe(getID(CHILD));\n });\n\n it('should stopPropagation if false is returned', function() {\n ReactEventEmitter.putListener(\n getID(CHILD),\n ON_CLICK_KEY,\n recordIDAndReturnFalse.bind(null, getID(CHILD))\n );\n ReactEventEmitter.putListener(\n getID(PARENT),\n ON_CLICK_KEY,\n recordID.bind(null, getID(PARENT))\n );\n ReactEventEmitter.putListener(\n getID(GRANDPARENT),\n ON_CLICK_KEY,\n recordID.bind(null, getID(GRANDPARENT))\n );\n ReactTestUtils.Simulate.click(CHILD);\n expect(idCallOrder.length).toBe(1);\n expect(idCallOrder[0]).toBe(getID(CHILD));\n });\n\n /**\n * The entire event registration state of the world should be \"locked-in\" at\n * the time the event occurs. This is to resolve many edge cases that come\n * about from a listener on a lower-in-DOM node causing structural changes at\n * places higher in the DOM. If this lower-in-DOM node causes new content to\n * be rendered at a place higher-in-DOM, we need to be careful not to invoke\n * these new listeners.\n */\n\n it('should invoke handlers that were removed while bubbling', function() {\n var handleParentClick = mocks.getMockFunction();\n var handleChildClick = function(event) {\n ReactEventEmitter.deleteAllListeners(getID(PARENT));\n };\n ReactEventEmitter.putListener(getID(CHILD), ON_CLICK_KEY, handleChildClick);\n ReactEventEmitter.putListener(\n getID(PARENT),\n ON_CLICK_KEY,\n handleParentClick\n );\n ReactTestUtils.Simulate.click(CHILD);\n expect(handleParentClick.mock.calls.length).toBe(1);\n });\n\n it('should not invoke newly inserted handlers while bubbling', function() {\n var handleParentClick = mocks.getMockFunction();\n var handleChildClick = function(event) {\n ReactEventEmitter.putListener(\n getID(PARENT),\n ON_CLICK_KEY,\n handleParentClick\n );\n };\n ReactEventEmitter.putListener(getID(CHILD), ON_CLICK_KEY, handleChildClick);\n ReactTestUtils.Simulate.click(CHILD);\n expect(handleParentClick.mock.calls.length).toBe(0);\n });\n\n it('should infer onTouchTap from a touchStart/End', function() {\n ReactEventEmitter.putListener(\n getID(CHILD),\n ON_TOUCH_TAP_KEY,\n recordID.bind(null, getID(CHILD))\n );\n ReactTestUtils.Simulate.touchStart(\n CHILD,\n ReactTestUtils.nativeTouchData(0, 0)\n );\n ReactTestUtils.Simulate.touchEnd(\n CHILD,\n ReactTestUtils.nativeTouchData(0, 0)\n );\n expect(idCallOrder.length).toBe(1);\n expect(idCallOrder[0]).toBe(getID(CHILD));\n });\n\n it('should infer onTouchTap from when dragging below threshold', function() {\n ReactEventEmitter.putListener(\n getID(CHILD),\n ON_TOUCH_TAP_KEY,\n recordID.bind(null, getID(CHILD))\n );\n ReactTestUtils.Simulate.touchStart(\n CHILD,\n ReactTestUtils.nativeTouchData(0, 0)\n );\n ReactTestUtils.Simulate.touchEnd(\n CHILD,\n ReactTestUtils.nativeTouchData(0, tapMoveThreshold - 1)\n );\n expect(idCallOrder.length).toBe(1);\n expect(idCallOrder[0]).toBe(getID(CHILD));\n });\n\n it('should not onTouchTap from when dragging beyond threshold', function() {\n ReactEventEmitter.putListener(\n getID(CHILD),\n ON_TOUCH_TAP_KEY,\n recordID.bind(null, getID(CHILD))\n );\n ReactTestUtils.Simulate.touchStart(\n CHILD,\n ReactTestUtils.nativeTouchData(0, 0)\n );\n ReactTestUtils.Simulate.touchEnd(\n CHILD,\n ReactTestUtils.nativeTouchData(0, tapMoveThreshold + 1)\n );\n expect(idCallOrder.length).toBe(0);\n });\n\n\n it('should bubble onTouchTap', function() {\n ReactEventEmitter.putListener(\n getID(CHILD),\n ON_TOUCH_TAP_KEY,\n recordID.bind(null, getID(CHILD))\n );\n ReactEventEmitter.putListener(\n getID(PARENT),\n ON_TOUCH_TAP_KEY,\n recordID.bind(null, getID(PARENT))\n );\n ReactEventEmitter.putListener(\n getID(GRANDPARENT),\n ON_TOUCH_TAP_KEY,\n recordID.bind(null, getID(GRANDPARENT))\n );\n ReactTestUtils.Simulate.touchStart(\n CHILD,\n ReactTestUtils.nativeTouchData(0, 0)\n );\n ReactTestUtils.Simulate.touchEnd(\n CHILD,\n ReactTestUtils.nativeTouchData(0, 0)\n );\n expect(idCallOrder.length).toBe(3);\n expect(idCallOrder[0]).toBe(getID(CHILD));\n expect(idCallOrder[1]).toBe(getID(PARENT));\n expect(idCallOrder[2]).toBe(getID(GRANDPARENT));\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactEventEmitter-test\", module);\n", -"core/__tests__/ReactIdentity-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React;\nvar ReactTestUtils;\nvar reactComponentExpect;\nvar ReactMount;\n\ndescribe('ReactIdentity', function() {\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n reactComponentExpect = require(\"../../reactComponentExpect\");\n ReactMount = require(\"../../ReactMount\");\n });\n\n var idExp = /^\\.r\\[.+?\\](.*)$/;\n function checkId(child, expectedId) {\n var actual = idExp.exec(ReactMount.getID(child));\n var expected = idExp.exec(expectedId);\n expect(actual).toBeTruthy();\n expect(expected).toBeTruthy();\n expect(actual[1]).toEqual(expected[1]);\n }\n\n it('should allow keyed objects to express identity', function() {\n var instance =\n React.DOM.div(null, \n {\n first: React.DOM.div(null ),\n second: React.DOM.div(null )\n }\n );\n\n React.renderComponent(instance, document.createElement('div'));\n var node = instance.getDOMNode();\n reactComponentExpect(instance).toBeDOMComponentWithChildCount(2);\n checkId(node.childNodes[0], '.r[0].{first}');\n checkId(node.childNodes[1], '.r[0].{second}');\n });\n\n it('should allow key property to express identity', function() {\n var instance =\n React.DOM.div(null, \n React.DOM.div( {key:\"apple\"} ),\n React.DOM.div( {key:\"banana\"} ),\n React.DOM.div( {key:0} ),\n React.DOM.div( {key:123} )\n );\n\n React.renderComponent(instance, document.createElement('div'));\n var node = instance.getDOMNode();\n reactComponentExpect(instance).toBeDOMComponentWithChildCount(4);\n checkId(node.childNodes[0], '.r[0].{apple}');\n checkId(node.childNodes[1], '.r[0].{banana}');\n checkId(node.childNodes[2], '.r[0].{0}');\n checkId(node.childNodes[3], '.r[0].{123}');\n });\n\n it('should use instance identity', function() {\n\n var Wrapper = React.createClass({displayName: 'Wrapper',\n render: function() {\n return React.DOM.a( {key:\"i_get_overwritten\"}, this.props.children);\n }\n });\n\n var instance =\n React.DOM.div(null, \n Wrapper( {key:\"wrap1\"}, React.DOM.span( {key:\"squirrel\"} )),\n Wrapper( {key:\"wrap2\"}, React.DOM.span( {key:\"bunny\"} )),\n Wrapper(null, React.DOM.span( {key:\"chipmunk\"} ))\n );\n\n React.renderComponent(instance, document.createElement('div'));\n var node = instance.getDOMNode();\n reactComponentExpect(instance).toBeDOMComponentWithChildCount(3);\n\n checkId(node.childNodes[0], '.r[0].{wrap1}');\n checkId(node.childNodes[0].firstChild, '.r[0].{wrap1}.{squirrel}');\n checkId(node.childNodes[1], '.r[0].{wrap2}');\n checkId(node.childNodes[1].firstChild, '.r[0].{wrap2}.{bunny}');\n checkId(node.childNodes[2], '.r[0].[2]');\n checkId(node.childNodes[2].firstChild, '.r[0].[2].{chipmunk}');\n });\n\n function renderAComponentWithKeyIntoContainer(key, container) {\n var span1 = React.DOM.span( {key:key} );\n var span2 = React.DOM.span(null );\n\n var map = {};\n map[key] = span2;\n\n React.renderComponent(React.DOM.div(null, [span1, map]), container);\n\n expect(span1.getDOMNode()).not.toBe(null);\n expect(span2.getDOMNode()).not.toBe(null);\n\n checkId(span1.getDOMNode(), '.r[0].{' + key + '}');\n checkId(span2.getDOMNode(), '.r[0].[1]{' + key + '}');\n }\n\n it('should allow any character as a key, in a detached parent', function() {\n var detachedContainer = document.createElement('div');\n renderAComponentWithKeyIntoContainer(\"<'WEIRD/&\\\\key'>\", detachedContainer);\n });\n\n it('should allow any character as a key, in an attached parent', function() {\n // This test exists to protect against implementation details that\n // incorrectly query escaped IDs using DOM tools like getElementById.\n var attachedContainer = document.createElement('div');\n document.body.appendChild(attachedContainer);\n\n renderAComponentWithKeyIntoContainer(\"<'WEIRD/&\\\\key'>\", attachedContainer);\n\n document.body.removeChild(attachedContainer);\n });\n\n it('should not allow scripts in keys to execute', function() {\n var h4x0rKey = '\">
1) {\n props.testProp = value;\n }\n return declaration.bind(null, props, 'testProp', 'testComponent');\n}\n\ndescribe('Primitive Types', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n it(\"should throw for invalid strings\", function() {\n expect(typeCheck(Props.string, [])).toThrow(\n 'Invariant Violation: Invalid prop `testProp` of type `array` ' +\n 'supplied to `testComponent`, expected `string`.'\n );\n expect(typeCheck(Props.string, false)).toThrow(\n 'Invariant Violation: Invalid prop `testProp` of type `boolean` ' +\n 'supplied to `testComponent`, expected `string`.'\n );\n expect(typeCheck(Props.string, 1)).toThrow(\n 'Invariant Violation: Invalid prop `testProp` of type `number` ' +\n 'supplied to `testComponent`, expected `string`.'\n );\n expect(typeCheck(Props.string, {})).toThrow(\n 'Invariant Violation: Invalid prop `testProp` of type `object` ' +\n 'supplied to `testComponent`, expected `string`.'\n );\n });\n\n it(\"should not throw for valid values\", function() {\n expect(typeCheck(Props.array, [])).not.toThrow();\n expect(typeCheck(Props.bool, false)).not.toThrow();\n expect(typeCheck(Props.func, function() {})).not.toThrow();\n expect(typeCheck(Props.number, 0)).not.toThrow();\n expect(typeCheck(Props.object, {})).not.toThrow();\n expect(typeCheck(Props.string, '')).not.toThrow();\n });\n\n it(\"should be implicitly optional and not throw without values\", function() {\n expect(typeCheck(Props.string, null)).not.toThrow();\n expect(typeCheck(Props.string, undefined)).not.toThrow();\n });\n\n it(\"should throw for missing required values\", function() {\n expect(typeCheck(Props.string.isRequired, null)).toThrow(\n 'Invariant Violation: Required prop `testProp` was not specified in ' +\n '`testComponent`.'\n );\n expect(typeCheck(Props.string.isRequired, undefined)).toThrow(\n 'Invariant Violation: Required prop `testProp` was not specified in ' +\n '`testComponent`.'\n );\n });\n});\n\ndescribe('Enum Types', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n it(\"should throw for invalid strings\", function() {\n expect(typeCheck(Props.oneOf(['red', 'blue']), true)).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected one of [\"blue\",\"red\"].'\n );\n expect(typeCheck(Props.oneOf(['red', 'blue']), [])).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected one of [\"blue\",\"red\"].'\n );\n expect(typeCheck(Props.oneOf(['red', 'blue']), '')).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected one of [\"blue\",\"red\"].'\n );\n });\n\n it(\"should not throw for valid values\", function() {\n expect(typeCheck(Props.oneOf(['red', 'blue']), 'red')).not.toThrow();\n expect(typeCheck(Props.oneOf(['red', 'blue']), 'blue')).not.toThrow();\n });\n\n it(\"should be implicitly optional and not throw without values\", function() {\n expect(typeCheck(Props.oneOf(['red', 'blue']), null)).not.toThrow();\n expect(typeCheck(Props.oneOf(['red', 'blue']), undefined)).not.toThrow();\n });\n});\n\ndescribe('Instance Types', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n it(\"should throw for invalid instances\", function() {\n function Person() {}\n\n expect(typeCheck(Props.instanceOf(Person), false)).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected instance of `Person`.'\n );\n expect(typeCheck(Props.instanceOf(Person), {})).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected instance of `Person`.'\n );\n expect(typeCheck(Props.instanceOf(Person), '')).toThrow(\n 'Invariant Violation: Invalid prop `testProp` supplied to ' +\n '`testComponent`, expected instance of `Person`.'\n );\n });\n\n it(\"should not throw for valid values\", function() {\n function Person() {}\n function Engineer() {}\n Engineer.prototype = new Person();\n\n expect(typeCheck(Props.instanceOf(Person), new Person())).not.toThrow();\n expect(typeCheck(Props.instanceOf(Person), new Engineer())).not.toThrow();\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactPropTypes-test\", module);\n", -"core/__tests__/ReactRenderDocument-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar React;\nvar ReactMount;\n\nvar getTestDocument;\n\nvar testDocument;\n\ndescribe('rendering React components at document', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n\n React = require(\"../../React\");\n ReactMount = require(\"../../ReactMount\");\n getTestDocument = require(\"../../getTestDocument\");\n\n testDocument = getTestDocument();\n });\n\n it('should be able to switch root constructors via state', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n \" Hello world \"\n )\n )\n );\n }\n });\n\n var Component2 = React.createClass({displayName: 'Component2',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n \" Goodbye world \"\n )\n )\n );\n }\n });\n\n var Root = React.createClass({displayName: 'Root',\n getInitialState: function() {\n return {toggled: false};\n },\n toggle: function() {\n this.setState({toggled: !this.state.toggled});\n },\n render: function() {\n if (this.state.toggled) {\n return Component2(null );\n }\n return Component(null );\n }\n });\n\n ReactMount.allowFullPageRender = true;\n var component = React.renderComponent(Root(null ), testDocument);\n expect(testDocument.body.innerHTML).toBe(' Hello world ');\n\n // Reactive update via state transition\n component.toggle();\n\n expect(testDocument.body.innerHTML).toBe(' Goodbye world ');\n\n });\n\n it('should be able to switch root constructors', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n \" Hello world \"\n )\n )\n );\n }\n });\n\n var Component2 = React.createClass({displayName: 'Component2',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n \" Goodbye world \"\n )\n )\n );\n }\n });\n\n ReactMount.allowFullPageRender = true;\n React.renderComponent(Component(null ), testDocument);\n\n expect(testDocument.body.innerHTML).toBe(' Hello world ');\n\n // Reactive update\n React.renderComponent(Component2(null ), testDocument);\n\n expect(testDocument.body.innerHTML).toBe(' Goodbye world ');\n\n });\n\n it('should be able to mount into document', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var Component = React.createClass({displayName: 'Component',\n render: function() {\n return (\n React.DOM.html(null, \n React.DOM.head(null, \n React.DOM.title(null, \"Hello World\")\n ),\n React.DOM.body(null, \n this.props.text\n )\n )\n );\n }\n });\n ReactMount.allowFullPageRender = true;\n React.renderComponent(Component( {text:\"Hello world\"} ), testDocument);\n\n expect(testDocument.body.innerHTML).toBe('Hello world');\n });\n\n it('should throw on full document render', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var container = testDocument;\n expect(function() {\n React.renderComponent(React.DOM.html(null ), container);\n }).toThrow(\n 'Invariant Violation: mountComponentIntoNode(...): Target container is ' +\n 'not valid.'\n );\n ReactMount.allowFullPageRender = true;\n expect(function() {\n React.renderComponent(React.DOM.html(null ), container);\n }).not.toThrow();\n });\n\n it('should throw on full document render of non-html', function() {\n if (!testDocument) {\n // These tests are not applicable in jst, since jsdom is buggy.\n return;\n }\n\n var container = testDocument;\n ReactMount.allowFullPageRender = true;\n expect(function() {\n React.renderComponent(React.DOM.div(null ), container);\n }).toThrow(\n 'Invariant Violation: mutateHTMLNodeWithMarkup(): ' +\n 'markup must start with = 0; i--) {\n triggerUpdate(components[i]);\n }\n });\n\n expectUpdates(expectation);\n }\n\n testUpdates(\n [root.refs.switcher.refs.box, root.refs.switcher],\n ['Switcher', 'Box', 'Child']\n );\n\n testUpdates(\n [root.refs.child, root.refs.switcher.refs.box],\n ['Box', 'Child']\n );\n\n testUpdates(\n [root.refs.child, root.refs.switcher],\n ['Switcher', 'Box', 'Child']\n );\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/ReactUpdates-test\", module);\n", -"core/__tests__/refs-destruction-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React = require(\"../../React\");\nvar ReactTestUtils = require(\"../../ReactTestUtils\");\nvar reactComponentExpect= require(\"../../reactComponentExpect\");\n\nvar TestComponent = React.createClass({displayName: 'TestComponent',\n render: function() {\n return (\n React.DOM.div(null, \n React.DOM.div( {ref:\"theInnerDiv\"}, \n \" Lets try to destroy this. \"\n )\n )\n );\n }\n});\n\ndescribe('refs-destruction', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n it(\"should remove refs when destroying the parent\", function() {\n var testInstance = ReactTestUtils.renderIntoDocument(TestComponent(null ));\n reactComponentExpect(testInstance.refs.theInnerDiv)\n .toBeDOMComponentWithTag('div');\n expect(Object.keys(testInstance.refs || {}).length).toEqual(1);\n testInstance.unmountComponent();\n expect(Object.keys(testInstance.refs || {}).length).toEqual(0);\n });\n\n it(\"should remove refs when destroying the child\", function() {\n var testInstance = ReactTestUtils.renderIntoDocument(TestComponent(null ));\n reactComponentExpect(testInstance.refs.theInnerDiv)\n .toBeDOMComponentWithTag('div');\n expect(Object.keys(testInstance.refs || {}).length).toEqual(1);\n testInstance.refs.theInnerDiv.unmountComponent();\n expect(Object.keys(testInstance.refs || {}).length).toEqual(0);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/refs-destruction-test\", module);\n", -"core/__tests__/refs-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar React = require(\"../../React\");\nvar ReactTestUtils = require(\"../../ReactTestUtils\");\n\nvar reactComponentExpect= require(\"../../reactComponentExpect\");\n\n\n/**\n * Counts clicks and has a renders an item for each click. Each item rendered\n * has a ref of the form \"clickLogN\".\n */\nvar ClickCounter = React.createClass({displayName: 'ClickCounter',\n getInitialState: function() {\n return {count: this.props.initialCount};\n },\n triggerReset: function() {\n this.setState({count: this.props.initialCount});\n },\n handleClick: function() {\n this.setState({count: this.state.count + 1});\n },\n render: function() {\n var children = [];\n var i;\n for (i=0; i < this.state.count; i++) {\n children.push(\n React.DOM.div(\n {className:\"clickLogDiv\",\n key:\"clickLog\" + i,\n ref:\"clickLog\" + i}\n )\n );\n }\n return (\n React.DOM.span( {className:\"clickIncrementer\", onClick:this.handleClick}, \n children\n )\n );\n }\n});\n\n/**\n * Only purpose is to test that refs are tracked even when applied to a\n * component that is injected down several layers. Ref systems are difficult to\n * build in such a way that ownership is maintained in an airtight manner.\n */\nvar GeneralContainerComponent = React.createClass({displayName: 'GeneralContainerComponent',\n render: function() {\n return React.DOM.div(null, this.props.children );\n }\n});\n\n/**\n * Notice how refs ownership is maintained even when injecting a component\n * into a different parent.\n */\nvar TestRefsComponent = React.createClass({displayName: 'TestRefsComponent',\n doReset: function() {\n this.refs.myCounter.triggerReset();\n },\n render: function() {\n return (\n React.DOM.div(null, \n React.DOM.div( {ref:\"resetDiv\", onClick:this.doReset}, \n \" Reset Me By Clicking This. \"\n ),\n GeneralContainerComponent( {ref:\"myContainer\"}, \n ClickCounter( {ref:\"myCounter\", initialCount:1})\n )\n )\n );\n }\n});\n\n/**\n * Render a TestRefsComponent and ensure that the main refs are wired up.\n */\nvar renderTestRefsComponent = function() {\n var testRefsComponent =\n ReactTestUtils.renderIntoDocument(TestRefsComponent(null ));\n\n reactComponentExpect(testRefsComponent)\n .toBeCompositeComponentWithType(TestRefsComponent);\n\n var generalContainer = testRefsComponent.refs.myContainer;\n var counter = testRefsComponent.refs.myCounter;\n\n reactComponentExpect(generalContainer)\n .toBeCompositeComponentWithType(GeneralContainerComponent);\n reactComponentExpect(counter)\n .toBeCompositeComponentWithType(ClickCounter);\n\n return testRefsComponent;\n};\n\n\nvar expectClickLogsLengthToBe = function(instance, length) {\n var clickLogs =\n ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, 'clickLogDiv');\n expect(clickLogs.length).toBe(length);\n expect(Object.keys(instance.refs.myCounter.refs).length).toBe(length);\n};\n\ndescribe('reactiverefs', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n /**\n * Ensure that for every click log there is a corresponding ref (from the\n * perspective of the injected ClickCounter component.\n */\n it(\"Should increase refs with an increase in divs\", function() {\n var testRefsComponent = renderTestRefsComponent();\n var clickIncrementer =\n ReactTestUtils.findRenderedDOMComponentWithClass(\n testRefsComponent,\n 'clickIncrementer'\n );\n\n expectClickLogsLengthToBe(testRefsComponent, 1);\n\n // After clicking the reset, there should still only be one click log ref.\n ReactTestUtils.Simulate.click(testRefsComponent.refs.resetDiv);\n expectClickLogsLengthToBe(testRefsComponent, 1);\n\n // Begin incrementing clicks (and therefore refs).\n ReactTestUtils.Simulate.click(clickIncrementer);\n expectClickLogsLengthToBe(testRefsComponent, 2);\n\n ReactTestUtils.Simulate.click(clickIncrementer);\n expectClickLogsLengthToBe(testRefsComponent, 3);\n\n // Now reset again\n ReactTestUtils.Simulate.click(testRefsComponent.refs.resetDiv);\n expectClickLogsLengthToBe(testRefsComponent, 1);\n\n });\n\n});\n\n\n\n/**\n * Tests that when a ref hops around children, we can track that correctly.\n */\ndescribe('ref swapping', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n });\n\n var RefHopsAround = React.createClass({displayName: 'RefHopsAround',\n getInitialState: function() {\n return {count: 0};\n },\n moveRef: function() {\n this.setState({ count: this.state.count + 1 });\n },\n render: function() {\n var count = this.state.count;\n /**\n * What we have here, is three divs with refs (div1/2/3), but a single\n * moving cursor ref `hopRef` that \"hops\" around the three. We'll call the\n * `moveRef()` function several times and make sure that the hop ref\n * points to the correct divs.\n */\n return (\n React.DOM.div(null, \n React.DOM.div(\n {className:\"first\",\n ref:count % 3 === 0 ? 'hopRef' : 'divOneRef'}\n ),\n React.DOM.div(\n {className:\"second\",\n ref:count % 3 === 1 ? 'hopRef' : 'divTwoRef'}\n ),\n React.DOM.div(\n {className:\"third\",\n ref:count % 3 === 2 ? 'hopRef' : 'divThreeRef'}\n )\n )\n );\n }\n });\n\n it(\"Allow refs to hop around children correctly\", function() {\n var refHopsAround = ReactTestUtils.renderIntoDocument(RefHopsAround(null ));\n\n var firstDiv =\n ReactTestUtils.findRenderedDOMComponentWithClass(refHopsAround, 'first');\n var secondDiv =\n ReactTestUtils.findRenderedDOMComponentWithClass(refHopsAround, 'second');\n var thirdDiv =\n ReactTestUtils.findRenderedDOMComponentWithClass(refHopsAround, 'third');\n\n expect(refHopsAround.refs.hopRef).toEqual(firstDiv);\n expect(refHopsAround.refs.divTwoRef).toEqual(secondDiv);\n expect(refHopsAround.refs.divThreeRef).toEqual(thirdDiv);\n\n refHopsAround.moveRef();\n expect(refHopsAround.refs.divOneRef).toEqual(firstDiv);\n expect(refHopsAround.refs.hopRef).toEqual(secondDiv);\n expect(refHopsAround.refs.divThreeRef).toEqual(thirdDiv);\n\n refHopsAround.moveRef();\n expect(refHopsAround.refs.divOneRef).toEqual(firstDiv);\n expect(refHopsAround.refs.divTwoRef).toEqual(secondDiv);\n expect(refHopsAround.refs.hopRef).toEqual(thirdDiv);\n\n /**\n * Make sure that after the third, we're back to where we started and the\n * refs are completely restored.\n */\n refHopsAround.moveRef();\n expect(refHopsAround.refs.hopRef).toEqual(firstDiv);\n expect(refHopsAround.refs.divTwoRef).toEqual(secondDiv);\n expect(refHopsAround.refs.divThreeRef).toEqual(thirdDiv);\n });\n});\n\n\nrequire(\"../../mock-modules\").register(\"core/__tests__/refs-test\", module);\n", -"dom/__tests__/CSSPropertyOperations-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar React = require(\"../../React\");\n\ndescribe('CSSPropertyOperations', function() {\n var CSSPropertyOperations;\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n CSSPropertyOperations = require(\"../../CSSPropertyOperations\");\n });\n\n it('should create markup for simple styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n backgroundColor: '#3b5998',\n display: 'none'\n })).toBe('background-color:#3b5998;display:none;');\n });\n\n it('should ignore undefined styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n backgroundColor: undefined,\n display: 'none'\n })).toBe('display:none;');\n });\n\n it('should ignore null styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n backgroundColor: null,\n display: 'none'\n })).toBe('display:none;');\n });\n\n it('should return null for no styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n backgroundColor: null,\n display: null\n })).toBe(null);\n });\n\n it('should automatically append `px` to relevant styles', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n left: 0,\n margin: 16,\n opacity: 0.5,\n padding: '4px'\n })).toBe('left:0;margin:16px;opacity:0.5;padding:4px;');\n });\n\n it('should not append `px` to styles that might need a number', function() {\n expect(CSSPropertyOperations.createMarkupForStyles({\n fillOpacity: 1,\n fontWeight: 2,\n opacity: 3,\n orphans: 4,\n zIndex: 5,\n zoom: 6,\n lineHeight: 7\n })).toBe(\n 'fill-opacity:1;font-weight:2;opacity:3;orphans:4;z-index:5;zoom:6;' +\n 'line-height:7;'\n );\n });\n\n it('should set style attribute when styles exist', function() {\n var styles = {\n backgroundColor: '#000',\n display: 'none'\n };\n var div = React.DOM.div( {style:styles} );\n var root = document.createElement('div');\n React.renderComponent(div, root);\n expect(/style=\".*\"/.test(root.innerHTML)).toBe(true);\n });\n\n it('should not set style attribute when no styles exist', function() {\n var styles = {\n backgroundColor: null,\n display: null\n };\n var div = React.DOM.div( {style:styles} );\n var root = document.createElement('div');\n React.renderComponent(div, root);\n expect(/style=\".*\"/.test(root.innerHTML)).toBe(false);\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/CSSPropertyOperations-test\", module);\n", -"dom/__tests__/DOMPropertyOperations-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\ndescribe('DOMPropertyOperations', function() {\n var DOMPropertyOperations;\n var DOMProperty;\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n var ReactDefaultInjection = require(\"../../ReactDefaultInjection\");\n ReactDefaultInjection.inject();\n\n DOMPropertyOperations = require(\"../../DOMPropertyOperations\");\n DOMProperty = require(\"../../DOMProperty\");\n });\n\n describe('createMarkupForProperty', function() {\n\n it('should create markup for simple properties', function() {\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'name',\n 'simple'\n )).toBe('name=\"simple\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'name',\n false\n )).toBe('name=\"false\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'name',\n null\n )).toBe('');\n });\n\n it('should work with the id attribute', function() {\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'id',\n 'simple'\n )).toBe('id=\"simple\"');\n });\n\n it('should warn about incorrect casing', function() {\n spyOn(console, 'warn');\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'tabindex',\n '1'\n )).toBe(null);\n expect(console.warn.argsForCall.length).toBe(1);\n expect(console.warn.argsForCall[0][0]).toContain('tabIndex');\n });\n\n it('should warn about class', function() {\n spyOn(console, 'warn');\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'class',\n 'muffins'\n )).toBe(null);\n expect(console.warn.argsForCall.length).toBe(1);\n expect(console.warn.argsForCall[0][0]).toContain('className');\n });\n\n it('should create markup for boolean properties', function() {\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'checked',\n 'simple'\n )).toBe('checked=\"simple\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'checked',\n true\n )).toBe('checked=\"true\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'checked',\n false\n )).toBe('');\n });\n\n it('should create markup for custom attributes', function() {\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'aria-label',\n 'simple'\n )).toBe('aria-label=\"simple\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'aria-label',\n false\n )).toBe('aria-label=\"false\"');\n\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'aria-label',\n null\n )).toBe('');\n });\n\n });\n\n describe('setValueForProperty', function() {\n var stubNode;\n\n beforeEach(function() {\n stubNode = document.createElement('div');\n });\n\n it('should set values as properties by default', function() {\n DOMPropertyOperations.setValueForProperty(stubNode, 'title', 'Tip!');\n expect(stubNode.title).toBe('Tip!');\n });\n\n it('should set values as attributes if necessary', function() {\n DOMPropertyOperations.setValueForProperty(stubNode, 'role', '#');\n expect(stubNode.getAttribute('role')).toBe('#');\n expect(stubNode.role).toBeUndefined();\n });\n\n it('should convert attribute values to string first', function() {\n // Browsers default to this behavior, but some test environments do not.\n // This ensures that we have consistent behavior.\n var obj = {toString: function() { return ''; }};\n DOMPropertyOperations.setValueForProperty(stubNode, 'role', obj);\n expect(stubNode.getAttribute('role')).toBe('');\n });\n\n it('should remove for falsey boolean properties', function() {\n DOMPropertyOperations.setValueForProperty(\n stubNode,\n 'allowFullScreen',\n false\n );\n expect(stubNode.hasAttribute('allowFullScreen')).toBe(false);\n });\n\n it('should use mutation method where applicable', function() {\n DOMPropertyOperations.setValueForProperty(\n stubNode,\n 'className',\n 'selected'\n );\n expect(stubNode.className).toBe('selected');\n\n DOMPropertyOperations.setValueForProperty(\n stubNode,\n 'className',\n null\n );\n expect(stubNode.className).toBe('');\n });\n\n });\n\n describe('injectDOMPropertyConfig', function() {\n it('should support custom attributes', function() {\n // foobar does not exist yet\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'foobar',\n 'simple'\n )).toBe(null);\n\n // foo-* does not exist yet\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'foo-xyz',\n 'simple'\n )).toBe(null);\n\n // inject foobar DOM property\n DOMProperty.injection.injectDOMPropertyConfig({\n isCustomAttribute: function(name) {\n return name.indexOf('foo-') === 0;\n },\n Properties: {foobar: null}\n });\n\n // Ensure old attributes still work\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'name',\n 'simple'\n )).toBe('name=\"simple\"');\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'data-name',\n 'simple'\n )).toBe('data-name=\"simple\"');\n\n // foobar should work\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'foobar',\n 'simple'\n )).toBe('foobar=\"simple\"');\n\n // foo-* should work\n expect(DOMPropertyOperations.createMarkupForProperty(\n 'foo-xyz',\n 'simple'\n )).toBe('foo-xyz=\"simple\"');\n\n // It should complain about double injections.\n expect(function() {\n DOMProperty.injection.injectDOMPropertyConfig(\n {Properties: {foobar: null}}\n );\n }).toThrow();\n });\n });\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/DOMPropertyOperations-test\", module);\n", -"dom/__tests__/Danger-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\nvar React = require(\"../../React\");\n\ndescribe('Danger', function() {\n\n describe('dangerouslyRenderMarkup', function() {\n var Danger;\n var transaction;\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n Danger = require(\"../../Danger\");\n\n var ReactReconcileTransaction = require(\"../../ReactReconcileTransaction\");\n transaction = new ReactReconcileTransaction();\n });\n\n it('should render markup', function() {\n var markup = (React.DOM.div(null )).mountComponent('.rX', transaction, 0);\n var output = Danger.dangerouslyRenderMarkup([markup])[0];\n\n expect(output.nodeName).toBe('DIV');\n });\n\n it('should render markup with props', function() {\n var markup = (React.DOM.div( {className:\"foo\"} )).mountComponent(\n '.rX',\n transaction,\n 0\n );\n var output = Danger.dangerouslyRenderMarkup([markup])[0];\n\n expect(output.nodeName).toBe('DIV');\n expect(output.className).toBe('foo');\n });\n\n it('should render wrapped markup', function() {\n var markup = (React.DOM.th(null )).mountComponent('.rX', transaction, 0);\n var output = Danger.dangerouslyRenderMarkup([markup])[0];\n\n expect(output.nodeName).toBe('TH');\n });\n\n it('should render lists of markup with similar `nodeName`', function() {\n var renderedMarkup = Danger.dangerouslyRenderMarkup(\n ['

1

', '

2

', '

3

']\n );\n\n expect(renderedMarkup.length).toBe(3);\n\n expect(renderedMarkup[0].nodeName).toBe('P');\n expect(renderedMarkup[1].nodeName).toBe('P');\n expect(renderedMarkup[2].nodeName).toBe('P');\n\n expect(renderedMarkup[0].innerHTML).toBe('1');\n expect(renderedMarkup[1].innerHTML).toBe('2');\n expect(renderedMarkup[2].innerHTML).toBe('3');\n });\n\n it('should render lists of markup with different `nodeName`', function() {\n var renderedMarkup = Danger.dangerouslyRenderMarkup(\n ['

1

', '
', '

3

']\n );\n\n expect(renderedMarkup.length).toBe(3);\n\n expect(renderedMarkup[0].nodeName).toBe('P');\n expect(renderedMarkup[1].nodeName).toBe('TD');\n expect(renderedMarkup[2].nodeName).toBe('P');\n\n expect(renderedMarkup[0].innerHTML).toBe('1');\n expect(renderedMarkup[1].innerHTML).toBe('2');\n expect(renderedMarkup[2].innerHTML).toBe('3');\n });\n\n it('should throw when rendering invalid markup', function() {\n expect(function() {\n Danger.dangerouslyRenderMarkup(['']);\n }).toThrow(\n 'Invariant Violation: dangerouslyRenderMarkup(...): Missing markup.'\n );\n\n spyOn(console, \"error\");\n\n var renderedMarkup = Danger.dangerouslyRenderMarkup(['

']);\n var args = console.error.argsForCall[0];\n\n expect(renderedMarkup.length).toBe(1);\n expect(renderedMarkup[0].nodeName).toBe('P');\n\n expect(console.error.argsForCall.length).toBe(1);\n\n expect(args.length).toBe(2);\n expect(args[0]).toBe('Danger: Discarding unexpected node:');\n expect(args[1].nodeName).toBe('P');\n });\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/Danger-test\", module);\n", -"dom/__tests__/getNodeForCharacterOffset-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar getTestDocument = require(\"../../getTestDocument\");\n\nvar getNodeForCharacterOffset = require(\"../../getNodeForCharacterOffset\");\n\n// Create node from HTML string\nfunction createNode(html) {\n var node = (getTestDocument() || document).createElement('div');\n node.innerHTML = html;\n return node;\n}\n\n// Check getNodeForCharacterOffset return value matches expected result.\nfunction expectNodeOffset(result, textContent, nodeOffset) {\n expect(result.node.textContent).toBe(textContent);\n expect(result.offset).toBe(nodeOffset);\n}\n\ndescribe('getNodeForCharacterOffset', function() {\n it('should handle siblings', function() {\n var node = createNode('123456789');\n\n expectNodeOffset(getNodeForCharacterOffset(node, 0), '123', 0);\n expectNodeOffset(getNodeForCharacterOffset(node, 4), '456', 1);\n });\n\n it('should handle trailing chars', function() {\n var node = createNode('123456789');\n\n expectNodeOffset(getNodeForCharacterOffset(node, 3), '123', 3);\n expectNodeOffset(getNodeForCharacterOffset(node, 9), '789', 3);\n });\n\n it('should handle trees', function() {\n var node = createNode(\n '' +\n '1' +\n '' +\n '' +\n '2' +\n '' +\n '' +\n '' +\n '' +\n '3' +\n '45' +\n '' +\n ''\n );\n\n expectNodeOffset(getNodeForCharacterOffset(node, 3), '3', 1);\n expectNodeOffset(getNodeForCharacterOffset(node, 5), '45', 2);\n expect(getNodeForCharacterOffset(node, 10)).toBeUndefined();\n });\n\n it('should handle non-existent offset', function() {\n var node = createNode('123');\n\n expect(getNodeForCharacterOffset(node, -1)).toBeUndefined();\n expect(getNodeForCharacterOffset(node, 4)).toBeUndefined();\n });\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/getNodeForCharacterOffset-test\", module);\n", -"dom/__tests__/mutateHTMLNodeWithMarkup-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar getTestDocument = require(\"../../getTestDocument\");\n\nvar mutateHTMLNodeWithMarkup = require(\"../../mutateHTMLNodeWithMarkup\");\n\ndescribe('mutateHTMLNodeWithMarkup', function() {\n it('should mutate the document html', function() {\n var html = 'testtest';\n var testDocument = getTestDocument() || document;\n\n mutateHTMLNodeWithMarkup(testDocument.documentElement, html);\n expect(testDocument.body.innerHTML).toBe('test');\n });\n\n it('should change attributes', function() {\n var html = 'testtest';\n var testDocument = getTestDocument() || document;\n\n mutateHTMLNodeWithMarkup(testDocument.documentElement, html);\n expect(!!testDocument.documentElement.getAttribute('lang')).toBe(false);\n\n var html2 = 'test' +\n 'test';\n mutateHTMLNodeWithMarkup(testDocument.documentElement, html2);\n expect(testDocument.documentElement.getAttribute('lang')).toBe('en');\n\n mutateHTMLNodeWithMarkup(testDocument.documentElement, html);\n expect(!!testDocument.documentElement.getAttribute('lang')).toBe(false);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"dom/__tests__/mutateHTMLNodeWithMarkup-test\", module);\n", -"dom/components/__tests__/ReactDOMButton-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n/*jshint evil:true */\n\nvar mocks = require(\"../../../mocks\");\n\ndescribe('ReactDOMButton', function() {\n var React;\n var ReactTestUtils;\n\n var onClick = mocks.getMockFunction();\n\n function expectClickThru(button) {\n onClick.mockClear();\n ReactTestUtils.Simulate.click(button.getDOMNode());\n expect(onClick.mock.calls.length).toBe(1);\n }\n\n function expectNoClickThru(button) {\n onClick.mockClear();\n ReactTestUtils.Simulate.click(button.getDOMNode());\n expect(onClick.mock.calls.length).toBe(0);\n }\n\n function mounted(button) {\n ReactTestUtils.renderIntoDocument(button);\n return button;\n }\n\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactTestUtils = require(\"../../../ReactTestUtils\");\n });\n\n it('should forward clicks when it starts out not disabled', function() {\n expectClickThru(mounted(React.DOM.button( {onClick:onClick} )));\n });\n\n it('should not forward clicks when it starts out disabled', function() {\n expectNoClickThru(\n mounted(React.DOM.button( {disabled:true, onClick:onClick} ))\n );\n });\n\n it('should forward clicks when it becomes not disabled', function() {\n var btn = mounted(React.DOM.button( {disabled:true, onClick:onClick} ));\n btn.setProps({disabled: false});\n expectClickThru(btn);\n });\n\n it('should not forward clicks when it becomes disabled', function() {\n var btn = mounted(React.DOM.button( {onClick:onClick} ));\n btn.setProps({disabled: true});\n expectNoClickThru(btn);\n });\n\n it('should work correctly if the listener is changed', function() {\n var btn = mounted(\n React.DOM.button( {disabled:true, onClick:function() {}} )\n );\n\n btn.setProps({\n disabled: false,\n onClick: onClick\n });\n\n expectClickThru(btn);\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"dom/components/__tests__/ReactDOMButton-test\", module);\n", -"dom/components/__tests__/ReactDOMInput-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n/*jshint evil:true */\n\nvar emptyFunction = require(\"../../../emptyFunction\");\nvar mocks = require(\"../../../mocks\");\n\ndescribe('ReactDOMInput', function() {\n var React;\n var ReactLink;\n var ReactTestUtils;\n\n var renderTextInput;\n\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactLink = require(\"../../../ReactLink\");\n ReactTestUtils = require(\"../../../ReactTestUtils\");\n\n renderTextInput = function(component) {\n var stub = ReactTestUtils.renderIntoDocument(component);\n var node = stub.getDOMNode();\n return node;\n };\n });\n\n it('should display `defaultValue` of number 0', function() {\n var stub = React.DOM.input( {type:\"text\", defaultValue:0} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('0');\n });\n\n it('should display \"true\" for `defaultValue` of `true`', function() {\n var stub = React.DOM.input( {type:\"text\", defaultValue:true} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('true');\n });\n\n it('should display \"false\" for `defaultValue` of `false`', function() {\n var stub = React.DOM.input( {type:\"text\", defaultValue:false} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('false');\n });\n\n it('should display \"foobar\" for `defaultValue` of `objToString`', function() {\n var objToString = {\n toString: function() {\n return \"foobar\";\n }\n };\n\n var stub = React.DOM.input( {type:\"text\", defaultValue:objToString} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('foobar');\n });\n\n it('should display `value` of number 0', function() {\n var stub = React.DOM.input( {type:\"text\", value:0} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('0');\n });\n\n it('should allow setting `value` to `true`', function() {\n var stub = React.DOM.input( {type:\"text\", value:\"yolo\"} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('yolo');\n\n stub.replaceProps({value: true});\n expect(node.value).toEqual('true');\n });\n\n it(\"should allow setting `value` to `false`\", function() {\n var stub = React.DOM.input( {type:\"text\", value:\"yolo\"} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('yolo');\n\n stub.replaceProps({value: false});\n expect(node.value).toEqual('false');\n });\n\n it('should allow setting `value` to `objToString`', function() {\n var stub = React.DOM.input( {type:\"text\", value:\"foo\"} );\n var node = renderTextInput(stub);\n\n expect(node.value).toBe('foo');\n\n var objToString = {\n toString: function() {\n return \"foobar\";\n }\n };\n\n stub.replaceProps({value: objToString});\n expect(node.value).toEqual('foobar');\n });\n\n it('should properly control a value of number `0`', function() {\n var stub = React.DOM.input( {type:\"text\", value:0} );\n var node = renderTextInput(stub);\n\n node.value = 'giraffe';\n ReactTestUtils.Simulate.input(node);\n expect(node.value).toBe('0');\n });\n\n it('should control radio buttons', function() {\n var RadioGroup = React.createClass({displayName: 'RadioGroup',\n render: function() {\n return (\n React.DOM.div(null, \n React.DOM.input( {ref:\"a\", type:\"radio\", name:\"fruit\", checked:true} ),\"A \",\n React.DOM.input( {ref:\"b\", type:\"radio\", name:\"fruit\"} ),\"B \",\n React.DOM.form(null, \n React.DOM.input( {ref:\"c\", type:\"radio\", name:\"fruit\", defaultChecked:true} )\n )\n )\n );\n }\n });\n\n var stub = ReactTestUtils.renderIntoDocument(RadioGroup(null ));\n var aNode = stub.refs.a.getDOMNode();\n var bNode = stub.refs.b.getDOMNode();\n var cNode = stub.refs.c.getDOMNode();\n\n expect(aNode.checked).toBe(true);\n expect(bNode.checked).toBe(false);\n // c is in a separate form and shouldn't be affected at all here\n expect(cNode.checked).toBe(true);\n\n bNode.checked = true;\n // This next line isn't necessary in a proper browser environment, but\n // jsdom doesn't uncheck the others in a group (which makes this whole test\n // a little less effective)\n aNode.checked = false;\n expect(cNode.checked).toBe(true);\n\n // Now let's run the actual ReactDOMInput change event handler (on radio\n // inputs, ChangeEventPlugin listens for the `click` event so trigger that)\n ReactTestUtils.Simulate.click(bNode);\n\n // The original state should have been restored\n expect(aNode.checked).toBe(true);\n expect(cNode.checked).toBe(true);\n });\n\n it('should support ReactLink', function() {\n var container = document.createElement('div');\n var link = new ReactLink('yolo', mocks.getMockFunction());\n var instance = React.DOM.input( {type:\"text\", valueLink:link} );\n\n React.renderComponent(instance, container);\n\n expect(instance.getDOMNode().value).toBe('yolo');\n expect(link.value).toBe('yolo');\n expect(link.requestChange.mock.calls.length).toBe(0);\n\n instance.getDOMNode().value = 'test';\n ReactTestUtils.Simulate.input(instance.getDOMNode());\n\n expect(link.requestChange.mock.calls.length).toBe(1);\n expect(link.requestChange.mock.calls[0][0]).toEqual('test');\n });\n\n it('should throw if both value and valueLink are provided', function() {\n var node = document.createElement('div');\n var link = new ReactLink('yolo', mocks.getMockFunction());\n var instance = React.DOM.input( {type:\"text\", valueLink:link} );\n\n expect(React.renderComponent.bind(React, instance, node)).not.toThrow();\n\n instance = React.DOM.input( {type:\"text\", valueLink:link, value:\"test\"} );\n expect(React.renderComponent.bind(React, instance, node)).toThrow();\n\n instance = React.DOM.input( {type:\"text\", valueLink:link, onChange:emptyFunction} );\n expect(React.renderComponent.bind(React, instance, node)).toThrow();\n\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"dom/components/__tests__/ReactDOMInput-test\", module);\n", -"dom/components/__tests__/ReactDOMSelect-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n/*jshint evil:true */\n\nvar mocks = require(\"../../../mocks\");\n\ndescribe('ReactDOMSelect', function() {\n var React;\n var ReactLink;\n var ReactTestUtils;\n\n var renderSelect;\n\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactLink = require(\"../../../ReactLink\");\n ReactTestUtils = require(\"../../../ReactTestUtils\");\n\n renderSelect = function(component) {\n var stub = ReactTestUtils.renderIntoDocument(component);\n var node = stub.getDOMNode();\n return node;\n };\n });\n\n it('should allow setting `defaultValue`', function() {\n var stub =\n React.DOM.select( {defaultValue:\"giraffe\"}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.value).toBe('giraffe');\n\n // Changing `defaultValue` should do nothing.\n stub.setProps({defaultValue: 'gorilla'});\n expect(node.value).toEqual('giraffe');\n });\n\n it('should allow setting `defaultValue` with multiple', function() {\n var stub =\n React.DOM.select( {multiple:true, defaultValue:['giraffe', 'gorilla']}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(true); // gorilla\n\n // Changing `defaultValue` should do nothing.\n stub.setProps({defaultValue: ['monkey']});\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(true); // gorilla\n });\n\n it('should allow setting `value`', function() {\n var stub =\n React.DOM.select( {value:\"giraffe\"}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.value).toBe('giraffe');\n\n // Changing the `value` prop should change the selected option.\n stub.setProps({value: 'gorilla'});\n expect(node.value).toEqual('gorilla');\n });\n\n it('should allow setting `value` with multiple', function() {\n var stub =\n React.DOM.select( {multiple:true, value:['giraffe', 'gorilla']}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(true); // gorilla\n\n // Changing the `value` prop should change the selected options.\n stub.setProps({value: ['monkey']});\n\n expect(node.options[0].selected).toBe(true); // monkey\n expect(node.options[1].selected).toBe(false); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n });\n\n it('should allow setting `value` with `objectToString`', function() {\n var objectToString = {\n animal: \"giraffe\",\n toString: function() {\n return this.animal;\n }\n };\n\n var stub =\n React.DOM.select( {multiple:true, value:[objectToString]}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n\n // Changing the `value` prop should change the selected options.\n objectToString.animal = \"monkey\";\n stub.forceUpdate();\n\n expect(node.options[0].selected).toBe(true); // monkey\n expect(node.options[1].selected).toBe(false); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n });\n\n it('should allow switching to multiple', function() {\n var stub =\n React.DOM.select( {defaultValue:\"giraffe\"}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n\n // When making it multiple, giraffe should still be selected\n stub.setProps({multiple: true, defaultValue: null});\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n });\n\n it('should allow switching from multiple', function() {\n var stub =\n React.DOM.select( {multiple:true, defaultValue:['giraffe', 'gorilla']}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(true); // gorilla\n\n // When removing multiple, giraffe should still be selected (but gorilla\n // will no longer be)\n stub.setProps({multiple: false, defaultValue: null});\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n });\n\n it('should support ReactLink', function() {\n var link = new ReactLink('giraffe', mocks.getMockFunction());\n var stub =\n React.DOM.select( {valueLink:link}, \n React.DOM.option( {value:\"monkey\"}, \"A monkey!\"),\n React.DOM.option( {value:\"giraffe\"}, \"A giraffe!\"),\n React.DOM.option( {value:\"gorilla\"}, \"A gorilla!\")\n );\n var node = renderSelect(stub);\n\n expect(node.options[0].selected).toBe(false); // monkey\n expect(node.options[1].selected).toBe(true); // giraffe\n expect(node.options[2].selected).toBe(false); // gorilla\n expect(link.requestChange.mock.calls.length).toBe(0);\n\n node.options[1].selected = false;\n node.options[2].selected = true;\n ReactTestUtils.Simulate.change(node);\n\n expect(link.requestChange.mock.calls.length).toBe(1);\n expect(link.requestChange.mock.calls[0][0]).toEqual('gorilla');\n\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"dom/components/__tests__/ReactDOMSelect-test\", module);\n", -"dom/components/__tests__/ReactDOMTextarea-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\n/*jshint evil:true */\n\nvar mocks = require(\"../../../mocks\");\n\ndescribe('ReactDOMTextarea', function() {\n var React;\n var ReactLink;\n var ReactTestUtils;\n\n var renderTextarea;\n\n beforeEach(function() {\n React = require(\"../../../React\");\n ReactLink = require(\"../../../ReactLink\");\n ReactTestUtils = require(\"../../../ReactTestUtils\");\n\n renderTextarea = function(component) {\n var stub = ReactTestUtils.renderIntoDocument(component);\n var node = stub.getDOMNode();\n // Polyfilling the browser's quirky behavior.\n node.value = node.innerHTML;\n return node;\n };\n });\n\n it('should allow setting `defaultValue`', function() {\n var stub = React.DOM.textarea( {defaultValue:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n // Changing `defaultValue` should do nothing.\n stub.replaceProps({defaultValue: 'gorilla'});\n expect(node.value).toEqual('giraffe');\n });\n\n it('should display `defaultValue` of number 0', function() {\n var stub = React.DOM.textarea( {defaultValue:0} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('0');\n });\n\n it('should display \"false\" for `defaultValue` of `false`', function() {\n var stub = React.DOM.textarea( {type:\"text\", defaultValue:false} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('false');\n });\n\n it('should display \"foobar\" for `defaultValue` of `objToString`', function() {\n var objToString = {\n toString: function() {\n return \"foobar\";\n }\n };\n\n var stub = React.DOM.textarea( {type:\"text\", defaultValue:objToString} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('foobar');\n });\n\n it('should display `value` of number 0', function() {\n var stub = React.DOM.textarea( {value:0} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('0');\n });\n\n it('should allow setting `value` to `giraffe`', function() {\n var stub = React.DOM.textarea( {value:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n stub.replaceProps({value: 'gorilla'});\n expect(node.value).toEqual('gorilla');\n });\n\n it('should allow setting `value` to `true`', function() {\n var stub = React.DOM.textarea( {value:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n stub.replaceProps({value: true});\n expect(node.value).toEqual('true');\n });\n\n it('should allow setting `value` to `false`', function() {\n var stub = React.DOM.textarea( {value:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n stub.replaceProps({value: false});\n expect(node.value).toEqual('false');\n });\n\n it('should allow setting `value` to `objToString`', function() {\n var stub = React.DOM.textarea( {value:\"giraffe\"} );\n var node = renderTextarea(stub);\n\n expect(node.value).toBe('giraffe');\n\n var objToString = {\n toString: function() {\n return \"foo\";\n }\n };\n stub.replaceProps({value: objToString});\n expect(node.value).toEqual('foo');\n });\n\n it('should properly control a value of number `0`', function() {\n var stub = React.DOM.textarea( {value:0} );\n var node = renderTextarea(stub);\n\n node.value = 'giraffe';\n ReactTestUtils.Simulate.input(node);\n expect(node.value).toBe('0');\n });\n\n it('should treat children like `defaultValue`', function() {\n spyOn(console, 'warn');\n\n var stub = React.DOM.textarea(null, \"giraffe\");\n var node = renderTextarea(stub);\n\n expect(console.warn.argsForCall.length).toBe(1);\n expect(node.value).toBe('giraffe');\n\n // Changing children should do nothing, it functions like `defaultValue`.\n stub.replaceProps({children: 'gorilla'});\n expect(node.value).toEqual('giraffe');\n });\n\n it('should allow numbers as children', function() {\n spyOn(console, 'warn');\n var node = renderTextarea(React.DOM.textarea(null, 17));\n expect(console.warn.argsForCall.length).toBe(1);\n expect(node.value).toBe('17');\n });\n\n it('should allow booleans as children', function() {\n spyOn(console, 'warn');\n var node = renderTextarea(React.DOM.textarea(null, false));\n expect(console.warn.argsForCall.length).toBe(1);\n expect(node.value).toBe('false');\n });\n\n it('should allow objects as children', function() {\n spyOn(console, 'warn');\n var obj = {\n toString: function() {\n return \"sharkswithlasers\";\n }\n };\n var node = renderTextarea(React.DOM.textarea(null, obj));\n expect(console.warn.argsForCall.length).toBe(1);\n expect(node.value).toBe('sharkswithlasers');\n });\n\n it('should throw with multiple or invalid children', function() {\n spyOn(console, 'warn');\n\n expect(function() {\n ReactTestUtils.renderIntoDocument(\n React.DOM.textarea(null, 'hello','there')\n );\n }).toThrow();\n\n expect(console.warn.argsForCall.length).toBe(1);\n\n var stub;\n expect(function() {\n stub = renderTextarea(React.DOM.textarea(null, React.DOM.strong(null )));\n }).not.toThrow();\n\n expect(stub.value).toBe('[object Object]');\n\n expect(console.warn.argsForCall.length).toBe(2);\n });\n\n it('should support ReactLink', function() {\n var container = document.createElement('div');\n var link = new ReactLink('yolo', mocks.getMockFunction());\n var instance = React.DOM.textarea( {valueLink:link} );\n\n React.renderComponent(instance, container);\n\n expect(instance.getDOMNode().value).toBe('yolo');\n expect(link.value).toBe('yolo');\n expect(link.requestChange.mock.calls.length).toBe(0);\n\n instance.getDOMNode().value = 'test';\n ReactTestUtils.Simulate.input(instance.getDOMNode());\n\n expect(link.requestChange.mock.calls.length).toBe(1);\n expect(link.requestChange.mock.calls[0][0]).toEqual('test');\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"dom/components/__tests__/ReactDOMTextarea-test\", module);\n", -"environment/__tests__/ReactServerRendering-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\")\n .dontMock('ExecutionEnvironment')\n .dontMock('React')\n .dontMock('ReactMount')\n .dontMock('ReactServerRendering')\n .dontMock('ReactTestUtils')\n .dontMock('ReactMarkupChecksum');\n\nvar mocks = require(\"../../mocks\");\n\nvar React;\nvar ReactMount;\nvar ReactTestUtils;\nvar ReactServerRendering;\nvar ReactMarkupChecksum;\nvar ExecutionEnvironment;\n\ndescribe('ReactServerRendering', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n React = require(\"../../React\");\n ReactMount = require(\"../../ReactMount\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n ExecutionEnvironment = require(\"../../ExecutionEnvironment\");\n ExecutionEnvironment.canUseDOM = false;\n ReactServerRendering = require(\"../../ReactServerRendering\");\n ReactMarkupChecksum = require(\"../../ReactMarkupChecksum\");\n });\n\n it('should generate simple markup', function() {\n var response;\n ReactServerRendering.renderComponentToString(\n React.DOM.span(null, \"hello world\"),\n function(response_) {\n response = response_;\n }\n );\n expect(response).toMatch(\n 'hello world'\n );\n });\n\n it('should render composite components', function() {\n var Parent = React.createClass({displayName: 'Parent',\n render: function() {\n return React.DOM.div(null, Child( {name:\"child\"} ));\n }\n });\n var Child = React.createClass({displayName: 'Child',\n render: function() {\n return React.DOM.span(null, \"My name is \", this.props.name);\n }\n });\n var response;\n ReactServerRendering.renderComponentToString(\n Parent(null ),\n function(response_) {\n response = response_;\n }\n );\n expect(response).toMatch(\n '
' +\n '' +\n 'My name is ' +\n 'child' +\n '' +\n '
'\n );\n });\n\n it('should only execute certain lifecycle methods', function() {\n var lifecycle = [];\n var TestComponent = React.createClass({displayName: 'TestComponent',\n componentWillMount: function() {\n lifecycle.push('componentWillMount');\n },\n componentDidMount: function() {\n lifecycle.push('componentDidMount');\n },\n getInitialState: function() {\n lifecycle.push('getInitialState');\n return {name: 'TestComponent'};\n },\n render: function() {\n lifecycle.push('render');\n return React.DOM.span(null, \"Component name: \", this.state.name);\n },\n componentWillUpdate: function() {\n lifecycle.push('componentWillUpdate');\n },\n componentDidUpdate: function() {\n lifecycle.push('componentDidUpdate');\n },\n shouldComponentUpdate: function() {\n lifecycle.push('shouldComponentUpdate');\n },\n componentWillReceiveProps: function() {\n lifecycle.push('componentWillReceiveProps');\n },\n componentWillUnmount: function() {\n lifecycle.push('componentWillUnmount');\n }\n });\n\n var response;\n\n ReactServerRendering.renderComponentToString(\n TestComponent(null ),\n function (_response) {\n response = _response;\n }\n );\n\n expect(response).toMatch(\n '' +\n 'Component name: ' +\n 'TestComponent' +\n ''\n );\n expect(lifecycle).toEqual(\n ['getInitialState', 'componentWillMount', 'render']\n );\n });\n\n it('should have the correct mounting behavior', function() {\n // This test is testing client-side behavior.\n ExecutionEnvironment.canUseDOM = true;\n\n var mountCount = 0;\n var numClicks = 0;\n\n var TestComponent = React.createClass({displayName: 'TestComponent',\n componentDidMount: function() {\n mountCount++;\n },\n click: function() {\n numClicks++;\n },\n render: function() {\n return (\n React.DOM.span( {ref:\"span\", onClick:this.click}, \"Name: \", this.props.name)\n );\n }\n });\n\n var element = document.createElement('div');\n React.renderComponent(TestComponent(null ), element);\n\n var lastMarkup = element.innerHTML;\n\n // Exercise the update path. Markup should not change,\n // but some lifecycle methods should be run again.\n React.renderComponent(TestComponent( {name:\"x\"} ), element);\n expect(mountCount).toEqual(1);\n\n // Unmount and remount. We should get another mount event and\n // we should get different markup, as the IDs are unique each time.\n React.unmountComponentAtNode(element);\n expect(element.innerHTML).toEqual('');\n React.renderComponent(TestComponent( {name:\"x\"} ), element);\n expect(mountCount).toEqual(2);\n expect(element.innerHTML).not.toEqual(lastMarkup);\n\n // Now kill the node and render it on top of server-rendered markup, as if\n // we used server rendering. We should mount again, but the markup should be\n // unchanged. We will append a sentinel at the end of innerHTML to be sure\n // that innerHTML was not changed.\n React.unmountComponentAtNode(element);\n expect(element.innerHTML).toEqual('');\n\n ExecutionEnvironment.canUseDOM = false;\n ReactServerRendering.renderComponentToString(\n TestComponent( {name:\"x\"} ),\n function(markup) {\n lastMarkup = markup;\n }\n );\n ExecutionEnvironment.canUseDOM = true;\n\n element.innerHTML = lastMarkup + ' __sentinel__';\n\n React.renderComponent(TestComponent( {name:\"x\"} ), element);\n expect(mountCount).toEqual(3);\n expect(element.innerHTML.indexOf('__sentinel__') > -1).toBe(true);\n React.unmountComponentAtNode(element);\n expect(element.innerHTML).toEqual('');\n\n // Now simulate a situation where the app is not idempotent. React should\n // warn but do the right thing.\n var _warn = console.warn;\n console.warn = mocks.getMockFunction();\n element.innerHTML = lastMarkup;\n var instance = React.renderComponent(TestComponent( {name:\"y\"} ), element);\n expect(mountCount).toEqual(4);\n expect(console.warn.mock.calls.length).toBe(1);\n expect(element.innerHTML.length > 0).toBe(true);\n expect(element.innerHTML).not.toEqual(lastMarkup);\n console.warn = _warn;\n\n // Ensure the events system works\n expect(numClicks).toEqual(0);\n ReactTestUtils.Simulate.click(instance.refs.span.getDOMNode());\n expect(numClicks).toEqual(1);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"environment/__tests__/ReactServerRendering-test\", module);\n", -"environment/__tests__/ReactWebWorker-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\ndescribe('ReactWebWorker', function() {\n ;(typeof Worker == 'undefined' ? xit : it)('can run React in a web worker', function() {\n var done = false;\n var error;\n\n var worker = new Worker(window.ReactWebWorker_URL || '/src/test/worker.js?_=' + Date.now().toString(36));\n worker.addEventListener('message', function(e) {\n var data = JSON.parse(e.data);\n if (data.type == 'error') {\n error = data.message + \"\\n\" + data.stack;\n } else {\n expect(data.type).toBe('done');\n done = true;\n }\n });\n\n waitsFor(function() {\n return done;\n });\n runs(function() {\n if (error) {\n console.log(error);\n throw new Error(error);\n }\n });\n });\n});\n\nrequire(\"../../mock-modules\").register(\"environment/__tests__/ReactWebWorker-test\", module);\n", -"event/__tests__/EventPluginRegistry-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar merge = require(\"../../merge\");\n\ndescribe('EventPluginRegistry', function() {\n var EventPluginRegistry;\n var createPlugin;\n\n beforeEach(function() {\n EventPluginRegistry = require(\"../../EventPluginRegistry\");\n EventPluginRegistry._resetEventPlugins();\n\n createPlugin = function(properties) {\n return merge({extractEvents: function() {}}, properties);\n };\n });\n\n it('should be able to inject ordering before plugins', function() {\n var OnePlugin = createPlugin();\n var TwoPlugin = createPlugin();\n var ThreePlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n two: TwoPlugin\n });\n EventPluginRegistry.injectEventPluginsByName({\n three: ThreePlugin\n });\n\n expect(EventPluginRegistry.plugins.length).toBe(3);\n expect(EventPluginRegistry.plugins[0]).toBe(OnePlugin);\n expect(EventPluginRegistry.plugins[1]).toBe(TwoPlugin);\n expect(EventPluginRegistry.plugins[2]).toBe(ThreePlugin);\n });\n\n it('should be able to inject plugins before and after ordering', function() {\n var OnePlugin = createPlugin();\n var TwoPlugin = createPlugin();\n var ThreePlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n two: TwoPlugin\n });\n EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);\n EventPluginRegistry.injectEventPluginsByName({\n three: ThreePlugin\n });\n\n expect(EventPluginRegistry.plugins.length).toBe(3);\n expect(EventPluginRegistry.plugins[0]).toBe(OnePlugin);\n expect(EventPluginRegistry.plugins[1]).toBe(TwoPlugin);\n expect(EventPluginRegistry.plugins[2]).toBe(ThreePlugin);\n });\n\n it('should be able to inject repeated plugins and out-of-order', function() {\n var OnePlugin = createPlugin();\n var TwoPlugin = createPlugin();\n var ThreePlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n three: ThreePlugin\n });\n EventPluginRegistry.injectEventPluginOrder(['one', 'two', 'three']);\n EventPluginRegistry.injectEventPluginsByName({\n two: TwoPlugin,\n three: ThreePlugin\n });\n\n expect(EventPluginRegistry.plugins.length).toBe(3);\n expect(EventPluginRegistry.plugins[0]).toBe(OnePlugin);\n expect(EventPluginRegistry.plugins[1]).toBe(TwoPlugin);\n expect(EventPluginRegistry.plugins[2]).toBe(ThreePlugin);\n });\n\n it('should throw if plugin does not implement `extractEvents`', function() {\n var BadPlugin = {};\n\n EventPluginRegistry.injectEventPluginOrder(['bad']);\n\n expect(function() {\n EventPluginRegistry.injectEventPluginsByName({\n bad: BadPlugin\n });\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Event plugins must ' +\n 'implement an `extractEvents` method, but `bad` does not.'\n );\n });\n\n it('should throw if plugin does not exist in ordering', function() {\n var OnePlugin = createPlugin();\n var RandomPlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginOrder(['one']);\n\n expect(function() {\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n random: RandomPlugin\n });\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Cannot inject event plugins ' +\n 'that do not exist in the plugin ordering, `random`.'\n );\n });\n\n it('should throw if ordering is injected more than once', function() {\n var pluginOrdering = [];\n\n EventPluginRegistry.injectEventPluginOrder(pluginOrdering);\n\n expect(function() {\n EventPluginRegistry.injectEventPluginOrder(pluginOrdering);\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Cannot inject event plugin ' +\n 'ordering more than once.'\n );\n });\n\n it('should throw if different plugins injected using same name', function() {\n var OnePlugin = createPlugin();\n var TwoPlugin = createPlugin();\n\n EventPluginRegistry.injectEventPluginsByName({same: OnePlugin});\n\n expect(function() {\n EventPluginRegistry.injectEventPluginsByName({same: TwoPlugin});\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Cannot inject two different ' +\n 'event plugins using the same name, `same`.'\n );\n });\n\n it('should publish registration names of injected plugins', function() {\n var OnePlugin = createPlugin({\n eventTypes: {\n click: {registrationName: 'onClick'},\n focus: {registrationName: 'onFocus'}\n }\n });\n var TwoPlugin = createPlugin({\n eventTypes: {\n magic: {\n phasedRegistrationNames: {\n bubbled: 'onMagicBubble',\n captured: 'onMagicCapture'\n }\n }\n }\n });\n\n EventPluginRegistry.injectEventPluginsByName({one: OnePlugin});\n EventPluginRegistry.injectEventPluginOrder(['one', 'two']);\n\n expect(EventPluginRegistry.registrationNamesKeys.length).toBe(2);\n expect(EventPluginRegistry.registrationNames.onClick).toBe(OnePlugin);\n expect(EventPluginRegistry.registrationNames.onFocus).toBe(OnePlugin);\n\n EventPluginRegistry.injectEventPluginsByName({two: TwoPlugin});\n\n expect(EventPluginRegistry.registrationNamesKeys.length).toBe(4);\n expect(EventPluginRegistry.registrationNames.onMagicBubble).toBe(TwoPlugin);\n expect(\n EventPluginRegistry.registrationNames.onMagicCapture\n ).toBe(TwoPlugin);\n });\n\n it('should throw if multiple registration names collide', function() {\n var OnePlugin = createPlugin({\n eventTypes: {\n photoCapture: {registrationName: 'onPhotoCapture'}\n }\n });\n var TwoPlugin = createPlugin({\n eventTypes: {\n photo: {\n phasedRegistrationNames: {\n bubbled: 'onPhotoBubble',\n captured: 'onPhotoCapture'\n }\n }\n }\n });\n\n EventPluginRegistry.injectEventPluginsByName({\n one: OnePlugin,\n two: TwoPlugin\n });\n\n expect(function() {\n EventPluginRegistry.injectEventPluginOrder(['one', 'two']);\n }).toThrow(\n 'Invariant Violation: EventPluginHub: More than one plugin attempted ' +\n 'to publish the same registration name, `onPhotoCapture`.'\n );\n });\n\n it('should throw if an invalid event is published', function() {\n var OnePlugin = createPlugin({\n eventTypes: {\n badEvent: {/* missing configuration */}\n }\n });\n\n EventPluginRegistry.injectEventPluginsByName({one: OnePlugin});\n\n expect(function() {\n EventPluginRegistry.injectEventPluginOrder(['one']);\n }).toThrow(\n 'Invariant Violation: EventPluginRegistry: Failed to publish event ' +\n '`badEvent` for plugin `one`.'\n );\n });\n\n it('should be able to get the plugin from synthetic events', function() {\n var clickDispatchConfig = {\n registrationName: 'onClick'\n };\n var magicDispatchConfig = {\n phasedRegistrationNames: {\n bubbled: 'onMagicBubble',\n captured: 'onMagicCapture'\n }\n };\n\n var OnePlugin = createPlugin({\n eventTypes: {\n click: clickDispatchConfig,\n magic: magicDispatchConfig\n }\n });\n\n var clickEvent = {dispatchConfig: clickDispatchConfig};\n var magicEvent = {dispatchConfig: magicDispatchConfig};\n\n expect(EventPluginRegistry.getPluginModuleForEvent(clickEvent)).toBe(null);\n expect(EventPluginRegistry.getPluginModuleForEvent(magicEvent)).toBe(null);\n\n EventPluginRegistry.injectEventPluginsByName({one: OnePlugin});\n EventPluginRegistry.injectEventPluginOrder(['one']);\n\n expect(\n EventPluginRegistry.getPluginModuleForEvent(clickEvent)\n ).toBe(OnePlugin);\n expect(\n EventPluginRegistry.getPluginModuleForEvent(magicEvent)\n ).toBe(OnePlugin);\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"event/__tests__/EventPluginRegistry-test\", module);\n", -"event/synthetic/__tests__/SyntheticEvent-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar SyntheticEvent;\n\ndescribe('SyntheticEvent', function() {\n var createEvent;\n\n beforeEach(function() {\n SyntheticEvent = require(\"../../../SyntheticEvent\");\n\n createEvent = function(nativeEvent) {\n return SyntheticEvent.getPooled({}, '', nativeEvent);\n };\n });\n\n it('should normalize `target` from the nativeEvent', function() {\n var target = document.createElement('div');\n var syntheticEvent = createEvent({srcElement: target});\n\n expect(syntheticEvent.target).toBe(target);\n expect(syntheticEvent.type).toBe(undefined);\n });\n\n it('should be able to `preventDefault`', function() {\n var nativeEvent = {};\n var syntheticEvent = createEvent(nativeEvent);\n\n expect(syntheticEvent.isDefaultPrevented()).toBe(false);\n syntheticEvent.preventDefault();\n expect(syntheticEvent.isDefaultPrevented()).toBe(true);\n\n expect(syntheticEvent.defaultPrevented).toBe(true);\n\n expect(nativeEvent.returnValue).toBe(false);\n });\n\n it('should be prevented if nativeEvent is prevented', function() {\n expect(\n createEvent({defaultPrevented: true}).isDefaultPrevented()\n ).toBe(true);\n expect(createEvent({returnValue: false}).isDefaultPrevented()).toBe(true);\n });\n\n it('should be able to `stopPropagation`', function() {\n var nativeEvent = {};\n var syntheticEvent = createEvent(nativeEvent);\n\n expect(syntheticEvent.isPropagationStopped()).toBe(false);\n syntheticEvent.stopPropagation();\n expect(syntheticEvent.isPropagationStopped()).toBe(true);\n\n expect(nativeEvent.cancelBubble).toBe(true);\n });\n\n it('should be able to `persist`', function() {\n var syntheticEvent = createEvent({});\n\n expect(syntheticEvent.isPersistent()).toBe(false);\n syntheticEvent.persist();\n expect(syntheticEvent.isPersistent()).toBe(true);\n });\n\n});\n\nrequire(\"../../../mock-modules\").register(\"event/synthetic/__tests__/SyntheticEvent-test\", module);\n", -"event/synthetic/__tests__/SyntheticWheelEvent-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar SyntheticWheelEvent;\n\ndescribe('SyntheticWheelEvent', function() {\n var createEvent;\n\n beforeEach(function() {\n SyntheticWheelEvent = require(\"../../../SyntheticWheelEvent\");\n\n createEvent = function(nativeEvent) {\n return SyntheticWheelEvent.getPooled({}, '', nativeEvent);\n };\n });\n\n it('should normalize properties from the Event interface', function() {\n var target = document.createElement('div');\n var syntheticEvent = createEvent({srcElement: target});\n\n expect(syntheticEvent.target).toBe(target);\n expect(syntheticEvent.type).toBe(undefined);\n });\n\n it('should normalize properties from the MouseEvent interface', function() {\n expect(createEvent({which: 2, button: 1}).button).toBe(1);\n });\n\n it('should normalize properties from the WheelEvent interface', function() {\n var standardEvent = createEvent({deltaX: 10, deltaY: -50});\n expect(standardEvent.deltaX).toBe(10);\n expect(standardEvent.deltaY).toBe(50);\n\n var webkitEvent = createEvent({wheelDeltaX: -10, wheelDeltaY: 50});\n expect(webkitEvent.deltaX).toBe(10);\n expect(webkitEvent.deltaY).toBe(50);\n });\n\n it('should be able to `preventDefault` and `stopPropagation`', function() {\n var nativeEvent = {};\n var syntheticEvent = createEvent(nativeEvent);\n\n expect(syntheticEvent.isDefaultPrevented()).toBe(false);\n syntheticEvent.preventDefault();\n expect(syntheticEvent.isDefaultPrevented()).toBe(true);\n\n expect(syntheticEvent.isPropagationStopped()).toBe(false);\n syntheticEvent.stopPropagation();\n expect(syntheticEvent.isPropagationStopped()).toBe(true);\n });\n\n it('should be able to `persist`', function() {\n var syntheticEvent = createEvent({});\n\n expect(syntheticEvent.isPersistent()).toBe(false);\n syntheticEvent.persist();\n expect(syntheticEvent.isPersistent()).toBe(true);\n });\n\n});\n\nrequire(\"../../../mock-modules\").register(\"event/synthetic/__tests__/SyntheticWheelEvent-test\", module);\n", -"eventPlugins/__tests__/AnalyticsEventPlugin-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @jsx React.DOM\n * @emails react-core\n */\n\n\"use strict\";\n\nvar mocks = require(\"../../mocks\");\n\ndescribe('AnalyticsEventPlugin', function() {\n var AnalyticsEventPluginFactory;\n var EventPluginHub;\n var EventPluginRegistry;\n var React;\n var ReactEventEmitter;\n var ReactTestUtils;\n\n var DefaultEventPluginOrder;\n var EnterLeaveEventPlugin;\n var ChangeEventPlugin;\n var ReactInstanceHandles;\n var SimpleEventPlugin;\n\n beforeEach(function() {\n AnalyticsEventPluginFactory = require(\"../../AnalyticsEventPluginFactory\");\n EventPluginHub = require(\"../../EventPluginHub\");\n EventPluginRegistry = require(\"../../EventPluginRegistry\");\n React = require(\"../../React\");\n ReactEventEmitter = require(\"../../ReactEventEmitter\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n\n EventPluginRegistry._resetEventPlugins();\n\n // Re-inject default events system after resetting.\n DefaultEventPluginOrder = require(\"../../DefaultEventPluginOrder\");\n EnterLeaveEventPlugin = require(\"../../EnterLeaveEventPlugin\");\n ChangeEventPlugin = require(\"../../ChangeEventPlugin\");\n ReactInstanceHandles = require(\"../../ReactInstanceHandles\");\n SimpleEventPlugin = require(\"../../SimpleEventPlugin\");\n\n EventPluginHub.injection.injectEventPluginOrder(DefaultEventPluginOrder);\n EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles);\n\n EventPluginHub.injection.injectEventPluginsByName({\n 'SimpleEventPlugin': SimpleEventPlugin,\n 'EnterLeaveEventPlugin': EnterLeaveEventPlugin,\n 'ChangeEventPlugin': ChangeEventPlugin\n });\n\n ReactEventEmitter.ensureListening(false, document);\n });\n\n it('should count events correctly', function() {\n var numClickEvents = 5;\n var numDoubleClickEvents = 7;\n var TEST_ANALYTICS_ID = 'test_analytics_id';\n var TestValidEvents = React.createClass({displayName: 'TestValidEvents',\n render: function() {\n return (\n React.DOM.div( {ref:\"testDiv\",\n 'data-analytics-id':TEST_ANALYTICS_ID,\n 'data-analytics-events':\"click,doubleClick\"}, \n \" Test \"\n )\n );\n }\n });\n var renderedComponent =\n ReactTestUtils.renderIntoDocument(TestValidEvents(null ));\n\n var cb = mocks.getMockFunction().mockImplementation(\n function(analyticsData) {\n expect(Object.keys(analyticsData).length).toBe(1);\n expect(Object.keys(analyticsData[TEST_ANALYTICS_ID]).length).toBe(2);\n expect(analyticsData[TEST_ANALYTICS_ID].click).toBe(numClickEvents);\n expect(analyticsData[TEST_ANALYTICS_ID].doubleClick).toBe(\n numDoubleClickEvents\n );\n }\n );\n\n EventPluginHub.injection.injectEventPluginsByName({\n AnalyticsEventPlugin:\n AnalyticsEventPluginFactory.createAnalyticsPlugin(cb)\n });\n\n // Simulate some clicks\n for (var i = 0; i < numClickEvents; i++) {\n ReactTestUtils.Simulate.click(renderedComponent.refs.testDiv);\n }\n // Simulate some double clicks\n for (i = 0; i < numDoubleClickEvents; i++) {\n ReactTestUtils.Simulate.doubleClick(renderedComponent.refs.testDiv);\n }\n // Simulate some other events not being tracked for analytics\n ReactTestUtils.Simulate.focus(renderedComponent.refs.testDiv);\n\n window.mockRunTimersOnce();\n expect(cb).toBeCalled();\n });\n\n it('error non no callback', function() {\n expect(function() {\n AnalyticsEventPluginFactory.createAnalyticsPlugin(null);\n }).toThrow();\n });\n\n it('error on invalid analytics events', function() {\n var TestInvalidEvents = React.createClass({displayName: 'TestInvalidEvents',\n render: function() {\n return (\n React.DOM.div( {ref:\"testDiv\",\n 'data-analytics-id':\"test_invalid_events\",\n 'data-analytics-events':\"click,123\"}, \n \" Test \"\n )\n );\n }\n });\n var renderedComponent =\n ReactTestUtils.renderIntoDocument(TestInvalidEvents(null ));\n\n var cb = mocks.getMockFunction();\n\n EventPluginHub.injection.injectEventPluginsByName({\n AnalyticsEventPlugin: AnalyticsEventPluginFactory.createAnalyticsPlugin(\n cb\n )\n });\n\n var error = false;\n try {\n ReactTestUtils.Simulate.click(renderedComponent.refs.testDiv);\n } catch(e) {\n error = true;\n }\n\n expect(error).toBe(true);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"eventPlugins/__tests__/AnalyticsEventPlugin-test\", module);\n", -"eventPlugins/__tests__/ResponderEventPlugin-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar CallbackRegistry;\nvar EventConstants;\nvar EventPropagators;\nvar ReactInstanceHandles;\nvar ResponderEventPlugin;\nvar SyntheticEvent;\n\nvar GRANDPARENT_ID = '.r[0]';\nvar PARENT_ID = '.r[0].0';\nvar CHILD_ID = '.r[0].0.0';\n\nvar topLevelTypes;\nvar responderEventTypes;\nvar spies;\n\nvar DUMMY_NATIVE_EVENT = {};\nvar DUMMY_RENDERED_TARGET = {};\n\nvar onStartShouldSetResponder = function(id, cb, capture) {\n var registrationNames = responderEventTypes\n .startShouldSetResponder\n .phasedRegistrationNames;\n CallbackRegistry.putListener(\n id,\n capture ? registrationNames.captured : registrationNames.bubbled,\n cb\n );\n};\n\nvar onScrollShouldSetResponder = function(id, cb, capture) {\n var registrationNames = responderEventTypes\n .scrollShouldSetResponder\n .phasedRegistrationNames;\n CallbackRegistry.putListener(\n id,\n capture ? registrationNames.captured : registrationNames.bubbled,\n cb\n );\n};\n\nvar onMoveShouldSetResponder = function(id, cb, capture) {\n var registrationNames = responderEventTypes\n .moveShouldSetResponder\n .phasedRegistrationNames;\n CallbackRegistry.putListener(\n id,\n capture ? registrationNames.captured : registrationNames.bubbled,\n cb\n );\n};\n\n\nvar onResponderGrant = function(id, cb) {\n CallbackRegistry.putListener(\n id,\n responderEventTypes.responderGrant.registrationName,\n cb\n );\n};\n\nvar extractForTouchStart = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topTouchStart,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForTouchMove = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topTouchMove,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForTouchEnd = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topTouchEnd,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForMouseDown = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topMouseDown,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForMouseMove = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topMouseMove,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\n\nvar extractForMouseUp = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topMouseUp,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\nvar extractForScroll = function(renderedTargetID) {\n return ResponderEventPlugin.extractEvents(\n topLevelTypes.topScroll,\n DUMMY_NATIVE_EVENT,\n renderedTargetID,\n DUMMY_RENDERED_TARGET\n );\n};\n\n\nvar onGrantChild;\nvar onGrantParent;\nvar onGrantGrandParent;\n\n\nvar existsInExtraction = function(extracted, test) {\n if (Array.isArray(extracted)) {\n for (var i = 0; i < extracted.length; i++) {\n if (test(extracted[i])) {\n return true;\n }\n }\n } else if (extracted) {\n return test(extracted);\n }\n return false;\n};\n\n/**\n * Helper validators.\n */\nfunction assertGrantEvent(id, extracted) {\n var test = function(event) {\n return event instanceof SyntheticEvent &&\n event.dispatchConfig === responderEventTypes.responderGrant &&\n event.dispatchMarker === id;\n };\n expect(ResponderEventPlugin.getResponderID()).toBe(id);\n expect(existsInExtraction(extracted, test)).toBe(true);\n}\n\nfunction assertResponderMoveEvent(id, extracted) {\n var test = function(event) {\n return event instanceof SyntheticEvent &&\n event.dispatchConfig === responderEventTypes.responderMove &&\n event.dispatchMarker === id;\n };\n expect(ResponderEventPlugin.getResponderID()).toBe(id);\n expect(existsInExtraction(extracted, test)).toBe(true);\n}\n\nfunction assertTerminateEvent(id, extracted) {\n var test = function(event) {\n return event instanceof SyntheticEvent &&\n event.dispatchConfig === responderEventTypes.responderTerminate &&\n event.dispatchMarker === id;\n };\n expect(ResponderEventPlugin.getResponderID()).not.toBe(id);\n expect(existsInExtraction(extracted, test)).toBe(true);\n}\n\nfunction assertRelease(id, extracted) {\n var test = function(event) {\n return event instanceof SyntheticEvent &&\n event.dispatchConfig === responderEventTypes.responderRelease &&\n event.dispatchMarker === id;\n };\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n expect(existsInExtraction(extracted, test)).toBe(true);\n}\n\n\nfunction assertNothingExtracted(extracted) {\n expect(Array.isArray(extracted)).toBe(false); // No grant events.\n expect(Array.isArray(extracted)).toBeFalsy();\n}\n\n\n/**\n * TODO:\n * - Test that returning false from `responderTerminationRequest` will never\n * cause the responder to be lost.\n * - Automate some of this testing by providing config data - generalize.\n */\n\ndescribe('ResponderEventPlugin', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n\n CallbackRegistry = require(\"../../CallbackRegistry\");\n EventConstants = require(\"../../EventConstants\");\n EventPropagators = require(\"../../EventPropagators\");\n ReactInstanceHandles = require(\"../../ReactInstanceHandles\");\n ResponderEventPlugin = require(\"../../ResponderEventPlugin\");\n SyntheticEvent = require(\"../../SyntheticEvent\");\n EventPropagators.injection.injectInstanceHandle(ReactInstanceHandles);\n\n // dumpCache, in open-source tests, only resets existing mocks. It does not\n // reset module-state though -- so we need to do this explicitly in the test\n // for now. Once that's no longer the case, we can delete this line.\n CallbackRegistry.__purge();\n\n topLevelTypes = EventConstants.topLevelTypes;\n responderEventTypes = ResponderEventPlugin.eventTypes;\n\n spies = {\n onStartShouldSetResponderChild: function() {},\n onStartShouldSetResponderParent: function() {},\n onStartShouldSetResponderParentCapture: function() {},\n onStartShouldSetResponderGrandParent: function() {},\n onMoveShouldSetResponderParent: function() {},\n onScrollShouldSetResponderParent: function() {}\n };\n\n onGrantChild = function() {};\n onGrantParent = function() {};\n onGrantGrandParent = function() {};\n });\n\n it('should not auto-set responder on touch start', function() {\n // Notice we're not registering the startShould* handler.\n var extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n });\n\n it('should not auto-set responder on mouse down', function() {\n // Notice we're not registering the startShould* handler.\n var extracted = extractForMouseDown(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n extractForMouseUp(CHILD_ID); // Let up!\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n\n // Register `onMoveShould*` handler.\n spyOn(spies, 'onMoveShouldSetResponderParent').andReturn(true);\n onMoveShouldSetResponder(PARENT_ID, spies.onMoveShouldSetResponderParent);\n onResponderGrant(PARENT_ID, onGrantParent);\n // Move mouse while not pressing down\n extracted = extractForMouseMove(CHILD_ID);\n assertNothingExtracted(extracted);\n // Not going to call `onMoveShould`* if not touching.\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(0);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n\n // Now try the move extraction again, this time while holding down, and not\n // letting up.\n extracted = extractForMouseDown(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n\n // Now moving can set the responder, if pressing down, even if there is no\n // current responder.\n extracted = extractForMouseMove(CHILD_ID);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(1);\n expect(ResponderEventPlugin.getResponderID()).toBe(PARENT_ID);\n assertGrantEvent(PARENT_ID, extracted);\n\n extractForMouseUp(CHILD_ID);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n });\n\n it('should not extract a grant/release event if double start', function() {\n // Return true - we should become the responder.\n var extracted;\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onResponderGrant(CHILD_ID, onGrantChild);\n\n extracted = extractForTouchStart(CHILD_ID);\n assertGrantEvent(CHILD_ID, extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n\n // Now we do *not* clear out the touch via a simulated touch end. This mocks\n // out an environment that likely will never happen, but could in some odd\n // error state so it's nice to make sure we recover gracefully.\n // extractForTouchEnd(CHILD_ID); // Clear the responder\n extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted();\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(2);\n });\n\n it('should bubble/capture responder on start', function() {\n // Return true - we should become the responder.\n var extracted;\n spyOn(spies, 'onStartShouldSetResponderParent').andReturn(true);\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onStartShouldSetResponder(PARENT_ID, spies.onStartShouldSetResponderParent);\n onResponderGrant(CHILD_ID, onGrantChild);\n onResponderGrant(PARENT_ID, onGrantParent);\n\n // Nothing extracted if no responder.\n extracted = extractForTouchMove(GRANDPARENT_ID);\n assertNothingExtracted(extracted);\n\n extracted = extractForTouchStart(CHILD_ID);\n assertGrantEvent(CHILD_ID, extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(spies.onStartShouldSetResponderParent.callCount).toBe(0);\n\n // Even if moving on the grandparent, the child will receive responder moves\n // (This is even true for mouse interactions - which we should absolutely\n // test)\n extracted = extractForTouchMove(GRANDPARENT_ID);\n assertResponderMoveEvent(CHILD_ID, extracted);\n extracted = extractForTouchMove(CHILD_ID); // Test move on child node too.\n assertResponderMoveEvent(CHILD_ID, extracted);\n\n // Reset the responder - id passed here shouldn't matter:\n // TODO: Test varying the id here.\n extracted = extractForTouchEnd(GRANDPARENT_ID); // Clear the responder\n assertRelease(CHILD_ID, extracted);\n\n // Now make sure the parent requests responder on capture.\n spyOn(spies, 'onStartShouldSetResponderParentCapture').andReturn(true);\n onStartShouldSetResponder(\n PARENT_ID,\n spies.onStartShouldSetResponderParent,\n true // Capture\n );\n onResponderGrant(PARENT_ID, onGrantGrandParent);\n extracted = extractForTouchStart(PARENT_ID);\n expect(ResponderEventPlugin.getResponderID()).toBe(PARENT_ID);\n assertGrantEvent(PARENT_ID, extracted);\n // Now move on various nodes, ensuring that the responder move is emitted to\n // the parent node.\n extracted = extractForTouchMove(GRANDPARENT_ID);\n assertResponderMoveEvent(PARENT_ID, extracted);\n extracted = extractForTouchMove(CHILD_ID); // Test move on child node too.\n assertResponderMoveEvent(PARENT_ID, extracted);\n\n // Reset the responder - id passed here shouldn't matter:\n // TODO: Test varying the id here.\n extracted = extractForTouchEnd(GRANDPARENT_ID); // Clear the responder\n assertRelease(PARENT_ID, extracted);\n\n });\n\n it('should invoke callback to ask if responder is desired', function() {\n // Return true - we should become the responder.\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n\n var extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(ResponderEventPlugin.getResponderID()).toBe(CHILD_ID);\n extractForTouchEnd(CHILD_ID); // Clear the responder\n\n // Now try returning false - we should not become the responder.\n spies.onStartShouldSetResponderChild.andReturn(false);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(2);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n extractForTouchEnd(CHILD_ID);\n expect(ResponderEventPlugin.getResponderID()).toBe(null); // Still null\n\n // Same thing as before but return true from \"shouldSet\".\n spies.onStartShouldSetResponderChild.andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onResponderGrant(CHILD_ID, onGrantChild);\n extracted = extractForTouchStart(CHILD_ID);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(3);\n assertGrantEvent(CHILD_ID, extracted);\n extracted = extractForTouchEnd(CHILD_ID); // Clear the responder\n assertRelease(CHILD_ID, extracted);\n });\n\n it('should give up responder to parent on move iff allowed', function() {\n // Return true - we should become the responder.\n var extracted;\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n spyOn(spies, 'onMoveShouldSetResponderParent').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onMoveShouldSetResponder(PARENT_ID, spies.onMoveShouldSetResponderParent);\n onResponderGrant(CHILD_ID, onGrantChild);\n onResponderGrant(PARENT_ID, onGrantParent);\n\n spies.onStartShouldSetResponderChild.andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n extracted = extractForTouchStart(CHILD_ID);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(0); // none yet\n assertGrantEvent(CHILD_ID, extracted); // Child is the current responder\n\n extracted = extractForTouchMove(CHILD_ID);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(1);\n assertGrantEvent(PARENT_ID, extracted);\n assertTerminateEvent(CHILD_ID, extracted);\n\n extracted = extractForTouchEnd(CHILD_ID); // Clear the responder\n assertRelease(PARENT_ID, extracted);\n });\n\n it('should responder move only on direct responder', function() {\n // Return true - we should become the responder.\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n\n var extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(ResponderEventPlugin.getResponderID()).toBe(CHILD_ID);\n extractForTouchEnd(CHILD_ID); // Clear the responder\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n\n // Now try returning false - we should not become the responder.\n spies.onStartShouldSetResponderChild.andReturn(false);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n extracted = extractForTouchStart(CHILD_ID);\n assertNothingExtracted(extracted);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(2);\n expect(ResponderEventPlugin.getResponderID()).toBe(null);\n extractForTouchEnd(CHILD_ID); // Clear the responder\n\n // Same thing as before but return true from \"shouldSet\".\n spies.onStartShouldSetResponderChild.andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onResponderGrant(CHILD_ID, onGrantChild);\n extracted = extractForTouchStart(CHILD_ID);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(3);\n assertGrantEvent(CHILD_ID, extracted);\n extracted = extractForTouchEnd(CHILD_ID); // Clear the responder\n assertRelease(CHILD_ID, extracted);\n });\n\n it('should give up responder to parent on scroll iff allowed', function() {\n // Return true - we should become the responder.\n var extracted;\n spyOn(spies, 'onStartShouldSetResponderChild').andReturn(true);\n spyOn(spies, 'onMoveShouldSetResponderParent').andReturn(false);\n spyOn(spies, 'onScrollShouldSetResponderParent').andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n onMoveShouldSetResponder(PARENT_ID, spies.onMoveShouldSetResponderParent);\n onScrollShouldSetResponder(\n PARENT_ID,\n spies.onScrollShouldSetResponderParent\n );\n onResponderGrant(CHILD_ID, onGrantChild);\n onResponderGrant(PARENT_ID, onGrantParent);\n\n spies.onStartShouldSetResponderChild.andReturn(true);\n onStartShouldSetResponder(CHILD_ID, spies.onStartShouldSetResponderChild);\n extracted = extractForTouchStart(CHILD_ID);\n expect(spies.onStartShouldSetResponderChild.callCount).toBe(1);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(0); // none yet\n assertGrantEvent(CHILD_ID, extracted); // Child is the current responder\n\n extracted = extractForTouchMove(CHILD_ID);\n expect(spies.onMoveShouldSetResponderParent.callCount).toBe(1);\n assertNothingExtracted(extracted);\n\n extracted = extractForScroll(CHILD_ID); // Could have been parent here too.\n expect(spies.onScrollShouldSetResponderParent.callCount).toBe(1);\n assertGrantEvent(PARENT_ID, extracted);\n assertTerminateEvent(CHILD_ID, extracted);\n\n extracted = extractForTouchEnd(CHILD_ID); // Clear the responder\n assertRelease(PARENT_ID, extracted);\n });\n\n\n});\n\nrequire(\"../../mock-modules\").register(\"eventPlugins/__tests__/ResponderEventPlugin-test\", module);\n", -"utils/__tests__/ImmutableObject-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\")\n .dontMock('ImmutableObject');\n\nvar ImmutableObject;\n\n/**\n * To perform performance testing of using `ImmutableObject` vs. not using\n * `ImmutableObject`, such testing must be done with __DEV__ set to false.\n */\ndescribe('ImmutableObject', function() {\n var message;\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n ImmutableObject = require(\"../../ImmutableObject\");\n this.addMatchers({\n /**\n * Equivalent with respect to serialization. Must stringify because\n * constructors are different and other comparison methods will not\n * consider them structurally equal. Probably not useful for use outside\n * of this test module.\n */\n toBeSeriallyEqualTo: function(expected) {\n var actual = this.actual;\n var notText = this.isNot ? \" not\" : \"\";\n this.message = function () {\n return \"Expected \" + JSON.stringify(actual) + notText +\n \" to be serially equal to \" + JSON.stringify(expected);\n };\n\n return JSON.stringify(actual) === JSON.stringify(expected);\n }\n });\n });\n\n /**\n * We are in __DEV__ by default.\n */\n var testDev = function(message, testFunc) {\n it(message, testFunc);\n };\n\n var testProd = function(message, testFunc) {\n // Temporarily enter production mode\n window.true = false;\n it(message, testFunc);\n window.true = true;\n };\n\n var testDevAndProd = function(message, testFunc) {\n testDev(message + ':DEV', testFunc);\n testProd(message + ':PROD', testFunc);\n };\n\n testDev('should be running in DEV', function() {\n expect(window.true).toBe(true);\n });\n\n testDev('should require initial map to be an object', function() {\n expect(function() {\n new ImmutableObject([1,2,3]);\n }).toThrow();\n\n expect(function() {\n new ImmutableObject('asdf');\n }).toThrow();\n\n expect(function() {\n new ImmutableObject({oldField: 'asdf', fieldTwo: null});\n }).not.toThrow();\n });\n\n testDev('should not exceed maximum call stack size with nodes', function() {\n var node = document.createElement('div');\n var object = new ImmutableObject({node: node});\n expect(object.node).toBe(node);\n });\n\n testDevAndProd('should not throw when not mutating directly', function() {\n var io = new ImmutableObject({oldField: 'asdf'});\n expect(function() {\n ImmutableObject.set(io, {newField: null}); // not a mutation!\n }).not.toThrow();\n });\n\n testDev('should prevent shallow field addition when strict', function() {\n if (window.callPhantom) return;\n expect(function() {\n var io = new ImmutableObject({oldField: 'asdf'});\n io.newField = 'this will not work';\n }).toThrow();\n });\n\n testDev('should prevent shallow field mutation when strict', function() {\n if (window.callPhantom) return;\n expect(function() {\n var io = new ImmutableObject({oldField: 'asdf'});\n io.oldField = 'this will not work!';\n }).toThrow();\n });\n\n testDev('should prevent deep field addition when strict', function() {\n if (window.callPhantom) return;\n expect(function() {\n var io =\n new ImmutableObject({shallowField: {deepField: {oldField: null}}});\n io.shallowField.deepField.oldField = 'this will not work!';\n }).toThrow();\n });\n\n testDev('should prevent deep field mutation when strict', function() {\n if (window.callPhantom) return;\n expect(function() {\n var io =\n new ImmutableObject({shallowField: {deepField: {oldField: null}}});\n io.shallowField.deepField.newField = 'this will not work!';\n }).toThrow();\n });\n\n testDevAndProd(\n 'should create object with same structure when set with {}',\n function() {\n var beforeIO =\n new ImmutableObject({shallowField: {deepField: {oldField: null}}});\n var afterIO = ImmutableObject.set(beforeIO, {});\n expect(afterIO).toBeSeriallyEqualTo(beforeIO);\n expect(afterIO).not.toBe(beforeIO);\n }\n );\n\n testDevAndProd(\n 'should create distinct object with shallow field insertion',\n function() {\n var beforeStructure = {\n oldShallowField: {\n deepField: {\n oldField: null\n }\n }\n };\n\n var delta = {\n newShallowField: 'newShallowFieldHere'\n };\n\n var expectedAfterStructure = {\n oldShallowField: {\n deepField: {\n oldField: null\n }\n },\n newShallowField: 'newShallowFieldHere'\n };\n\n var beforeIO = new ImmutableObject(beforeStructure);\n var afterIO = ImmutableObject.set(beforeIO, delta);\n expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);\n expect(afterIO).not.toBe(beforeIO);\n }\n );\n\n testDevAndProd(\n 'should create distinct object with shallow field mutation',\n function() {\n var beforeStructure = {\n oldShallowField: {\n deepField: {\n oldField: null\n }\n }\n };\n\n var delta = {\n oldShallowField: 'this will clobber the old field'\n };\n\n var expectedAfterStructure = {\n oldShallowField: 'this will clobber the old field'\n };\n\n var beforeIO = new ImmutableObject(beforeStructure);\n var afterIO = ImmutableObject.set(beforeIO, delta);\n expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);\n expect(afterIO).not.toBe(beforeIO);\n }\n );\n\n message = 'should create distinct object with deep field insertion';\n testDevAndProd(message, function() {\n var beforeStructure = {\n oldShallowField: {\n deepField: {\n oldField: null\n }\n }\n };\n\n var delta = {\n oldShallowField: {newDeepField: 'hello'}\n };\n\n // ImmutableObject does not yet support deep merging with\n // ImmutableObject.set().\n var expectedAfterStructure = {\n oldShallowField: {newDeepField: 'hello'}\n };\n\n var beforeIO = new ImmutableObject(beforeStructure);\n var afterIO = ImmutableObject.set(beforeIO, delta);\n expect(afterIO).toBeSeriallyEqualTo(expectedAfterStructure);\n expect(afterIO).not.toBe(beforeIO);\n });\n\n message =\n 'should tolerate arrays at deeper levels and prevent mutation on them';\n testDevAndProd(message, function() {\n if (window.callPhantom) {\n // PhantomJS has a bug with Object.freeze and Arrays.\n // https://github.com/ariya/phantomjs/issues/10817\n return;\n }\n var beforeStructure = {\n shallowField: [1,'second field',3]\n };\n var io = new ImmutableObject(beforeStructure);\n expect(function() {\n io.newField = 'nope!';\n }).toThrow();\n expect(function() {\n io.shallowField[0] = 'nope!';\n }).toThrow();\n expect(io.shallowField[1]).toEqual('second field');\n });\n\n message = 'should provide a setField interface as sugar for set()';\n testDevAndProd(message, function() {\n var beforeIO = new ImmutableObject({initialField: null});\n var afterIO =\n ImmutableObject.setField(beforeIO, 'anotherField', 'anotherValue');\n expect(afterIO).toBeSeriallyEqualTo({\n initialField: null,\n anotherField: 'anotherValue'\n });\n expect(afterIO).not.toBe(beforeIO);\n });\n\n message = 'should recursively create distinct objects when deep copying';\n testDevAndProd(message, function() {\n var beforeIO = new ImmutableObject({\n a: {b: 'b', c: {}, d: 'd', e: new ImmutableObject({f: 'f'}) }\n });\n var afterIO = ImmutableObject.setDeep(beforeIO, {\n a: {b: {}, c: 'C', e: {f: 'F', g: 'G'}, h: 'H'}\n });\n expect(afterIO).toBeSeriallyEqualTo({\n a: {b: {}, c: 'C', d: 'd', e: {f: 'F', g: 'G'}, h: 'H'}\n });\n expect(afterIO).not.toBe(beforeIO);\n expect(afterIO.a).not.toBe(beforeIO.a);\n expect(afterIO.a.e).not.toBe(beforeIO.a.e);\n });\n\n testDevAndProd('should deep copy member immutability', function() {\n var beforeIO = new ImmutableObject({\n a: {b: new ImmutableObject({c: 'c'}), e: {f: 'f'}}\n });\n var afterIO = ImmutableObject.setDeep(beforeIO, {\n a: {b: {d: 'D'}, e: new ImmutableObject({g: 'G'})}\n });\n expect(afterIO).toBeSeriallyEqualTo({\n a: {b: {c: 'c', d: 'D'}, e: {f: 'f', g: 'G'}}\n });\n expect(afterIO instanceof ImmutableObject).toBe(true);\n expect(afterIO.a.b instanceof ImmutableObject).toBe(true);\n expect(afterIO.a.e instanceof ImmutableObject).toBe(true);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/ImmutableObject-test\", module);\n", -"utils/__tests__/OrderedMap-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar OrderedMap;\n\n/**\n * Shared, reusable objects.\n */\nvar hasEmptyStringKey = {\n 'thisKeyIsFine': {data: []},\n '': {thisShouldCauseAFailure: []},\n 'thisKeyIsAlsoFine': {data: []}\n};\n\n/**\n * Used as map/forEach callback.\n */\nvar duplicate = function(itm, key, count) {\n return {\n uniqueID: itm.uniqueID,\n val: itm.val + key + count + this.justToTestScope\n };\n};\n\n// Should not be allowed - because then null/'null' become impossible to\n// distinguish. Every key MUST be a string period!\nvar hasNullAndUndefStringKey = [\n {uniqueID: 'undefined', val: 'thisIsUndefined'},\n {uniqueID: 'null', val: 'thisIsNull'}\n];\nvar hasNullKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: null, data: []}\n];\n\nvar hasObjectKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: {}, data: []}\n];\n\nvar hasArrayKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: [], data: []}\n];\n\n// This should be allowed\nvar hasNullStringKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: 'null', data: []}\n];\n\nvar hasUndefinedKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: undefined, data: []}\n];\n\nvar hasUndefinedStringKey = [\n {uniqueID: 'thisKeyIsFine', data: []},\n {uniqueID: 'thisKeyIsAlsoFine', data: []},\n {uniqueID: 'undefined', data: []}\n];\n\nvar hasPositiveNumericKey = [\n {uniqueID: 'notANumber', data: []},\n {uniqueID: '5', data: []},\n {uniqueID: 'notAnotherNumber',data: []}\n];\n\nvar hasZeroStringKey = [\n {uniqueID: 'greg', data: 'grego'},\n {uniqueID: '0', data: '0o'},\n {uniqueID: 'tom', data: 'tomo'}\n];\n\nvar hasZeroNumberKey = [\n {uniqueID: 'greg', data: 'grego'},\n {uniqueID: 0, data: '0o'},\n {uniqueID: 'tom', data: 'tomo'}\n];\n\nvar hasAllNumericStringKeys = [\n {uniqueID: '0', name: 'Gregory'},\n {uniqueID: '2', name: 'James'},\n {uniqueID: '1', name: 'Tom'}\n];\n\nvar hasAllNumericKeys = [\n {uniqueID: 0, name: 'Gregory'},\n {uniqueID: 2, name: 'James'},\n {uniqueID: 1, name: 'Tom'}\n];\n\nvar hasAllValidKeys = [\n {uniqueID: 'keyOne', value: 'valueOne'},\n {uniqueID: 'keyTwo', value: 'valueTwo'}\n];\n\nvar hasDuplicateKeys = [\n {uniqueID: 'keyOne', value: 'valueOne'},\n {uniqueID: 'keyTwo', value: 'valueTwo'},\n {uniqueID: 'keyOne', value: 'valueThree'}\n];\n\nvar idEntities = [\n {uniqueID: 'greg', name: 'Gregory'},\n {uniqueID: 'james', name: 'James'},\n {uniqueID: 'tom', name: 'Tom'}\n];\n\nvar hasEmptyKey = [\n {uniqueID: 'greg', name: 'Gregory'},\n {uniqueID: '', name: 'James'},\n {uniqueID: 'tom', name: 'Tom'}\n];\n\nvar extractUniqueID = function(entity) {\n return entity.uniqueID;\n};\n\ndescribe('OrderedMap', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n OrderedMap = require(\"../../OrderedMap\");\n });\n\n it('should create according to simple object with keys', function() {\n OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);\n // Iterate over and ensure key order.\n });\n\n it('should create from array when providing an identity CB', function() {\n expect(function() {\n OrderedMap.fromArray(idEntities, extractUniqueID);\n }).not.toThrow();\n });\n\n it('should throw if constructing from Array without identity CB', function() {\n OrderedMap.fromArray(idEntities, extractUniqueID);\n // Iterate and ensure key order\n });\n\n it('should not throw when fromArray extracts a numeric key', function() {\n expect(function() {\n OrderedMap.fromArray(hasPositiveNumericKey, extractUniqueID);\n }).not.toThrow();\n\n });\n\n it('should throw when any key is the empty string', function() {\n expect(function() {\n OrderedMap.fromArray(hasEmptyKey, extractUniqueID);\n }).toThrow();\n });\n\n it('should not throw when a key is the string \"undefined\" or \"null\"',\n function() {\n var om = OrderedMap.fromArray(hasNullAndUndefStringKey, extractUniqueID);\n expect(om.length).toBe(2);\n expect(om.indexOfKey('undefined')).toBe(0);\n expect(om.indexOfKey('null')).toBe(1);\n expect(om.keyAfter('undefined')).toBe('null');\n expect(om.keyAfter('null')).toBe(undefined);\n expect(om.keyBefore('undefined')).toBe(undefined);\n expect(om.has('undefined')).toBe(true);\n expect(om.has('null')).toBe(true);\n expect(om.get('undefined').val).toBe('thisIsUndefined');\n expect(om.get('null').val).toBe('thisIsNull');\n });\n\n\n /**\n * Numeric keys are cast to strings.\n */\n it('should not throw when a key is the number zero', function() {\n var om = OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID);\n expect(om.length).toBe(3);\n expect(om.indexOfKey('0')).toBe(1);\n expect(om.indexOfKey(0)).toBe(1);\n });\n\n it('should throw when any key is falsey', function() {\n expect(function() {\n OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasNullKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasUndefinedKey, extractUniqueID);\n }).toThrow();\n });\n\n it('should not throw on string keys \"undefined/null\"', function() {\n expect(function() {\n OrderedMap.fromArray(hasNullStringKey, extractUniqueID);\n }).not.toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasUndefinedStringKey, extractUniqueID);\n }).not.toThrow();\n });\n\n it('should throw on extracting keys that are not strings/nums', function() {\n expect(function() {\n OrderedMap.fromArray(hasObjectKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasArrayKey, extractUniqueID);\n }).toThrow();\n });\n\n it('should throw if instantiating with duplicate key', function() {\n expect(function() {\n OrderedMap.fromArray(hasDuplicateKeys, extractUniqueID);\n }).toThrow();\n });\n\n it('should not throw when a key is the string \"0\"', function() {\n var verifyOM = function(om) {\n expect(om.length).toBe(3);\n expect(om.indexOfKey('greg')).toBe(0);\n expect(om.indexOfKey('0')).toBe(1);\n expect(om.indexOfKey(0)).toBe(1); // Casts on writes and reads.\n expect(om.indexOfKey('tom')).toBe(2);\n expect(om.keyAfter('greg')).toBe('0');\n expect(om.keyAfter('0')).toBe('tom');\n expect(om.keyAfter(0)).toBe('tom');\n expect(om.keyAfter('tom')).toBe(undefined);\n expect(om.keyBefore('greg')).toBe(undefined);\n expect(om.keyBefore(0)).toBe('greg');\n expect(om.keyBefore('0')).toBe('greg');\n expect(om.keyBefore('tom')).toBe('0');\n expect(om.has('undefined')).toBe(false);\n expect(om.has(0)).toBe(true);\n expect(om.has('0')).toBe(true);\n };\n var om = OrderedMap.fromArray(hasZeroStringKey, extractUniqueID);\n verifyOM(om);\n om = OrderedMap.fromArray(hasZeroNumberKey, extractUniqueID);\n verifyOM(om);\n });\n\n it('should throw when getting invalid public key', function() {\n var om = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);\n expect(function() {\n om.has(undefined);\n }).toThrow();\n expect(function() {\n om.get(undefined);\n }).toThrow();\n expect(function() {\n om.has(null);\n }).toThrow();\n expect(function() {\n om.get(null);\n }).toThrow();\n expect(function() {\n om.has('');\n }).toThrow();\n expect(function() {\n om.get('');\n }).toThrow();\n });\n\n it('should throw when any key is falsey', function() {\n expect(function() {\n OrderedMap.fromArray(hasEmptyStringKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasNullKey, extractUniqueID);\n }).toThrow();\n\n expect(function() {\n OrderedMap.fromArray(hasUndefinedKey, extractUniqueID);\n }).toThrow();\n });\n\n\n it('should throw when fromArray is passed crazy args', function() {\n // Test passing another OrderedMap (when it expects a plain object.)\n // This is probably not what you meant to do! We should error.\n var validOM = OrderedMap.fromArray(hasAllValidKeys, extractUniqueID);\n expect(function() {\n OrderedMap.fromArray({uniqueID: 'asdf'}, extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray(validOM, extractUniqueID);\n }).toThrow();\n });\n\n it('should throw when fromArray is passed crazy things', function() {\n expect(function() {\n OrderedMap.fromArray(null, extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray('stringgg', extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray(undefined, extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray(new Date(), extractUniqueID);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray({}, extractUniqueID);\n }).toThrow();\n\n // Test failure without extractor\n expect(function() {\n OrderedMap.fromArray(idEntities);\n }).toThrow();\n expect(function() {\n OrderedMap.fromArray(idEntities, extractUniqueID);\n }).not.toThrow();\n });\n\n // Testing methods that accept other `OrderedMap`s.\n it('should throw when from/merge is passed an non-OrderedMap.', function() {\n // Test passing an array to construction.\n expect(function() {\n OrderedMap.from(idEntities, extractUniqueID);\n }).toThrow();\n\n // Test passing an array to merge.\n expect(function() {\n OrderedMap.fromArray(idEntities, extractUniqueID)\n .merge(idEntities, extractUniqueID);\n }).toThrow();\n\n\n // Test passing a plain object to merge.\n expect(function() {\n OrderedMap.fromArray(\n idEntities,\n extractUniqueID\n ).merge({blah: 'willFail'});\n }).toThrow();\n });\n\n it('should throw when accessing key before/after of non-key', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'first'},\n {uniqueID: 'two'}], extractUniqueID\n );\n expect(function() {\n om.keyBefore('dog');\n }).toThrow();\n expect(function() {\n om.keyAfter('cat');\n }).toThrow();\n expect(function() {\n om.keyAfter(null);\n }).toThrow();\n expect(function() {\n om.keyAfter(undefined);\n }).toThrow();\n });\n\n it('should throw passing invalid/not-present-keys to before/after',\n function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'},\n {uniqueID: 'three', val: 'third'},\n {uniqueID: 'four', val: 'fourth'}\n ], extractUniqueID);\n\n expect(function() {\n om.keyBefore('');\n }).toThrow();\n expect(function() {\n om.keyBefore(null);\n }).toThrow();\n expect(function() {\n om.keyBefore(undefined);\n }).toThrow();\n expect(function() {\n om.keyBefore('notInTheOrderedMap!');\n }).toThrow();\n\n expect(function() {\n om.keyAfter('');\n }).toThrow();\n expect(function() {\n om.keyAfter(null);\n }).toThrow();\n expect(function() {\n om.keyAfter(undefined);\n }).toThrow();\n expect(function() {\n om.keyAfter('notInTheOrderedMap!');\n }).toThrow();\n\n expect(function() {\n om.nthKeyAfter('', 1);\n }).toThrow();\n expect(function() {\n om.nthKeyAfter(null, 1);\n }).toThrow();\n expect(function() {\n om.nthKeyAfter(undefined, 1);\n }).toThrow();\n expect(function() {\n om.nthKeyAfter('notInTheOrderedMap!', 1);\n }).toThrow();\n\n expect(function() {\n om.nthKeyBefore('', 1);\n }).toThrow();\n expect(function() {\n om.nthKeyBefore(null, 1);\n }).toThrow();\n expect(function() {\n om.nthKeyBefore(undefined, 1);\n }).toThrow();\n expect(function() {\n om.nthKeyBefore('notInTheOrderedMap!', 1);\n }).toThrow();\n });\n\n it('should correctly determine the nth key after before', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'},\n {uniqueID: 'three', val: 'third'},\n {uniqueID: 'four', val: 'fourth'}\n ], extractUniqueID);\n expect(om.keyBefore('one')).toBe(undefined); // first key\n expect(om.keyBefore('two')).toBe('one');\n expect(om.keyBefore('three')).toBe('two');\n expect(om.keyBefore('four')).toBe('three');\n\n expect(om.keyAfter('one')).toBe('two'); // first key\n expect(om.keyAfter('two')).toBe('three');\n expect(om.keyAfter('three')).toBe('four');\n expect(om.keyAfter('four')).toBe(undefined);\n\n expect(om.nthKeyBefore('one', 0)).toBe('one'); // first key\n expect(om.nthKeyBefore('one', 1)).toBe(undefined);\n expect(om.nthKeyBefore('one', 2)).toBe(undefined);\n expect(om.nthKeyBefore('two', 0)).toBe('two');\n expect(om.nthKeyBefore('two', 1)).toBe('one');\n expect(om.nthKeyBefore('four', 0)).toBe('four');\n expect(om.nthKeyBefore('four', 1)).toBe('three');\n\n expect(om.nthKeyAfter('one', 0)).toBe('one');\n expect(om.nthKeyAfter('one', 1)).toBe('two');\n expect(om.nthKeyAfter('one', 2)).toBe('three');\n expect(om.nthKeyAfter('two', 0)).toBe('two');\n expect(om.nthKeyAfter('two', 1)).toBe('three');\n expect(om.nthKeyAfter('four', 0)).toBe('four');\n expect(om.nthKeyAfter('four', 1)).toBe(undefined);\n });\n\n it('should compute key indices correctly', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'}\n ], extractUniqueID);\n expect(om.keyAtIndex(0)).toBe('one');\n expect(om.keyAtIndex(1)).toBe('two');\n expect(om.keyAtIndex(2)).toBe(undefined);\n expect(om.indexOfKey('one')).toBe(0);\n expect(om.indexOfKey('two')).toBe(1);\n expect(om.indexOfKey('nope')).toBe(undefined);\n expect(function() {\n om.indexOfKey(null);\n }).toThrow();\n expect(function() {\n om.indexOfKey(undefined);\n }).toThrow();\n expect(function() {\n om.indexOfKey(''); // Empty key is not allowed\n }).toThrow();\n });\n\n it('should compute indices on array that extracted numeric ids', function() {\n var om = OrderedMap.fromArray(hasZeroStringKey, extractUniqueID);\n expect(om.keyAtIndex(0)).toBe('greg');\n expect(om.keyAtIndex(1)).toBe('0');\n expect(om.keyAtIndex(2)).toBe('tom');\n expect(om.indexOfKey('greg')).toBe(0);\n expect(om.indexOfKey('0')).toBe(1);\n expect(om.indexOfKey('tom')).toBe(2);\n\n\n var verifyNumericKeys = function(om) {\n expect(om.keyAtIndex(0)).toBe('0');\n expect(om.keyAtIndex(1)).toBe('2');\n expect(om.keyAtIndex(2)).toBe('1');\n expect(om.indexOfKey('0')).toBe(0);\n expect(om.indexOfKey('2')).toBe(1); // Proove these are not ordered by\n expect(om.indexOfKey('1')).toBe(2); // their keys\n };\n var omStringNumberKeys =\n OrderedMap.fromArray(hasAllNumericStringKeys, extractUniqueID);\n verifyNumericKeys(omStringNumberKeys);\n var omNumericKeys =\n OrderedMap.fromArray(hasAllNumericKeys, extractUniqueID);\n verifyNumericKeys(omNumericKeys);\n });\n\n it('should compute indices on mutually exclusive merge', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'}\n ], extractUniqueID);\n var om2 = OrderedMap.fromArray([\n {uniqueID: 'three', val: 'third'}\n ], extractUniqueID);\n var res = om.merge(om2);\n\n expect(res.length).toBe(3);\n\n expect(res.keyAtIndex(0)).toBe('one');\n expect(res.keyAtIndex(1)).toBe('two');\n expect(res.keyAtIndex(2)).toBe('three');\n expect(res.keyAtIndex(3)).toBe(undefined);\n\n expect(res.indexOfKey('one')).toBe(0);\n expect(res.indexOfKey('two')).toBe(1);\n expect(res.indexOfKey('three')).toBe(2);\n expect(res.indexOfKey('dog')).toBe(undefined);\n\n expect(res.has('one')).toBe(true);\n expect(res.has('two')).toBe(true);\n expect(res.has('three')).toBe(true);\n expect(res.has('dog')).toBe(false);\n\n expect(res.get('one').val).toBe('first');\n expect(res.get('two').val).toBe('second');\n expect(res.get('three').val).toBe('third');\n expect(res.get('dog')).toBe(undefined);\n });\n\n it('should compute indices on intersected merge', function() {\n var oneTwo = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'secondOM1'}\n ], extractUniqueID);\n\n var testOneTwoMergedWithTwoThree = function(res) {\n expect(res.length).toBe(3);\n expect(res.keyAtIndex(0)).toBe('one');\n expect(res.keyAtIndex(1)).toBe('two');\n expect(res.keyAtIndex(2)).toBe('three');\n expect(res.keyAtIndex(3)).toBe(undefined);\n expect(res.indexOfKey('one')).toBe(0);\n expect(res.indexOfKey('two')).toBe(1);\n expect(res.indexOfKey('three')).toBe(2);\n expect(res.indexOfKey('dog')).toBe(undefined);\n expect(res.has('one')).toBe(true);\n expect(res.has('two')).toBe(true);\n expect(res.has('three')).toBe(true);\n expect(res.has('dog')).toBe(false);\n expect(res.get('one').val).toBe('first');\n expect(res.get('two').val).toBe('secondOM2');\n expect(res.get('three').val).toBe('third');\n expect(res.get('dog')).toBe(undefined);\n };\n\n var result =\n oneTwo.merge(OrderedMap.fromArray([\n {uniqueID: 'two', val: 'secondOM2'},\n {uniqueID: 'three', val: 'third'}\n ], extractUniqueID));\n testOneTwoMergedWithTwoThree(result);\n\n // Everything should be exactly as before, since the ordering of `two` was\n // already determined by `om`.\n result = oneTwo.merge(\n OrderedMap.fromArray([\n {uniqueID: 'three', val: 'third'},\n {uniqueID: 'two', val:'secondOM2'}\n ], extractUniqueID)\n );\n testOneTwoMergedWithTwoThree(result);\n\n\n var testTwoThreeMergedWithOneTwo = function(res) {\n expect(res.length).toBe(3);\n expect(res.keyAtIndex(0)).toBe('two');\n expect(res.keyAtIndex(1)).toBe('three');\n expect(res.keyAtIndex(2)).toBe('one');\n expect(res.keyAtIndex(3)).toBe(undefined);\n expect(res.indexOfKey('two')).toBe(0);\n expect(res.indexOfKey('three')).toBe(1);\n expect(res.indexOfKey('one')).toBe(2);\n expect(res.indexOfKey('cat')).toBe(undefined);\n expect(res.has('two')).toBe(true);\n expect(res.has('three')).toBe(true);\n expect(res.has('one')).toBe(true);\n expect(res.has('dog')).toBe(false);\n expect(res.get('one').val).toBe('first');\n expect(res.get('two').val).toBe('secondOM1');\n expect(res.get('three').val).toBe('third');\n expect(res.get('dog')).toBe(undefined);\n };\n result = OrderedMap.fromArray([\n {uniqueID: 'two', val: 'secondOM2'},\n {uniqueID: 'three', val: 'third'}\n ], extractUniqueID).merge(oneTwo);\n testTwoThreeMergedWithOneTwo(result);\n\n });\n\n it('should merge mutually exclusive keys to the end.', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'one', val: 'first'},\n {uniqueID: 'two', val: 'second'}\n ], extractUniqueID);\n var om2 = OrderedMap.fromArray([\n {uniqueID: 'three', val: 'first'},\n {uniqueID: 'four', val: 'second'}\n ], extractUniqueID);\n var res = om.merge(om2);\n expect(res.length).toBe(4);\n\n });\n\n it('should map correctly', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ], extractUniqueID);\n var scope = {justToTestScope: 'justTestingScope'};\n var verifyResult = function(omResult) {\n expect(omResult.length).toBe(3);\n expect(omResult.keyAtIndex(0)).toBe('x');\n expect(omResult.keyAtIndex(1)).toBe('y');\n expect(omResult.keyAtIndex(2)).toBe('z');\n expect(omResult.get('x').val).toBe('xxx0justTestingScope');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n expect(omResult.get('z').val).toBe('zzz2justTestingScope');\n };\n var resultOM = om.map(function(itm, key, count) {\n return {\n uniqueID: itm.uniqueID,\n val: itm.val + key + count + this.justToTestScope\n };\n }, scope);\n verifyResult(resultOM);\n\n var resArray = [];\n om.forEach(function(itm, key, count) {\n resArray.push({\n uniqueID: itm.uniqueID,\n val: itm.val + key + count + this.justToTestScope\n });\n }, scope);\n resultOM = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyResult(resultOM);\n });\n\n it('should filter correctly', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ], extractUniqueID);\n var scope = {justToTestScope: 'justTestingScope'};\n\n var filteringCallback = function(item, key, indexInOriginal) {\n expect(this).toBe(scope);\n expect(key === 'x' || key === 'y' || key === 'z').toBe(true);\n if (key === 'x') {\n expect(item.val).toBe('xx');\n expect(indexInOriginal).toBe(0);\n return false;\n } else if (key === 'y') {\n expect(item.val).toBe('yy');\n expect(indexInOriginal).toBe(1);\n return true;\n } else {\n expect(item.val).toBe('zz');\n expect(indexInOriginal).toBe(2);\n return true;\n }\n };\n\n var verifyResult = function(omResult) {\n expect(omResult.length).toBe(2);\n expect(omResult.keyAtIndex(0)).toBe('y');\n expect(omResult.keyAtIndex(1)).toBe('z');\n expect(omResult.has('x')).toBe(false);\n expect(omResult.has('z')).toBe(true);\n expect(omResult.get('z').val).toBe('zz');\n expect(omResult.has('y')).toBe(true);\n expect(omResult.get('y').val).toBe('yy');\n };\n\n var resultOM = om.filter(filteringCallback, scope);\n verifyResult(resultOM);\n });\n\n it('should throw when providing invalid ranges to ranging', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ], extractUniqueID);\n var scope = {justToTestScope: 'justTestingScope'};\n\n expect(function() {\n om.mapRange(duplicate, 0, 3, scope);\n }).not.toThrow();\n expect(function() {\n om.filterRange(duplicate, 0, 3, scope);\n }).not.toThrow();\n expect(function() {\n om.forEachRange(duplicate, 0, 3, scope);\n }).not.toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'x' , 3, scope);\n }).toThrow(\n 'Invariant Violation: mapKeyRange must be given keys ' +\n 'that are present.'\n );\n expect(function() {\n om.forEachKeyRange(duplicate, 'x', 3, scope);\n }).toThrow(\n 'Invariant Violation: forEachKeyRange must be given keys ' +\n 'that are present.'\n );\n\n expect(function() {\n om.mapRange(duplicate, 0, 4, scope);\n }).toThrow();\n expect(function() {\n om.filterRange(duplicate, 0, 4, scope);\n }).toThrow();\n expect(function() {\n om.forEachRange(duplicate, 0, 4, scope);\n }).toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'x', null, scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'x', null, scope);\n }).toThrow();\n\n expect(function() {\n om.mapRange(duplicate, -1, 1, scope);\n }).toThrow();\n expect(function() {\n om.filterRange(duplicate, -1, 1, scope);\n }).toThrow();\n expect(function() {\n om.forEachRange(duplicate, -1, 1, scope);\n }).toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, null, 'y', scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, null, 'y', scope);\n }).toThrow();\n\n expect(function() {\n om.mapRange(duplicate, 0, 0, scope);\n }).not.toThrow();\n expect(function() {\n om.filterRange(duplicate, 0, 0, scope);\n }).not.toThrow();\n expect(function() {\n om.forEachRange(duplicate, 0, 0, scope);\n }).not.toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'x', 'x', scope);\n }).not.toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'x', 'x', scope);\n }).not.toThrow();\n\n expect(function() {\n om.mapRange(duplicate, 0, -1, scope);\n }).toThrow();\n expect(function() {\n om.filterRange(duplicate, 0, -1, scope);\n }).toThrow();\n expect(function() {\n om.forEachRange(duplicate, 0, -1, scope);\n }).toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'x', null, scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'x', null, scope);\n }).toThrow();\n\n expect(function() {\n om.mapRange(duplicate, 2, 1, scope);\n }).not.toThrow();\n expect(function() {\n om.filterRange(duplicate, 2, 1, scope);\n }).not.toThrow();\n expect(function() {\n om.forEachRange(duplicate, 2, 1, scope);\n }).not.toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'z', 'z', scope);\n }).not.toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'z', 'z', scope);\n }).not.toThrow();\n\n expect(function() {\n om.mapRange(duplicate, 2, 2, scope);\n }).toThrow();\n expect(function() {\n om.filterRange(duplicate, 2, 2, scope);\n }).toThrow();\n expect(function() {\n om.forEachRange(duplicate, 2, 2, scope);\n }).toThrow();\n expect(function() {\n om.mapKeyRange(duplicate, 'z', null, scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'z', null, scope);\n }).toThrow();\n\n // Provide keys in reverse order - should throw.\n expect(function() {\n om.mapKeyRange(duplicate, 'y', 'x', scope);\n }).toThrow();\n expect(function() {\n om.forEachKeyRange(duplicate, 'y', 'x', scope);\n }).toThrow();\n });\n\n // TEST length zero map, or keyrange start===end\n\n it('should map range correctly', function() {\n var om = OrderedMap.fromArray([\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ], extractUniqueID);\n var scope = {justToTestScope: 'justTestingScope'};\n var verifyThreeItems = function(omResult) {\n expect(omResult.length).toBe(3);\n expect(omResult.keyAtIndex(0)).toBe('x');\n expect(omResult.keyAtIndex(1)).toBe('y');\n expect(omResult.keyAtIndex(2)).toBe('z');\n expect(omResult.get('x').val).toBe('xxx0justTestingScope');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n expect(omResult.get('z').val).toBe('zzz2justTestingScope');\n };\n var verifyFirstTwoItems = function(omResult) {\n expect(omResult.length).toBe(2);\n expect(omResult.keyAtIndex(0)).toBe('x');\n expect(omResult.keyAtIndex(1)).toBe('y');\n expect(omResult.get('x').val).toBe('xxx0justTestingScope');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n };\n\n var verifyLastTwoItems = function(omResult) {\n expect(omResult.length).toBe(2);\n expect(omResult.keyAtIndex(0)).toBe('y');\n expect(omResult.keyAtIndex(1)).toBe('z');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n expect(omResult.get('z').val).toBe('zzz2justTestingScope');\n };\n\n var verifyMiddleItem = function(omResult) {\n expect(omResult.length).toBe(1);\n expect(omResult.keyAtIndex(0)).toBe('y');\n expect(omResult.get('y').val).toBe('yyy1justTestingScope');\n };\n\n var verifyEmpty = function(omResult) {\n expect(omResult.length).toBe(0);\n };\n\n var omResultThree = om.mapRange(duplicate, 0, 3, scope);\n verifyThreeItems(omResultThree);\n var resArray = [];\n var pushToResArray = function(itm, key, count) {\n resArray.push({\n uniqueID: itm.uniqueID,\n val: itm.val + key + count + this.justToTestScope\n });\n };\n\n om.forEachRange(pushToResArray, 0, 3, scope);\n omResultThree = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyThreeItems(omResultThree);\n\n var omResultFirstTwo = om.mapRange(duplicate, 0, 2, scope);\n verifyFirstTwoItems(omResultFirstTwo);\n resArray = [];\n om.forEachRange(pushToResArray, 0, 2, scope);\n omResultFirstTwo = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyFirstTwoItems(omResultFirstTwo);\n\n var omResultLastTwo = om.mapRange(duplicate, 1, 2, scope);\n verifyLastTwoItems(omResultLastTwo);\n resArray = [];\n om.forEachRange(pushToResArray, 1, 2, scope);\n omResultLastTwo = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyLastTwoItems(omResultLastTwo);\n\n var omResultMiddle = om.mapRange(duplicate, 1, 1, scope);\n verifyMiddleItem(omResultMiddle);\n resArray = [];\n om.forEachRange(pushToResArray, 1, 1, scope);\n omResultMiddle = OrderedMap.fromArray(resArray, extractUniqueID);\n verifyMiddleItem(omResultMiddle);\n\n var omResultNone = om.mapRange(duplicate, 1, 0, scope);\n verifyEmpty(omResultNone);\n });\n\n it('should extract the original array correctly', function() {\n var sourceArray = [\n {uniqueID: 'x', val: 'xx'},\n {uniqueID: 'y', val: 'yy'},\n {uniqueID: 'z', val: 'zz'}\n ];\n var om = OrderedMap.fromArray(sourceArray, extractUniqueID);\n expect(om.toArray()).toEqual(sourceArray);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/OrderedMap-test\", module);\n", -"utils/__tests__/ReactChildren-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n * @jsx React.DOM\n */\n\n\"use strict\";\n\ndescribe('ReactChildren', function() {\n var ReactChildren;\n var React;\n\n beforeEach(function() {\n ReactChildren = require(\"../../ReactChildren\");\n React = require(\"../../React\");\n });\n\n\n it('should support identity for simple', function() {\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return kid;\n });\n\n var simpleKid = React.DOM.span( {key:\"simple\"} );\n\n // First pass children into a component to fully simulate what happens when\n // using structures that arrive from transforms.\n\n var instance = React.DOM.div(null, simpleKid);\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n callback.reset();\n var mappedChildren = ReactChildren.map(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n expect(mappedChildren[Object.keys(mappedChildren)[0]]).toBe(simpleKid);\n });\n\n it('should treat single arrayless child as being in array', function() {\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return kid;\n });\n\n var simpleKid = React.DOM.span(null );\n var instance = React.DOM.div(null, simpleKid);\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n callback.reset();\n var mappedChildren = ReactChildren.map(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n expect(mappedChildren[Object.keys(mappedChildren)[0]]).toBe(simpleKid);\n });\n\n it('should treat single child in array as expected', function() {\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return kid;\n });\n\n var simpleKid = React.DOM.span(null );\n var instance = React.DOM.div(null, [simpleKid]);\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n callback.reset();\n var mappedChildren = ReactChildren.map(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(simpleKid, 0);\n expect(mappedChildren[Object.keys(mappedChildren)[0]]).toBe(simpleKid);\n });\n\n it('should pass key to returned component', function() {\n var mapFn = function (kid, index) {\n return React.DOM.div(null, kid);\n };\n\n var simpleKid = React.DOM.span( {key:\"simple\"} );\n\n var instance = React.DOM.div(null, simpleKid);\n var mappedChildren = ReactChildren.map(instance.props.children, mapFn);\n\n var mappedKeys = Object.keys(mappedChildren);\n expect(mappedKeys.length).toBe(1);\n expect(mappedChildren[mappedKeys[0]]).not.toBe(simpleKid);\n expect(mappedChildren[mappedKeys[0]].props.children).toBe(simpleKid);\n expect(mappedKeys[0]).toBe('{simple}');\n });\n\n it('should invoke callback with the right context', function() {\n var lastContext;\n var callback = function (kid, index) {\n lastContext = this;\n return this;\n };\n\n var scopeTester = {};\n\n var simpleKid = React.DOM.span( {key:\"simple\"} );\n var instance = React.DOM.div(null, simpleKid);\n ReactChildren.forEach(instance.props.children, callback, scopeTester);\n expect(lastContext).toBe(scopeTester);\n\n var mappedChildren =\n ReactChildren.map(instance.props.children, callback, scopeTester);\n\n var mappedKeys = Object.keys(mappedChildren);\n expect(mappedKeys.length).toBe(1);\n expect(mappedChildren[mappedKeys[0]]).toBe(scopeTester);\n });\n\n it('should be called for each child', function() {\n var zero = React.DOM.div( {key:\"keyZero\"} );\n var one = null;\n var two = React.DOM.div( {key:\"keyTwo\"} );\n var three = null;\n var four = React.DOM.div( {key:\"keyFour\"} );\n\n var zeroMapped = React.DOM.div( {key:\"giraffe\"} ); // Key should be overridden\n var oneMapped = null; // Key should be added even if we don't supply it!\n var twoMapped = React.DOM.div(null ); // Key should be added even if not supplied!\n var threeMapped = React.DOM.span(null ); // Map from null to something.\n var fourMapped = React.DOM.div( {key:\"keyFour\"} );\n\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return index === 0 ? zeroMapped :\n index === 1 ? oneMapped :\n index === 2 ? twoMapped :\n index === 3 ? threeMapped : fourMapped;\n });\n\n var instance = (\n React.DOM.div(null, \n zero,\n one,\n two,\n three,\n four\n )\n );\n\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(zero, 0);\n expect(callback).toHaveBeenCalledWith(one, 1);\n expect(callback).toHaveBeenCalledWith(two, 2);\n expect(callback).toHaveBeenCalledWith(three, 3);\n expect(callback).toHaveBeenCalledWith(four, 4);\n callback.reset();\n\n var mappedChildren =\n ReactChildren.map(instance.props.children, callback);\n var mappedKeys = Object.keys(mappedChildren);\n expect(callback.calls.length).toBe(5);\n expect(mappedKeys.length).toBe(5);\n // Keys default to indices.\n expect(mappedKeys).toEqual(\n ['{keyZero}', '[1]', '{keyTwo}', '[3]', '{keyFour}']\n );\n\n expect(callback).toHaveBeenCalledWith(zero, 0);\n expect(mappedChildren[mappedKeys[0]]).toBe(zeroMapped);\n\n expect(callback).toHaveBeenCalledWith(one, 1);\n expect(mappedChildren[mappedKeys[1]]).toBe(oneMapped);\n\n expect(callback).toHaveBeenCalledWith(two, 2);\n expect(mappedChildren[mappedKeys[2]]).toBe(twoMapped);\n\n expect(callback).toHaveBeenCalledWith(three, 3);\n expect(mappedChildren[mappedKeys[3]]).toBe(threeMapped);\n\n expect(callback).toHaveBeenCalledWith(four, 4);\n expect(mappedChildren[mappedKeys[4]]).toBe(fourMapped);\n });\n\n\n it('should be called for each child in nested structure', function() {\n var zero = React.DOM.div( {key:\"keyZero\"} );\n var one = null;\n var two = React.DOM.div( {key:\"keyTwo\"} );\n var three = null;\n var four = React.DOM.div( {key:\"keyFour\"} );\n var five = React.DOM.div( {key:\"keyFiveCompletelyIgnored\"} );\n // five is placed into a JS object with a key that takes precedence over the\n // component key attribute.\n // Precedence is as follows:\n // 1. JavaScript Object key if in a JavaScript object:\n // 2. If grouped in an Array, the `key` attribute.\n // 3. The array index if in a JavaScript Array.\n\n var zeroMapped = React.DOM.div( {key:\"giraffe\"} ); // Key should be overridden\n var oneMapped = null; // Key should be added even if we don't supply it!\n var twoMapped = React.DOM.div(null ); // Key should be added even if not supplied!\n var threeMapped = React.DOM.span(null ); // Map from null to something.\n var fourMapped = React.DOM.div( {key:\"keyFour\"} );\n var fiveMapped = React.DOM.div(null );\n\n var callback = jasmine.createSpy().andCallFake(function (kid, index) {\n return index === 0 ? zeroMapped :\n index === 1 ? oneMapped :\n index === 2 ? twoMapped :\n index === 3 ? threeMapped :\n index === 4 ? fourMapped : fiveMapped;\n });\n\n var instance = (\n React.DOM.div(null, \n [{\n firstHalfKey: [zero, one, two],\n secondHalfKey: [three, four],\n keyFive: five\n }]\n )\n );\n\n ReactChildren.forEach(instance.props.children, callback);\n expect(callback).toHaveBeenCalledWith(zero, 0);\n expect(callback).toHaveBeenCalledWith(one, 1);\n expect(callback).toHaveBeenCalledWith(two, 2);\n expect(callback).toHaveBeenCalledWith(three, 3);\n expect(callback).toHaveBeenCalledWith(four, 4);\n expect(callback).toHaveBeenCalledWith(five, 5);\n callback.reset();\n\n var mappedChildren = ReactChildren.map(instance.props.children, callback);\n var mappedKeys = Object.keys(mappedChildren);\n expect(callback.calls.length).toBe(6);\n expect(mappedKeys.length).toBe(6);\n // Keys default to indices.\n expect(mappedKeys).toEqual([\n '[0]{firstHalfKey}{keyZero}',\n '[0]{firstHalfKey}[1]',\n '[0]{firstHalfKey}{keyTwo}',\n '[0]{secondHalfKey}[0]',\n '[0]{secondHalfKey}{keyFour}',\n '[0]{keyFive}'\n ]);\n\n expect(callback).toHaveBeenCalledWith(zero, 0);\n expect(mappedChildren[mappedKeys[0]]).toBe(zeroMapped);\n\n expect(callback).toHaveBeenCalledWith(one, 1);\n expect(mappedChildren[mappedKeys[1]]).toBe(oneMapped);\n\n expect(callback).toHaveBeenCalledWith(two, 2);\n expect(mappedChildren[mappedKeys[2]]).toBe(twoMapped);\n\n expect(callback).toHaveBeenCalledWith(three, 3);\n expect(mappedChildren[mappedKeys[3]]).toBe(threeMapped);\n\n expect(callback).toHaveBeenCalledWith(four, 4);\n expect(mappedChildren[mappedKeys[4]]).toBe(fourMapped);\n\n expect(callback).toHaveBeenCalledWith(five, 5);\n expect(mappedChildren[mappedKeys[5]]).toBe(fiveMapped);\n });\n\n it('should retain key across two mappings', function() {\n var zeroForceKey = React.DOM.div( {key:\"keyZero\"} );\n var oneForceKey = React.DOM.div( {key:\"keyOne\"} );\n\n // Key should be overridden\n var zeroForceKeyMapped = React.DOM.div( {key:\"giraffe\"} );\n // Key should be added even if we don't supply it!\n var oneForceKeyMapped = React.DOM.div(null );\n\n var mapFn = function(kid, index) {\n return index === 0 ? zeroForceKeyMapped : oneForceKeyMapped;\n };\n\n var forcedKeys = (\n React.DOM.div(null, \n zeroForceKey,\n oneForceKey\n )\n );\n\n var expectedForcedKeys = ['{keyZero}', '{keyOne}'];\n var mappedChildrenForcedKeys =\n ReactChildren.map(forcedKeys.props.children, mapFn);\n var mappedForcedKeys = Object.keys(mappedChildrenForcedKeys);\n expect(mappedForcedKeys).toEqual(expectedForcedKeys);\n\n var expectedRemappedForcedKeys = ['{{keyZero}}', '{{keyOne}}'];\n var remappedChildrenForcedKeys =\n ReactChildren.map(mappedChildrenForcedKeys, mapFn);\n expect(\n Object.keys(remappedChildrenForcedKeys)\n ).toEqual(expectedRemappedForcedKeys);\n\n });\n\n it('should not throw if key provided is a dupe with array key', function() {\n var zero = React.DOM.div(null );\n var one = React.DOM.div( {key:\"0\"} );\n\n var mapFn = function() {\n return null;\n };\n\n var instance = (\n React.DOM.div(null, \n zero,\n one\n )\n );\n\n expect(function() {\n ReactChildren.map(instance.props.children, mapFn);\n }).not.toThrow();\n });\n\n it('should throw if key provided is a dupe with explicit key', function() {\n var zero = React.DOM.div( {key:\"something\"});\n var one = React.DOM.div( {key:\"something\"} );\n\n var mapFn = function() {return null;};\n var instance = (\n React.DOM.div(null, zero,one)\n );\n\n expect(function() {\n ReactChildren.map(instance.props.children, mapFn);\n }).toThrow();\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/ReactChildren-test\", module);\n", -"utils/__tests__/Transaction-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nvar Transaction;\nvar mixInto;\n\nvar INIT_ERRORED = 'initErrored'; // Just a dummy value to check for.\ndescribe('Transaction', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n Transaction = require(\"../../Transaction\");\n mixInto = require(\"../../mixInto\");\n });\n\n /**\n * We should not invoke closers for inits that failed. We should pass init\n * return values to closers when those inits are successful. We should not\n * invoke the actual method when any of the initializers fail.\n */\n it('should invoke closers with/only-with init returns', function() {\n var throwInInit = function() {\n throw new Error('close[0] should receive Transaction.OBSERVED_ERROR');\n };\n\n var performSideEffect;\n var dontPerformThis = function() {\n performSideEffect = 'This should never be set to this';\n };\n\n /**\n * New test Transaction subclass.\n */\n var TestTransaction = function() {\n this.reinitializeTransaction();\n this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else\n this.secondCloseParam = INIT_ERRORED; // WILL be set to something else\n this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else\n };\n mixInto(TestTransaction, Transaction.Mixin);\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n initialize: throwInInit,\n close: function(initResult) {\n this.firstCloseParam = initResult;\n }\n },\n {\n initialize: function() { return 'asdf'; },\n close: function(initResult) {\n this.secondCloseParam = initResult;\n }\n },\n {\n initialize: throwInInit,\n close: function(initResult) {\n this.lastCloseParam = initResult;\n }\n }\n ];\n };\n\n var transaction = new TestTransaction();\n\n expect(function() {\n transaction.perform(dontPerformThis);\n }).toThrow();\n\n expect(performSideEffect).toBe(undefined);\n expect(transaction.firstCloseParam).toBe(INIT_ERRORED);\n expect(transaction.secondCloseParam).toBe('asdf');\n expect(transaction.lastCloseParam).toBe(INIT_ERRORED);\n expect(transaction.isInTransaction()).toBe(false);\n });\n\n it('should invoke closers and wrapped method when inits success', function() {\n\n var performSideEffect;\n /**\n * New test Transaction subclass.\n */\n var TestTransaction = function() {\n this.reinitializeTransaction();\n this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else\n this.secondCloseParam = INIT_ERRORED; // WILL be set to something else\n this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else\n };\n mixInto(TestTransaction, Transaction.Mixin);\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n initialize: function() {\n return 'firstResult';\n },\n close: function(initResult) {\n this.firstCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'secondResult';\n },\n close: function(initResult) {\n this.secondCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'thirdResult';\n },\n close: function(initResult) {\n this.lastCloseParam = initResult;\n }\n }\n ];\n };\n\n var transaction = new TestTransaction();\n\n transaction.perform(function() {\n performSideEffect = 'SIDE_EFFECT';\n });\n\n expect(performSideEffect).toBe('SIDE_EFFECT');\n expect(transaction.firstCloseParam).toBe('firstResult');\n expect(transaction.secondCloseParam).toBe('secondResult');\n expect(transaction.lastCloseParam).toBe('thirdResult');\n expect(transaction.isInTransaction()).toBe(false);\n });\n\n /**\n * When the operation throws, the transaction should throw, but all of the\n * error-free closers should execute gracefully without issue. If a closer\n * throws an error, the transaction should prefer to throw the error\n * encountered earlier in the operation.\n */\n it('should throw when wrapped operation throws', function() {\n\n var performSideEffect;\n /**\n * New test Transaction subclass.\n */\n var TestTransaction = function() {\n this.reinitializeTransaction();\n this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else\n this.secondCloseParam = INIT_ERRORED; // WILL be set to something else\n this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else\n };\n mixInto(TestTransaction, Transaction.Mixin);\n // Now, none of the close/inits throw, but the operation we wrap will throw.\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n initialize: function() {\n return 'firstResult';\n },\n close: function(initResult) {\n this.firstCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'secondResult';\n },\n close: function(initResult) {\n this.secondCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'thirdResult';\n },\n close: function(initResult) {\n this.lastCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n return 'fourthResult';\n },\n close: function(initResult) {\n throw new Error('The transaction should throw a TypeError.');\n }\n }\n ];\n };\n\n var transaction = new TestTransaction();\n\n expect(function() {\n var isTypeError = false;\n try {\n transaction.perform(function() {\n throw new TypeError(\"Thrown in main wrapped operation\");\n });\n } catch (err) {\n isTypeError = (err instanceof TypeError);\n }\n return isTypeError;\n }()).toBe(true);\n\n expect(performSideEffect).toBe(undefined);\n expect(transaction.firstCloseParam).toBe('firstResult');\n expect(transaction.secondCloseParam).toBe('secondResult');\n expect(transaction.lastCloseParam).toBe('thirdResult');\n expect(transaction.isInTransaction()).toBe(false);\n });\n\n it('should throw errors in transaction close', function() {\n var TestTransaction = function() {\n this.reinitializeTransaction();\n };\n mixInto(TestTransaction, Transaction.Mixin);\n var exceptionMsg = 'This exception should throw.';\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n close: function(initResult) {\n throw new Error(exceptionMsg);\n }\n }\n ];\n };\n\n var transaction = new TestTransaction();\n expect(function() {\n transaction.perform(function() {});\n }).toThrow(exceptionMsg);\n });\n\n it('should allow nesting of transactions', function() {\n var performSideEffect;\n var nestedPerformSideEffect;\n /**\n * New test Transaction subclass.\n */\n var TestTransaction = function() {\n this.reinitializeTransaction();\n this.firstCloseParam = INIT_ERRORED; // WON'T be set to something else\n this.secondCloseParam = INIT_ERRORED; // WILL be set to something else\n this.lastCloseParam = INIT_ERRORED; // WON'T be set to something else\n };\n mixInto(TestTransaction, Transaction.Mixin);\n TestTransaction.prototype.getTransactionWrappers = function() {\n return [\n {\n initialize: function() {\n return 'firstResult';\n },\n close: function(initResult) {\n this.firstCloseParam = initResult;\n }\n },\n {\n initialize: function() {\n this.nestedTransaction = new NestedTransaction();\n },\n close: function() {\n // Test performing a transaction in another transaction's close()\n this.nestedTransaction.perform(function() {\n nestedPerformSideEffect = 'NESTED_SIDE_EFFECT';\n });\n }\n }\n ];\n };\n\n var NestedTransaction = function() {\n this.reinitializeTransaction();\n };\n mixInto(NestedTransaction, Transaction.Mixin);\n NestedTransaction.prototype.getTransactionWrappers = function() {\n return [{\n initialize: function() {\n this.hasInitializedNested = true;\n },\n close: function() {\n this.hasClosedNested = true;\n }\n }];\n };\n\n var transaction = new TestTransaction();\n\n transaction.perform(function() {\n performSideEffect = 'SIDE_EFFECT';\n });\n\n expect(performSideEffect).toBe('SIDE_EFFECT');\n expect(nestedPerformSideEffect).toBe('NESTED_SIDE_EFFECT');\n expect(transaction.firstCloseParam).toBe('firstResult');\n expect(transaction.isInTransaction()).toBe(false);\n expect(transaction.nestedTransaction.hasClosedNested).toBe(true);\n expect(transaction.nestedTransaction.hasInitializedNested).toBe(true);\n expect(transaction.nestedTransaction.isInTransaction()).toBe(false);\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/Transaction-test\", module);\n", -"utils/__tests__/escapeTextForBrowser-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\ndescribe('escapeTextForBrowser', function() {\n\n var escapeTextForBrowser = require(\"../../escapeTextForBrowser\");\n\n it('should escape boolean to string', function() {\n expect(escapeTextForBrowser(true)).toBe('true');\n expect(escapeTextForBrowser(false)).toBe('false');\n });\n\n it('should escape object to string', function() {\n var escaped = escapeTextForBrowser({\n toString: function() {\n return 'ponys';\n }\n });\n\n expect(escaped).toBe('ponys');\n });\n\n it('should escape number to string', function() {\n expect(escapeTextForBrowser(42)).toBe('42');\n });\n\n it('should escape string', function() {\n var escaped = escapeTextForBrowser('');\n expect(escaped).not.toContain('<');\n expect(escaped).not.toContain('>');\n expect(escaped).not.toContain('\\'');\n expect(escaped).not.toContain('/');\n expect(escaped).not.toContain('\\\"');\n\n escaped = escapeTextForBrowser('&');\n expect(escaped).toBe('&');\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/escapeTextForBrowser-test\", module);\n", -"utils/__tests__/joinClasses-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\").dontMock('joinClasses');\n\nvar joinClasses = require(\"../../joinClasses\");\n\ndescribe('joinClasses', function() {\n\n it('should return a single className', function() {\n expect(joinClasses('aaa')).toEqual('aaa');\n });\n\n it('should join two classes together', function() {\n var aaa = 'aaa';\n var bbb = 'bbb';\n expect(joinClasses(aaa, bbb)).toEqual('aaa bbb');\n });\n\n it('should join many classes together', function() {\n var aaa = 'aaa';\n var bbb = 'bbb';\n var ccc = 'ccc';\n var ddd = 'ddd';\n var eee = 'eee';\n expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa bbb ccc ddd eee');\n });\n\n it('should omit undefined and empty classes', function() {\n var aaa = 'aaa';\n var bbb;\n var ccc = null;\n var ddd = '';\n var eee = 'eee';\n expect(joinClasses(bbb)).toEqual('');\n expect(joinClasses(bbb, bbb, bbb)).toEqual('');\n expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa eee');\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/joinClasses-test\", module);\n", -"utils/__tests__/keyMirror-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\").dontMock('keyMirror');\n\nvar keyMirror = require(\"../../keyMirror\");\n\ndescribe('keyMirror', function() {\n it('should create an object with values matching keys provided', function() {\n var mirror = keyMirror({\n foo: null,\n bar: true,\n \"baz\": { some: \"object\" },\n qux: undefined\n });\n expect('foo' in mirror).toBe(true);\n expect(mirror.foo).toBe('foo');\n expect('bar' in mirror).toBe(true);\n expect(mirror.bar).toBe('bar');\n expect('baz' in mirror).toBe(true);\n expect(mirror.baz).toBe('baz');\n expect('qux' in mirror).toBe(true);\n expect(mirror.qux).toBe('qux');\n });\n\n it('should not use properties from prototypes', function() {\n function Klass() {\n this.useMeToo = true;\n }\n Klass.prototype.doNotUse = true;\n var instance = new Klass();\n instance.useMe = true;\n\n var mirror = keyMirror(instance);\n\n expect('doNotUse' in mirror).toBe(false);\n expect('useMe' in mirror).toBe(true);\n expect('useMeToo' in mirror).toBe(true);\n });\n\n it('should throw when a non-object argument is used', function() {\n [null, undefined, 0, 7, ['uno'], true, \"string\"].forEach(function(testVal) {\n expect(keyMirror.bind(null, testVal)).toThrow();\n });\n });\n\n it('should work when \"constructor\" is a key', function() {\n var obj = { constructor: true };\n expect(keyMirror.bind(null, obj)).not.toThrow();\n var mirror = keyMirror(obj);\n expect('constructor' in mirror).toBe(true);\n });\n});\n\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/keyMirror-test\", module);\n", -"utils/__tests__/memoizeStringOnly-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\ndescribe('memoizeStringOnly', function() {\n var memoizeStringOnly;\n\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n memoizeStringOnly = require(\"../../memoizeStringOnly\");\n });\n\n it('should be transparent to callers', function() {\n var callback = function(string) {\n return string;\n };\n var memoized = memoizeStringOnly(callback);\n\n expect(memoized('foo'), callback('foo'));\n });\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/memoizeStringOnly-test\", module);\n", -"utils/__tests__/onlyChild-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n * @jsx React.DOM\n */\n\n\"use strict\";\n\ndescribe('onlyChild', function() {\n\n var React;\n var onlyChild;\n var WrapComponent;\n\n beforeEach(function() {\n React = require(\"../../React\");\n onlyChild = require(\"../../onlyChild\");\n WrapComponent = React.createClass({\n render: function() {\n return (\n React.DOM.div(null, \n onlyChild(this.props.children, this.props.mapFn, this)\n )\n );\n }\n });\n });\n\n it('should fail when passed two children', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n React.DOM.div(null ),\n React.DOM.span(null )\n );\n onlyChild(instance.props.children);\n }).toThrow();\n });\n\n it('should fail when passed nully values', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n null\n );\n onlyChild(instance.props.children);\n }).toThrow();\n\n expect(function() {\n var instance =\n WrapComponent(null, \n undefined\n );\n onlyChild(instance.props.children);\n }).toThrow();\n });\n\n it('should fail when key/value objects', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n {oneThing: React.DOM.span(null )}\n );\n onlyChild(instance.props.children);\n }).toThrow();\n });\n\n\n it('should not fail when passed interpolated single child', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n React.DOM.span(null )\n );\n onlyChild(instance.props.children);\n }).not.toThrow();\n });\n\n\n it('should return the only child', function() {\n expect(function() {\n var instance =\n WrapComponent(null, \n React.DOM.span(null )\n );\n onlyChild(instance.props.children);\n }).not.toThrow();\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/onlyChild-test\", module);\n", -"utils/__tests__/mergeFuncs-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n */\n\n\"use strict\";\n\nrequire(\"../../mock-modules\")\n .dontMock('mergeHelpers')\n .dontMock('merge')\n .dontMock('mergeDeep')\n .dontMock('mergeInto')\n .dontMock('mergeDeepInto');\n\nvar mergeHelpers;\nvar merge;\nvar mergeInto;\nvar mergeDeep;\nvar mergeDeepInto;\n\nvar isTerminal;\nvar MAX_MERGE_DEPTH;\n\n/**\n * Simple helper to traverse an object, calling the callback (cb) on every\n * nonTerminal node it finds. It stops once it reaches the maximum depth,\n * because we know that the merge functions shouldn't merge past that depth\n * anyways. If you don't \"stop\" once reaching the MAX_MERGE_DEPTH, there won't\n * be a practical way to traverse circular structures.\n */\nvar traverseUntilLeaves = function(obj, cb, depth) {\n if ((depth || 0) >= MAX_MERGE_DEPTH) {\n return;\n }\n var key;\n if (!isTerminal(obj) && !Array.isArray(obj)) {\n cb(obj);\n for (key in obj) {\n if (!obj.hasOwnProperty(key)) {\n continue;\n }\n traverseUntilLeaves(obj[key], cb, (depth || 0) + 1);\n }\n }\n};\n\n/*\n * Checks that the structure of two merged objects are identical. Checks\n * MAX_LEVEL because we don't want to block other unit tests if I have an\n * infinite loop.\n */\nvar MAX_LEVEL = 50;\nvar structureEquals = function(one, two, levelParam) {\n var level = levelParam || 0;\n var oneKey;\n var twoKey;\n if (level > MAX_LEVEL) {\n throw new Error('structure equals computation explored too many levels');\n }\n if (isTerminal(one) && isTerminal(two)) {\n return one === two;\n } else if (!isTerminal(one) && !isTerminal(two)) {\n var allInOneAreInTwo = true;\n for (oneKey in one) {\n if (!one.hasOwnProperty(oneKey)) {\n continue;\n }\n if (!structureEquals(one[oneKey], two[oneKey], level + 1)) {\n allInOneAreInTwo = false;\n }\n }\n var allInTwoAreInOne = true;\n for (twoKey in two) {\n if (!two.hasOwnProperty(twoKey)) {\n continue;\n }\n if (!structureEquals(two[twoKey], one[twoKey], level + 1)) {\n allInTwoAreInOne = false;\n }\n }\n // Sure, the computations overlap a bit.\n return allInOneAreInTwo && allInTwoAreInOne;\n } else {\n return false;\n }\n};\n\n\nvar makeCircular = function() {\n var obj = {};\n obj.self = obj;\n return obj;\n};\n\n\n\n/**\n * Not a symmetric function. Checks if there are any node references\n * (nonTerminal [non-string, non-null, etc]) that exist in inThis. See\n * sharesOnlyTerminalMemory.\n */\nvar hasNoNodeReferencesIn = function(obj, inThis) {\n traverseUntilLeaves(obj, function(nonTerm) {\n traverseUntilLeaves(inThis, function(inThisNonTerm) {\n if (inThisNonTerm === nonTerm) {\n return false;\n }\n });\n });\n return true;\n};\n\n/**\n * Checks that two objects share no memory references with each other (except\n * possibly at the terminal nodes (such as strings etc)). This is used to test\n * isolation of memory. When certain merge operations occur we need to ensure\n * that we did not leak references across objects.\n */\nvar sharesOnlyTerminalMemory = function(a, b) {\n return hasNoNodeReferencesIn(a, b) && hasNoNodeReferencesIn(b, a);\n};\n\n/**\n * Tests all of the merging functions. You provide it data that describes what\n * a deep merge looks like and what a shallow merge looks like. It will make\n * sure that various input/output contracts are adhered to, in addition to\n * ensuring that various guarantees about side-effects are upheld.\n * The test data must provide functions createOne/createTwo as a means to\n * create test data for objects one/two respsectively - each time these\n * functions must return pristine copies so that we can test for side effects\n * correctly.\n */\nvar testAllMerges = function(testData) {\n var createOne = testData.createOne;\n var createTwo = testData.createTwo;\n var one;\n var two;\n\n /*\n * Test merge()\n */\n one = createOne();\n two = createTwo();\n if (testData.mergeShouldThrow) {\n expect(function() {\n merge(one, two);\n }).toThrow();\n } else {\n var mergeRes = merge(one, two);\n if (testData.shallowResultShouldBe) {\n expect(structureEquals(\n mergeRes,\n testData.shallowResultShouldBe)\n ).toBe(true);\n }\n // Ensure the result is not the exact same object memory reference.\n expect(mergeRes === one).toBe(false);\n }\n\n /*\n * Test mergeInto()\n */\n one = createOne();\n two = createTwo();\n if (testData.mergeIntoShouldThrow) {\n expect(function() {\n mergeInto(one, two);\n }).toThrow();\n } else {\n var mergeIntoRes = mergeInto(one, two);\n if (testData.shallowResultShouldBe) {\n expect(structureEquals(\n one,\n testData.shallowResultShouldBe)\n ).toBe(true);\n }\n /*\n * Ensure it's the exact same object reference\n * TODO: We should ensure that for every object path p in one points to\n * the original object reference in one before the mutation.\n */\n expect(mergeIntoRes === undefined).toBe(true);\n }\n\n /*\n * Test mergeDeep()\n */\n one = createOne();\n two = createTwo();\n if (testData.mergeDeepShouldThrow) {\n expect(function() {\n mergeDeep(one, two, testData.arrayStrategy);\n }).toThrow();\n } else {\n var mergeDeepRes = mergeDeep(one, two, testData.arrayStrategy);\n if (testData.deepResultShouldBe) {\n expect(structureEquals(\n mergeDeepRes,\n testData.deepResultShouldBe)\n ).toBe(true);\n }\n expect(sharesOnlyTerminalMemory(mergeDeepRes, one)).toBe(true);\n expect(sharesOnlyTerminalMemory(mergeDeepRes, two)).toBe(true);\n }\n\n /*\n * Test mergeDeepInto()\n */\n one = createOne();\n two = createTwo();\n if (testData.mergeDeepIntoShouldThrow) {\n expect(function() {\n mergeDeepInto(one, two, testData.arrayStrategy);\n }).toThrow();\n } else {\n var mergeDeepIntoRes = mergeDeepInto(one, two, testData.arrayStrategy);\n expect(mergeDeepIntoRes).toBe(undefined);\n if (testData.deepResultShouldBe) {\n expect(structureEquals(\n one,\n testData.deepResultShouldBe)\n ).toBe(true);\n }\n expect(mergeDeepIntoRes === undefined).toBe(true);\n expect(sharesOnlyTerminalMemory(one, two)).toBe(true);\n }\n\n};\n\n/**\n * ReactTextWithEntities is not a React component, but rather a helper function\n * that returns an array. You can use that array as a helper function when\n * constructing a structure.\n */\ndescribe('mergeFuncs', function() {\n beforeEach(function() {\n require(\"../../mock-modules\").dumpCache();\n mergeHelpers = require(\"../../mergeHelpers\");\n merge = require(\"../../merge\");\n mergeInto = require(\"../../mergeInto\");\n mergeDeep = require(\"../../mergeDeep\");\n mergeDeepInto = require(\"../../mergeDeepInto\");\n isTerminal = mergeHelpers.isTerminal;\n MAX_MERGE_DEPTH = mergeHelpers.MAX_MERGE_DEPTH;\n });\n\n var twoLevelsDeep = function() {\n return {\n shallowObject: {\n deepObject: {\n a: 'a',\n b: 'b'\n },\n deepObject2: {\n one: 'one',\n two: 'two'\n }\n }\n };\n };\n\n it('should not throw if first argument is circular', function() {\n testAllMerges({\n createOne: makeCircular,\n createTwo: function() { return {thisOneIsNotCircular: true}; },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: false\n });\n });\n\n it('should throw if second argument is circular', function() {\n testAllMerges({\n createOne: function() { return {thisOneIsNotCircular: true}; },\n createTwo: makeCircular,\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n });\n\n it('should throw if something deep is circular in second param', function() {\n testAllMerges({\n createOne: function() { return {thisOneIsNotCircular: true}; },\n createTwo: function() {\n return {\n deeper: {\n deeper: makeCircular()\n }\n };\n },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n });\n\n it('should throw if something deep is circular in first param', function() {\n testAllMerges({\n createOne: function() {\n return {\n deeper: {\n deeper: makeCircular()\n }\n };\n },\n createTwo: function() { return {thisOneIsNotCircular: true}; },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: false\n });\n });\n\n\n it('should throw exceptions on invalid data/params', function() {\n testAllMerges({\n createOne: function() { return []; },\n createTwo: function() { return {}; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {}; },\n createTwo: function() { return []; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return []; },\n createTwo: function() { return {hasDeepStructure: 'yes'}; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {hasDeepStructure: 'yes'}; },\n createTwo: function() { return []; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {hasDeepStructure: 'yes'}; },\n createTwo: function() { return []; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n /*\n * mergeInto functions do not accept an empty first parameter. There would\n * be nothing to mutate!\n */\n testAllMerges({\n createOne: function() { return null; },\n createTwo: function() { return {field: 'yes'}; },\n mergeIntoShouldThrow: true,\n mergeDeepIntoShouldThrow: true,\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n testAllMerges({\n createOne: function() { return undefined; },\n createTwo: function() { return {field: 'yes'}; },\n mergeIntoShouldThrow: true,\n mergeDeepIntoShouldThrow: true,\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n // Every merge function accepts an empty second parameter.\n testAllMerges({\n createOne: function() { return {field: 'yes'}; },\n createTwo: function() { return null; },\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n testAllMerges({\n createOne: function() { return null; },\n createTwo: function() { return null; },\n deepResultShouldBe: {},\n shallowResultShouldBe: {},\n mergeIntoShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {field: 'yes'}; },\n createTwo: function() { return undefined; },\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n testAllMerges({\n createOne: function() { return 0; },\n createTwo: function() { return {field: 'yes'}; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n /*\n * The fact that the second param is empty shouldn't change that we still\n * error on arrays.\n */\n testAllMerges({\n createOne: function() { return []; },\n createTwo: function() { return undefined; },\n mergeShouldThrow: true,\n mergeIntoShouldThrow: true,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n testAllMerges({\n createOne: function() { return {field: 'yes'}; },\n createTwo: function() { return null; },\n shallowResultShouldBe: {field: 'yes'},\n deepResultShouldBe: {field: 'yes'}\n });\n });\n\n\n it('should merge very deep objects correctly.',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n shouldBeClobberedByNull: {\n color: 'blue'\n },\n shouldGetTwoFieldsWhenDeepMerge: {\n firstField: { color: 'red' }\n },\n shouldRemainUndefined: undefined,\n shouldRemainFour: 4,\n shouldRemainZero: 0,\n shouldBeClobberedByObj: 0\n };\n },\n createTwo: function() {\n return {\n shouldBeClobberedByNull: null,\n shouldGetTwoFieldsWhenDeepMerge: {\n secondField: { color: 'black' }\n },\n shouldBeClobberedByObj: { thisObj: true }\n };\n },\n shallowResultShouldBe: {\n shouldBeClobberedByNull: null,\n // only gets one field when merged shallowly\n shouldGetTwoFieldsWhenDeepMerge: {\n secondField: { color: 'black' }\n },\n shouldRemainUndefined: undefined,\n shouldRemainFour: 4,\n shouldRemainZero: 0,\n shouldBeClobberedByObj: { thisObj: true }\n },\n deepResultShouldBe: {\n shouldRemainUndefined: undefined,\n shouldRemainFour: 4,\n shouldRemainZero: 0,\n shouldBeClobberedByNull: null,\n shouldGetTwoFieldsWhenDeepMerge: {\n firstField: { color: 'red' },\n secondField: { color: 'black' }\n },\n shouldBeClobberedByObj: { thisObj: true }\n }\n });\n }\n );\n\n it(\n 'should not throw with one non-colliding arrays with no arrayStrategy',\n function() {\n testAllMerges({\n createOne: function() { return { hasDeepStructure: 'yes' }; },\n createTwo: function() { return { hasArrayDeeper: [] }; },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false,\n shallowResultShouldBe: {\n hasDeepStructure: 'yes',\n hasArrayDeeper: []\n },\n deepResultShouldBe: {\n hasDeepStructure: 'yes',\n hasArrayDeeper: []\n }\n });\n }\n );\n\n it(\n 'should not throw with two non-colliding arrays with no arrayStrategy',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n arrayOne: [1]\n };\n },\n createTwo: function() {\n return {\n arrayTwo: [2]\n };\n },\n arrayStrategy: mergeHelpers.ArrayStrategies.Clobber,\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n });\n }\n ),\n\n it('should throw if no arrayStrategy supplied on Array merges', function() {\n testAllMerges({\n createOne: function() {\n return {\n arrayOne: [1]\n };\n },\n createTwo: function() {\n return {\n arrayOne: [9]\n };\n },\n shallowResultShouldBe: {\n arrayOne: [9]\n },\n // Doesn't throw on the shallow versions.\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: true,\n mergeDeepIntoShouldThrow: true\n });\n }),\n\n it('should not throw if never forced to merge two Arrays', function() {\n testAllMerges({\n createOne: function() {\n return {\n arrayOne: [1]\n };\n },\n createTwo: function() {\n return {\n arrayTwo: [9] // <-- See, never forced to merge with arrayOne\n };\n },\n shallowResultShouldBe: {\n arrayOne: [1],\n arrayTwo: [9]\n },\n // Doesn't throw on the shallow versions.\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n });\n }),\n\n it(\n 'should correctly deep merge Arrays with arrayStrategy clobber',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n deep: {\n array: [1],\n nonArray: {\n hi: 'hi'\n }\n }\n };\n },\n createTwo: function() {\n return {\n deep: {\n array: [10,11, {deepFieldInArray: 'yes'}],\n nonArray: {\n bye: 'bye'\n }\n }\n };\n },\n shallowResultShouldBe: {\n deep: {\n array: [10,11, {deepFieldInArray: 'yes'}],\n nonArray: {\n bye: 'bye'\n }\n }\n },\n deepResultShouldBe: {\n deep: {\n array: [10,11, {deepFieldInArray: 'yes'}],\n nonArray: {\n hi: 'hi',\n bye: 'bye'\n }\n }\n },\n arrayStrategy: mergeHelpers.ArrayStrategies.Clobber,\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n });\n }\n ),\n\n\n it(\n 'should correctly deep merge Arrays with arrayStrategy indexByIndex',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n deep: {\n array: [{\n atIndexZero: {\n indexZeroGreeting: 'You Are At Index Zero',\n indexZeroStatus: false\n }\n }]\n }\n };\n },\n createTwo: function() {\n return {\n deep: {\n array: [{\n atIndexZero: {\n indexZeroStatus: true,\n newFieldAtIndexZero: 'newField'\n }\n },\n {\n atIndexOne: {\n nothingOriginallyAtThisIndex: true\n }\n }]\n }\n };\n },\n shallowResultShouldBe: {\n deep: {\n array: [{\n atIndexZero: {\n indexZeroStatus: true,\n newFieldAtIndexZero: 'newField'\n }\n },\n {\n atIndexOne: {\n nothingOriginallyAtThisIndex: true\n }\n }]\n }\n },\n deepResultShouldBe: {\n deep: {\n array: [{\n atIndexZero: {\n indexZeroGreeting: 'You Are At Index Zero', // <-- See!?\n indexZeroStatus: true,\n newFieldAtIndexZero: 'newField'\n }\n },\n {\n atIndexOne: {\n nothingOriginallyAtThisIndex: true\n }\n }]\n }\n },\n arrayStrategy: mergeHelpers.ArrayStrategies.IndexByIndex,\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n }\n );\n }),\n\n it('should merge deep data correctly', function() {\n var mergeData = {\n shallowObject: {\n deepObject: {\n c: 'c',\n d: 'd'\n },\n deepObject2: {\n three: 'three',\n four: 'four'\n }\n }\n };\n var deepResult = {\n shallowObject: {\n deepObject: {\n a: 'a',\n b: 'b',\n c: 'c',\n d: 'd'\n },\n deepObject2: {\n one: 'one',\n two: 'two',\n three: 'three',\n four: 'four'\n }\n }\n };\n var shallowResult = mergeData; // The same\n\n testAllMerges({\n createOne: function() { return twoLevelsDeep(); },\n createTwo: function() { return mergeData; },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false,\n deepResultShouldBe: deepResult,\n shallowResultShouldBe: shallowResult\n });\n });\n\n it('should fill in complementing regions of data trees', function() {\n var mergeData = {\n shallowObject: {\n newDepth: {\n hello: 'goodbye'\n }\n }\n };\n var deepResult = {\n shallowObject: {\n deepObject: {\n a: 'a',\n b: 'b'\n },\n deepObject2: {\n one: 'one',\n two: 'two'\n },\n // This is added!\n newDepth: {\n hello: 'goodbye'\n }\n }\n };\n var shallowResult = mergeData; // The same\n\n testAllMerges({\n createOne: function() { return twoLevelsDeep(); },\n createTwo: function() { return mergeData; },\n // The deep merge of the two\n deepResultShouldBe: deepResult,\n shallowResultShouldBe: shallowResult\n });\n });\n\n /**\n * Arrays and Objects wipe out terminals (and vice versa).\n */\n it('should clobber terminals with objects/arrays vice versa', function() {\n var makeOne = function() {\n return {\n thisFieldDoesNothing: {},\n deep: {\n // Objects\n thisShouldSwitchFromObjectToTerminal: {hello: 'goodbye'},\n thisShouldSwitchFromTerminalToObject: 'yes',\n\n // Arrays\n thisShouldSwitchFromArrayToTerminal: ['goodbye'],\n thisShouldSwitchFromTerminalToArray: 'yes'\n }\n };\n };\n var makeTwo = function() {\n return {\n deep: {\n // Objects\n thisShouldSwitchFromObjectToTerminal: 'terminal',\n thisShouldSwitchFromTerminalToObject: {nowItsAnObject: 'yay'},\n\n // Arrays\n thisShouldSwitchFromArrayToTerminal: 'terminal',\n thisShouldSwitchFromTerminalToArray: ['yay']\n }\n };\n };\n var deepResult = {\n thisFieldDoesNothing: {\n\n },\n deep: {\n // Objects\n thisShouldSwitchFromObjectToTerminal: 'terminal',\n thisShouldSwitchFromTerminalToObject: {nowItsAnObject: 'yay'},\n\n // Arrays\n thisShouldSwitchFromArrayToTerminal: 'terminal',\n thisShouldSwitchFromTerminalToArray: ['yay']\n }\n };\n\n testAllMerges({\n createOne: makeOne,\n createTwo: makeTwo,\n deepResultShouldBe: deepResult, // The deep merge of the two\n shallowResultShouldBe: deepResult // The same this time.\n });\n });\n\n /**\n * Arrays wipe out Objects and Objects wipe out Arrays.\n */\n it('should clobber terminals with objects/arrays vice versa', function() {\n var makeOne = function() {\n return {\n thisFieldDoesNothing: {},\n deep: {\n thisShouldSwitchFromObjectToArray: {hello: 'goodbye'},\n thisShouldSwitchFromArrayToObject: [1,2,3]\n }\n };\n };\n var makeTwo = function() {\n return {\n deep: {\n thisShouldSwitchFromObjectToArray: [7,8,9],\n thisShouldSwitchFromArrayToObject: {iUsedToBeAnArray:true}\n }\n };\n };\n var deepResult = {\n thisFieldDoesNothing: {},\n deep: {\n thisShouldSwitchFromObjectToArray: [7,8,9],\n thisShouldSwitchFromArrayToObject: {iUsedToBeAnArray:true}\n }\n };\n\n testAllMerges({\n createOne: makeOne,\n createTwo: makeTwo,\n deepResultShouldBe: deepResult, // The deep merge of the two\n shallowResultShouldBe: deepResult // The same this time.\n });\n });\n\n it(\n 'should not clobber terminals/objects/arrays that are not over-written',\n function() {\n testAllMerges({\n createOne: function() {\n return {\n deep: {\n terminal: 'I am a terminal',\n object: {iAmAnObject: true},\n array: [1,2,3]\n }\n };\n },\n createTwo: function() {\n return {\n deep: {\n completelyDifferentField: 'no collision here!'\n }\n };\n },\n shallowResultShouldBe: {\n deep: {\n completelyDifferentField: 'no collision here!'\n }\n },\n deepResultShouldBe: {\n deep: {\n completelyDifferentField: 'no collision here!',\n terminal: 'I am a terminal',\n object: {iAmAnObject: true},\n array: [1,2,3]\n }\n },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n }\n );\n }),\n\n it('should correctly clobber terminals with cloned arrays', function() {\n testAllMerges({\n createOne: function() {\n return {\n deep: {\n changesFromTermToArray: 'I am a terminal'\n }\n };\n },\n createTwo: function() {\n return {\n deep: {\n changesFromTermToArray: ['I', 'am', 'an', 'array']\n }\n };\n },\n shallowResultShouldBe: {\n deep: {\n changesFromTermToArray: ['I', 'am', 'an', 'array']\n }\n },\n deepResultShouldBe: {\n deep: {\n changesFromTermToArray: ['I', 'am', 'an', 'array']\n }\n },\n mergeShouldThrow: false,\n mergeIntoShouldThrow: false,\n mergeDeepShouldThrow: false,\n mergeDeepIntoShouldThrow: false\n });\n }),\n\n it('should detect terminals correctly in merge* functions', function() {\n var boolResFalse = isTerminal(false);\n expect(boolResFalse).toBe(true);\n\n var boolResTrue = isTerminal(true);\n expect(boolResTrue).toBe(true);\n\n var numRes = isTerminal(123);\n expect(numRes).toBe(true);\n\n var zeroRes = isTerminal(0);\n expect(zeroRes).toBe(true);\n\n var stringRes = isTerminal('i am a string');\n expect(stringRes).toBe(true);\n\n var objLiteralRes = isTerminal({somethingHere: true});\n expect(objLiteralRes).toBe(false);\n\n var undefRes = isTerminal(undefined);\n expect(undefRes).toBe(true);\n\n var nullRes = isTerminal(null);\n expect(nullRes).toBe(true);\n\n var arrRes = isTerminal([]);\n expect(arrRes).toBe(false);\n });\n});\n\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/mergeFuncs-test\", module);\n", -"utils/__tests__/sliceChildren-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n * @jsx React.DOM\n */\n\n\"use strict\";\n\ndescribe('sliceChildren', function() {\n\n var React;\n var ReactTestUtils;\n\n var sliceChildren;\n var reactComponentExpect;\n\n var Partial;\n\n beforeEach(function() {\n React = require(\"../../React\");\n ReactTestUtils = require(\"../../ReactTestUtils\");\n\n sliceChildren = require(\"../../sliceChildren\");\n reactComponentExpect = require(\"../../reactComponentExpect\");\n\n Partial = React.createClass({\n render: function() {\n return (\n React.DOM.div(null, \n sliceChildren(\n this.props.children,\n this.props.start,\n this.props.end\n )\n )\n );\n }\n });\n });\n\n function renderAndSlice(set, start, end) {\n var instance = Partial( {start:start, end:end}, set);\n ReactTestUtils.renderIntoDocument(instance);\n var rendered = reactComponentExpect(instance)\n .expectRenderedChild()\n .instance();\n return rendered.props.children;\n }\n\n it('should render the whole set if start zero is supplied', function() {\n var fullSet = [\n React.DOM.div( {key:\"A\"} ),\n React.DOM.div( {key:\"B\"} ),\n React.DOM.div( {key:\"C\"} )\n ];\n var children = renderAndSlice(fullSet, 0);\n expect(children).toEqual({\n '{A}': fullSet[0],\n '{B}': fullSet[1],\n '{C}': fullSet[2]\n });\n });\n\n it('should render the remaining set if no end index is supplied', function() {\n var fullSet = [\n React.DOM.div( {key:\"A\"} ),\n React.DOM.div( {key:\"B\"} ),\n React.DOM.div( {key:\"C\"} )\n ];\n var children = renderAndSlice(fullSet, 1);\n expect(children).toEqual({\n '{B}': fullSet[1],\n '{C}': fullSet[2]\n });\n });\n\n it('should exclude everything at or after the end index', function() {\n var fullSet = [\n React.DOM.div( {key:\"A\"} ),\n React.DOM.div( {key:\"B\"} ),\n React.DOM.div( {key:\"C\"} ),\n React.DOM.div( {key:\"D\"} )\n ];\n var children = renderAndSlice(fullSet, 1, 2);\n expect(children).toEqual({\n '{B}': fullSet[1]\n });\n });\n\n it('should allow static children to be sliced', function() {\n var a = React.DOM.div(null );\n var b = React.DOM.div(null );\n var c = React.DOM.div(null );\n\n var instance = Partial( {start:1, end:2}, a,b,c);\n ReactTestUtils.renderIntoDocument(instance);\n var rendered = reactComponentExpect(instance)\n .expectRenderedChild()\n .instance();\n\n expect(rendered.props.children).toEqual({\n '[1]': b\n });\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/sliceChildren-test\", module);\n", -"utils/__tests__/traverseAllChildren-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @emails react-core\n * @jsx React.DOM\n */\n\n\"use strict\";\n\ndescribe('traverseAllChildren', function() {\n var traverseAllChildren;\n var React;\n beforeEach(function() {\n traverseAllChildren = require(\"../../traverseAllChildren\");\n React = require(\"../../React\");\n });\n\n\n it('should support identity for simple', function() {\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var simpleKid = React.DOM.span( {key:\"simple\"} );\n\n // Jasmine doesn't provide a way to test that the fn was invoked with scope.\n var instance = React.DOM.div(null, simpleKid);\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n simpleKid,\n '{simple}',\n 0\n );\n expect(traverseContext.length).toEqual(1);\n });\n\n it('should treat single arrayless child as being in array', function() {\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var simpleKid = React.DOM.span(null );\n var instance = React.DOM.div(null, simpleKid);\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n simpleKid,\n '[0]',\n 0\n );\n expect(traverseContext.length).toEqual(1);\n });\n\n it('should treat single child in array as expected', function() {\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var simpleKid = React.DOM.span(null );\n var instance = React.DOM.div(null, [simpleKid]);\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n simpleKid,\n '[0]',\n 0\n );\n expect(traverseContext.length).toEqual(1);\n });\n\n it('should be called for each child', function() {\n var zero = React.DOM.div( {key:\"keyZero\"} );\n var one = null;\n var two = React.DOM.div( {key:\"keyTwo\"} );\n var three = null;\n var four = React.DOM.div( {key:\"keyFour\"} );\n\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var instance = (\n React.DOM.div(null, \n zero,\n one,\n two,\n three,\n four\n )\n );\n\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n zero,\n '{keyZero}',\n 0\n );\n expect(traverseFn).toHaveBeenCalledWith(traverseContext, one, '[1]', 1);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n two,\n '{keyTwo}',\n 2\n );\n expect(traverseFn).toHaveBeenCalledWith(traverseContext, three, '[3]', 3);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n four,\n '{keyFour}',\n 4\n );\n });\n\n // Todo: test that nums/strings are converted to ReactComponents.\n\n it('should be called for each child in nested structure', function() {\n var zero = React.DOM.div( {key:\"keyZero\"} );\n var one = null;\n var two = React.DOM.div( {key:\"keyTwo\"} );\n var three = null;\n var four = React.DOM.div( {key:\"keyFour\"} );\n var five = React.DOM.div( {key:\"keyFiveCompletelyIgnored\"} );\n // Name precedence is as follows:\n // 1. JavaScript Object key if in a JavaScript object:\n // 2. If grouped in an Array, the `key` attribute.\n // 3. The array index if in a JavaScript Array.\n\n\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var instance = (\n React.DOM.div(null, \n [{\n firstHalfKey: [zero, one, two],\n secondHalfKey: [three, four],\n keyFive: five\n }]\n )\n );\n\n traverseAllChildren(instance.props.children, traverseFn, traverseContext);\n expect(traverseFn.calls.length).toBe(6);\n expect(traverseContext.length).toEqual(6);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n zero,\n '[0]{firstHalfKey}{keyZero}',\n 0\n );\n\n expect(traverseFn)\n .toHaveBeenCalledWith(traverseContext, one, '[0]{firstHalfKey}[1]', 1);\n\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n two,\n '[0]{firstHalfKey}{keyTwo}',\n 2\n );\n\n expect(traverseFn)\n .toHaveBeenCalledWith(traverseContext, three, '[0]{secondHalfKey}[0]', 3);\n\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n four,\n '[0]{secondHalfKey}{keyFour}',\n 4\n );\n\n expect(traverseFn)\n .toHaveBeenCalledWith(traverseContext, five, '[0]{keyFive}', 5);\n });\n\n it('should retain key across two mappings', function() {\n var zeroForceKey = React.DOM.div( {key:\"keyZero\"} );\n var oneForceKey = React.DOM.div( {key:\"keyOne\"} );\n var traverseContext = [];\n var traverseFn =\n jasmine.createSpy().andCallFake(function (context, kid, key, index) {\n context.push(true);\n });\n\n var forcedKeys = (\n React.DOM.div(null, \n zeroForceKey,\n oneForceKey\n )\n );\n\n traverseAllChildren(forcedKeys.props.children, traverseFn, traverseContext);\n expect(traverseContext.length).toEqual(2);\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n zeroForceKey,\n '{keyZero}',\n 0\n );\n expect(traverseFn).toHaveBeenCalledWith(\n traverseContext,\n oneForceKey,\n '{keyOne}',\n 1\n );\n });\n\n});\n\nrequire(\"../../mock-modules\").register(\"utils/__tests__/traverseAllChildren-test\", module);\n", -"vendor/error/__tests__/erx-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Copyright 2004-present Facebook. All Rights Reserved.\n *\n * @emails catchen@fb.com\n * @emails javascript@lists.facebook.com\n */\n\nrequire(\"../../../mock-modules\")\n .dontMock('erx')\n .dontMock('ex');\n\ndescribe('erx', function() {\n var erx = require(\"../../../erx\");\n var ex = require(\"../../../ex\");\n\n it('should always reverse ex if placeholder and argument match', function() {\n expect(erx(ex('zero argument'))).toEqual(['zero argument']);\n expect(erx(ex('one argument: %s', 'one')))\n .toEqual(['one argument: %s', 'one']);\n expect(erx(ex('two arguments: %s, %s', 'one', 2)))\n .toEqual(['two arguments: %s, %s', 'one', '2']);\n expect(erx(ex('three arguments: %s, %s, %s', 'one', 2, { value: 3 })))\n .toEqual(['three arguments: %s, %s, %s', 'one', '2', '[object Object]']);\n });\n\n it('should be idempotent', function() {\n var messageWithParams = erx(ex('one argument: %s', 'one'));\n expect(messageWithParams).toEqual(erx(messageWithParams));\n });\n\n it('should treat plain text as it was ex-ed with no argument', function() {\n expect(erx('plain text')).toEqual(['plain text']);\n });\n\n it('should work when text was appended/prepended to ex-ed text', function() {\n expect(erx('prepended text|' + ex('zero argument') + '|appended text'))\n .toEqual(['prepended text|zero argument|appended text']);\n expect(erx(\n 'prepended text|' +\n ex('one argument: %s', 'one') +\n '|appended text'\n )).toEqual(['prepended text|one argument: %s|appended text', 'one']);\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"vendor/error/__tests__/erx-test\", module);\n", -"vendor/error/__tests__/ex-test":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Copyright 2004-present Facebook. All Rights Reserved.\n *\n * @emails catchen@fb.com\n * @emails javascript@lists.facebook.com\n */\n\nrequire(\"../../../mock-modules\")\n .dontMock('ex');\n\ndescribe('ex', function() {\n var ex = require(\"../../../ex\");\n\n it('should convert whatever arguments into one string', function() {\n expect(typeof ex('zero argument')).toEqual('string');\n expect(typeof ex('one argument: %s', 'one')).toEqual('string');\n expect(typeof ex('two arguments: %s, %s', 'one', 2))\n .toEqual('string');\n expect(typeof ex('three arguments: %s, %s, %s', 'one', 2, { value: 3 }))\n .toEqual('string');\n });\n\n it('should handle placeholder and argument number mismatch', function() {\n expect(typeof ex('zero placeholder and one argument', 'one'))\n .toEqual('string');\n expect(typeof ex('one placeholder and zero argument: %s'))\n .toEqual('string');\n });\n});\n\nrequire(\"../../../mock-modules\").register(\"vendor/error/__tests__/ex-test\", module);\n", -"test/phantomjs-shims":"(function() {\n\nvar Ap = Array.prototype;\nvar slice = Ap.slice;\nvar Fp = Function.prototype;\n\nif (!Fp.bind) {\n // PhantomJS doesn't support Function.prototype.bind natively, so\n // polyfill it whenever this module is required.\n Fp.bind = function(context) {\n var func = this;\n var args = slice.call(arguments, 1);\n\n function bound() {\n var invokedAsConstructor = func.prototype && (this instanceof func);\n return func.apply(\n // Ignore the context parameter when invoking the bound function\n // as a constructor. Note that this includes not only constructor\n // invocations using the new keyword but also calls to base class\n // constructors such as BaseClass.call(this, ...) or super(...).\n !invokedAsConstructor && context || this,\n args.concat(slice.call(arguments))\n );\n }\n\n // The bound function must share the .prototype of the unbound\n // function so that any object created by one constructor will count\n // as an instance of both constructors.\n bound.prototype = func.prototype;\n\n return bound;\n };\n}\n\n})();\n\nrequire(\"../mock-modules\").register(\"test/phantomjs-shims\", module);\n", -"ReactTestUtils":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactTestUtils\n */\n\nvar EventConstants = require(\"./EventConstants\");\nvar React = require(\"./React\");\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactTextComponent = require(\"./ReactTextComponent\");\nvar ReactMount = require(\"./ReactMount\");\n\nvar mergeInto = require(\"./mergeInto\");\n\nvar topLevelTypes = EventConstants.topLevelTypes;\n\nfunction Event(suffix) {}\n\n/**\n * @class ReactTestUtils\n */\n\n/**\n * Todo: Support the entire DOM.scry query syntax. For now, these simple\n * utilities will suffice for testing purposes.\n * @lends ReactTestUtils\n */\nvar ReactTestUtils = {\n renderIntoDocument: function(instance) {\n var div = document.createElement('div');\n document.documentElement.appendChild(div);\n return React.renderComponent(instance, div);\n },\n\n isComponentOfType: function(inst, type) {\n return !!(\n inst &&\n ReactComponent.isValidComponent(inst) &&\n inst.constructor === type.componentConstructor\n );\n },\n\n isDOMComponent: function(inst) {\n return !!(inst &&\n ReactComponent.isValidComponent(inst) &&\n !!inst.tagName);\n },\n\n isCompositeComponent: function(inst) {\n return !!(\n inst &&\n ReactComponent.isValidComponent(inst) &&\n typeof inst.render === 'function' &&\n typeof inst.setState === 'function' &&\n typeof inst.updateComponent === 'function'\n );\n },\n\n isCompositeComponentWithType: function(inst, type) {\n return !!(ReactTestUtils.isCompositeComponent(inst) &&\n (inst.constructor === type.componentConstructor ||\n inst.constructor === type));\n },\n\n isTextComponent: function(inst) {\n return inst instanceof ReactTextComponent;\n },\n\n findAllInRenderedTree: function(inst, test) {\n if (!inst) {\n return [];\n }\n var ret = test(inst) ? [inst] : [];\n if (ReactTestUtils.isDOMComponent(inst)) {\n var renderedChildren = inst._renderedChildren;\n var key;\n for (key in renderedChildren) {\n if (!renderedChildren.hasOwnProperty(key)) {\n continue;\n }\n ret = ret.concat(\n ReactTestUtils.findAllInRenderedTree(renderedChildren[key], test)\n );\n }\n } else if (ReactTestUtils.isCompositeComponent(inst)) {\n ret = ret.concat(\n ReactTestUtils.findAllInRenderedTree(inst._renderedComponent, test)\n );\n }\n return ret;\n },\n\n /**\n * Finds all instance of components in the rendered tree that are DOM\n * components with the class name matching `className`.\n * @return an array of all the matches.\n */\n scryRenderedDOMComponentsWithClass: function(root, className) {\n return ReactTestUtils.findAllInRenderedTree(root, function(inst) {\n var instClassName = inst.props.className;\n return ReactTestUtils.isDOMComponent(inst) && (\n instClassName &&\n (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1\n );\n });\n },\n\n /**\n * Like scryRenderedDOMComponentsWithClass but expects there to be one result,\n * and returns that one result, or throws exception if there is any other\n * number of matches besides one.\n * @return {!ReactDOMComponent} The one match.\n */\n findRenderedDOMComponentWithClass: function(root, className) {\n var all =\n ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className);\n if (all.length !== 1) {\n throw new Error('Did not find exactly one match for class:' + className);\n }\n return all[0];\n },\n\n\n /**\n * Finds all instance of components in the rendered tree that are DOM\n * components with the tag name matching `tagName`.\n * @return an array of all the matches.\n */\n scryRenderedDOMComponentsWithTag: function(root, tagName) {\n return ReactTestUtils.findAllInRenderedTree(root, function(inst) {\n return ReactTestUtils.isDOMComponent(inst) &&\n inst.tagName === tagName.toUpperCase();\n });\n },\n\n /**\n * Like scryRenderedDOMComponentsWithTag but expects there to be one result,\n * and returns that one result, or throws exception if there is any other\n * number of matches besides one.\n * @return {!ReactDOMComponent} The one match.\n */\n findRenderedDOMComponentWithTag: function(root, tagName) {\n var all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName);\n if (all.length !== 1) {\n throw new Error('Did not find exactly one match for tag:' + tagName);\n }\n return all[0];\n },\n\n\n /**\n * Finds all instances of components with type equal to `componentType`.\n * @return an array of all the matches.\n */\n scryRenderedComponentsWithType: function(root, componentType) {\n return ReactTestUtils.findAllInRenderedTree(root, function(inst) {\n return ReactTestUtils.isCompositeComponentWithType(inst, componentType);\n });\n },\n\n /**\n * Same as `scryRenderedComponentsWithType` but expects there to be one result\n * and returns that one result, or throws exception if there is any other\n * number of matches besides one.\n * @return {!ReactComponent} The one match.\n */\n findRenderedComponentWithType: function(root, componentType) {\n var all = ReactTestUtils.scryRenderedComponentsWithType(\n root,\n componentType\n );\n if (all.length !== 1) {\n throw new Error(\n 'Did not find exactly one match for componentType:' + componentType\n );\n }\n return all[0];\n },\n\n /**\n * Simulates a top level event being dispatched from a raw event that occured\n * on and `Element` node.\n * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`\n * @param {!Element} node The dom to simulate an event occurring on.\n * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent.\n */\n simulateEventOnNode: function(topLevelType, node, fakeNativeEvent) {\n var virtualHandler =\n ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(\n topLevelType\n );\n fakeNativeEvent.target = node;\n virtualHandler(fakeNativeEvent);\n },\n\n /**\n * Simulates a top level event being dispatched from a raw event that occured\n * on the `ReactDOMComponent` `comp`.\n * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`.\n * @param comp {!ReactDOMComponent}\n * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent.\n */\n simulateEventOnDOMComponent: function(topLevelType, comp, fakeNativeEvent) {\n var reactRootID = comp._rootNodeID || comp._rootDomId;\n if (!reactRootID) {\n throw new Error('Simulating event on non-rendered component');\n }\n var virtualHandler =\n ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(\n topLevelType\n );\n var node = ReactMount.getNode(reactRootID);\n fakeNativeEvent.target = node;\n /* jsdom is returning nodes without id's - fixing that issue here. */\n ReactMount.setID(node, reactRootID);\n virtualHandler(fakeNativeEvent);\n },\n\n nativeTouchData: function(x, y) {\n return {\n touches: [\n {pageX: x, pageY: y}\n ]\n };\n },\n\n Simulate: null // Will populate\n};\n\n/**\n * Exports:\n *\n * - `ReactTestUtils.Simulate.click(Element/ReactDOMComponent)`\n * - `ReactTestUtils.Simulate.mouseMove(Element/ReactDOMComponent)`\n * - `ReactTestUtils.Simulate.mouseIn/ReactDOMComponent)`\n * - `ReactTestUtils.Simulate.mouseOut(Element/ReactDOMComponent)`\n * - ... (All keys from `EventConstants.topLevelTypes`)\n *\n * Note: Top level event types are a subset of the entire set of handler types\n * (which include a broader set of \"synthetic\" events). For example, onDragDone\n * is a synthetic event. You certainly may write test cases for these event\n * types, but it doesn't make sense to simulate them at this low of a level. In\n * this case, the way you test an `onDragDone` event is by simulating a series\n * of `mouseMove`/ `mouseDown`/`mouseUp` events - Then, a synthetic event of\n * type `onDragDone` will be constructed and dispached through your system\n * automatically.\n */\n\nfunction makeSimulator(eventType) {\n return function(domComponentOrNode, nativeEventData) {\n var fakeNativeEvent = new Event(eventType);\n mergeInto(fakeNativeEvent, nativeEventData);\n if (ReactTestUtils.isDOMComponent(domComponentOrNode)) {\n ReactTestUtils.simulateEventOnDOMComponent(\n eventType,\n domComponentOrNode,\n fakeNativeEvent\n );\n } else if (!!domComponentOrNode.tagName) {\n // Will allow on actual dom nodes.\n ReactTestUtils.simulateEventOnNode(\n eventType,\n domComponentOrNode,\n fakeNativeEvent\n );\n }\n };\n}\n\nReactTestUtils.Simulate = {};\nvar eventType;\nfor (eventType in topLevelTypes) {\n // Event type is stored as 'topClick' - we transform that to 'click'\n var convenienceName = eventType.indexOf('top') === 0 ?\n eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType;\n /**\n * @param {!Element || ReactDOMComponent} domComponentOrNode\n * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent.\n */\n ReactTestUtils.Simulate[convenienceName] = makeSimulator(eventType);\n}\n\nmodule.exports = ReactTestUtils;\n\nrequire(\"./mock-modules\").register(\"ReactTestUtils\", module);\n", -"reactComponentExpect":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule reactComponentExpect\n * @nolint\n */\n\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactTestUtils = require(\"./ReactTestUtils\");\n\nvar mergeInto = require(\"./mergeInto\");\n\nfunction reactComponentExpect(instance) {\n if (instance instanceof reactComponentExpect) {\n return instance;\n }\n\n if (!(this instanceof reactComponentExpect)) {\n return new reactComponentExpect(instance);\n }\n\n this._instance = instance;\n this.toBeValidReactComponent();\n}\n\nmergeInto(reactComponentExpect.prototype, {\n // Getters -------------------------------------------------------------------\n\n /**\n * @instance: Retrieves the backing instance.\n */\n instance: function() {\n return this._instance;\n },\n\n /**\n * There are two types of components in the world.\n * - A component created via React.createClass() - Has a single child\n * subComponent - the return value from the .render() function. This\n * function @subComponent expects that this._instance is component created\n * with React.createClass().\n * - A primitive DOM component - which has many renderedChildren, each of\n * which may have a name that is unique with respect to its siblings. This\n * method will fail if this._instance is a primitive component.\n *\n * TL;DR: An instance may have a subComponent (this._renderedComponent) or\n * renderedChildren, but never both. Neither will actually show up until you\n * render the component (simply instantiating is not enough).\n */\n expectRenderedChild: function() {\n this.toBeCompositeComponent();\n return new reactComponentExpect(this.instance()._renderedComponent);\n },\n\n /**\n * The nth child of a DOMish component instance that is not falsy.\n */\n expectRenderedChildAt: function(childIndex) {\n // Currently only dom components have arrays of children, but that will\n // change soon.\n this.toBeDOMComponent();\n var renderedChildren = this.instance()._renderedChildren || {};\n var nonEmptyCount = 0;\n var name;\n for (name in renderedChildren) {\n if (!renderedChildren.hasOwnProperty(name)) {\n continue;\n }\n if (renderedChildren[name]) {\n if (nonEmptyCount === childIndex) {\n return new reactComponentExpect(renderedChildren[name]);\n }\n nonEmptyCount++;\n }\n }\n throw new Error('Child:' + childIndex + ' is not found');\n },\n\n toBeDOMComponentWithChildCount: function(n) {\n this.toBeDOMComponent();\n expect(this.instance()._renderedChildren).toBeTruthy();\n var len = Object.keys(this.instance()._renderedChildren).length;\n expect(len).toBe(n);\n return this;\n },\n\n toBeDOMComponentWithNoChildren: function() {\n this.toBeDOMComponent();\n expect(this.instance()._renderedChildren).toBeFalsy();\n return this;\n },\n\n // Matchers ------------------------------------------------------------------\n\n toBeComponentOfType: function(convenienceConstructor) {\n expect(ReactTestUtils.isComponentOfType(\n this.instance(),\n convenienceConstructor\n )).toBe(true);\n return this;\n },\n\n /**\n * A component that is created with React.createClass. Just duck typing\n * here.\n */\n toBeCompositeComponent: function() {\n this.toBeValidReactComponent();\n expect(ReactTestUtils.isCompositeComponent(this.instance())).toBe(true);\n return this;\n },\n\n toBeCompositeComponentWithType: function(convenienceConstructor) {\n expect(ReactTestUtils.isCompositeComponentWithType(\n this.instance(),\n convenienceConstructor\n )).toBe(true);\n return this;\n },\n\n toBeTextComponent: function() {\n expect(ReactTestUtils.isTextComponent(this.instance())).toBe(true);\n return this;\n },\n\n /**\n * Falsy values are valid components - the vanished component that is.\n */\n toBeValidReactComponent: function() {\n expect(ReactComponent.isValidComponent(this.instance())).toBe(true);\n return this;\n },\n\n toBePresent: function() {\n expect(this.instance()).toBeTruthy();\n return this;\n },\n\n /**\n * A terminal type of component representing some virtual dom node. Just duck\n * typing here.\n */\n toBeDOMComponent: function() {\n expect(ReactTestUtils.isDOMComponent(this.instance())).toBe(true);\n return this;\n },\n\n /**\n * @deprecated\n * @see toBeComponentOfType\n */\n toBeDOMComponentWithTag: function(tag) {\n this.toBeDOMComponent();\n expect(this.instance().tagName).toBe(tag.toUpperCase());\n return this;\n },\n\n /**\n * Check that internal state values are equal to a state of expected values.\n */\n scalarStateEqual: function(stateNameToExpectedValue) {\n expect(this.instance()).toBeTruthy();\n for (var stateName in stateNameToExpectedValue) {\n if (!stateNameToExpectedValue.hasOwnProperty(stateName)) {\n continue;\n }\n expect(this.instance().state[stateName])\n .toEqual(stateNameToExpectedValue[stateName]);\n }\n return this;\n },\n\n /**\n * Check a set of props are equal to a set of expected values - only works\n * with scalars.\n */\n scalarPropsEqual: function(propNameToExpectedValue) {\n expect(this.instance()).toBeTruthy();\n for (var propName in propNameToExpectedValue) {\n if (!propNameToExpectedValue.hasOwnProperty(propName)) {\n continue;\n }\n expect(this.instance().props[propName])\n .toEqual(propNameToExpectedValue[propName]);\n }\n return this;\n }\n});\n\nmodule.exports = reactComponentExpect;\n\nrequire(\"./mock-modules\").register(\"reactComponentExpect\", module);\n", -"mocks":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule mocks\n */\n\nfunction isA(typeName, value) {\n return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';\n}\n\nfunction getType(ref) {\n if (isA('RegExp', ref)) {\n return 'regexp';\n }\n\n if (isA('Array', ref)) {\n return 'array';\n }\n\n if (isA('Function', ref)) {\n return 'function';\n }\n\n if (isA('Object', ref)) {\n return 'object';\n }\n\n // consider number and string fields to be constants that we want to\n // pick up as they are\n if (isA('Number', ref) || isA('String', ref)) {\n return 'constant';\n }\n\n return null;\n}\n\nfunction makeComponent(metadata) {\n switch (metadata.type) {\n case 'object':\n return {};\n\n case 'array':\n return [];\n\n case 'regexp':\n return new RegExp();\n\n case 'constant':\n return metadata.value;\n\n case 'function':\n var defaultReturnValue;\n var specificReturnValues = [];\n var mockImpl;\n var isReturnValueLastSet = false;\n var calls = [];\n var instances = [];\n var prototype =\n (metadata.members && metadata.members.prototype &&\n metadata.members.prototype.members) || {};\n\n var f = function() {\n global.dirtyMocks.push(f);\n\n instances.push(this);\n calls.push(Array.prototype.slice.call(arguments));\n if (this instanceof arguments.callee) {\n // This is probably being called as a constructor\n for (var slot in prototype) {\n // Copy prototype methods to the instance to make\n // it easier to interact with mock instance call and\n // return values\n if (prototype[slot].type == 'function') {\n var protoImpl = this[slot];\n this[slot] = generateFromMetadata(prototype[slot]);\n this[slot]._protoImpl = protoImpl;\n }\n }\n\n // Run the mock constructor implementation\n mockImpl && mockImpl.apply(this, arguments);\n return;\n }\n\n var returnValue;\n // If return value is last set, either specific or default, i.e.\n // mockReturnValue()/mockDefaultReturnValue() is called and no\n // mockImplementation() is called after that.\n // use the set return value.\n if (isReturnValueLastSet) {\n returnValue = specificReturnValues.shift();\n if (returnValue === undefined) {\n returnValue = defaultReturnValue;\n }\n }\n\n // If mockImplementation() is last set, or specific return values\n // are used up, use the mock implementation.\n if (mockImpl && returnValue === undefined) {\n return mockImpl.apply(this, arguments);\n }\n\n // Otherwise use prototype implementation\n if (returnValue === undefined && arguments.callee._protoImpl) {\n return arguments.callee._protoImpl.apply(this, arguments);\n }\n\n return returnValue;\n };\n\n f._isMockFunction = true;\n\n f.mock = {\n calls : calls,\n instances : instances\n };\n\n f.mockClear = function() {\n calls.length = 0;\n instances.length = 0;\n };\n\n f.mockReturnValue = function(value) {\n // next function call will return this value or default return value\n isReturnValueLastSet = true;\n specificReturnValues.push(value);\n return f;\n };\n\n f.mockDefaultReturnValue = function(value) {\n // next function call will return specified return value or this one\n isReturnValueLastSet = true;\n defaultReturnValue = value;\n return f;\n };\n\n f.mockImplementation = function(fn) {\n // next function call will use mock implementation return value\n isReturnValueLastSet = false;\n mockImpl = fn;\n return f;\n };\n\n f.mockReturnThis = function() {\n return f.mockImplementation(function() {\n return this;\n });\n };\n\n f._getMockImplementation = function() {\n return mockImpl;\n };\n\n if (metadata.mockImpl) {\n f.mockImplementation(metadata.mockImpl);\n }\n\n return f;\n }\n\n throw new Error('Unrecognized type ' + metadata.type);\n}\n\nfunction generateFromMetadata(_metadata) {\n var callbacks = [];\n var refs = {};\n\n function generateMock(metadata) {\n var mock = makeComponent(metadata);\n if (metadata.ref_id != null) {\n refs[metadata.ref_id] = mock;\n }\n\n function getRefCallback(slot, ref) {\n return function() {\n mock[slot] = refs[ref];\n };\n }\n\n for (var slot in metadata.members) {\n var slotMetadata = metadata.members[slot];\n if (slotMetadata.ref != null) {\n callbacks.push(getRefCallback(slot, slotMetadata.ref));\n } else {\n mock[slot] = generateMock(slotMetadata);\n }\n }\n\n return mock;\n }\n\n var mock = generateMock(_metadata);\n callbacks.forEach(function(setter) {\n setter();\n });\n\n return mock;\n}\n\n\nfunction _getMetadata(component, _refs) {\n var refs = _refs || [];\n\n // This is a potential performance drain, since the whole list is scanned\n // for every component\n var ref = refs.indexOf(component);\n if (ref > -1) {\n return {ref: ref};\n }\n\n var type = getType(component);\n if (!type) {\n return null;\n }\n\n var metadata = {type : type};\n if (type == 'constant') {\n metadata.value = component;\n return metadata;\n } else if (type == 'function') {\n if (component._isMockFunction) {\n metadata.mockImpl = component._getMockImplementation();\n }\n }\n\n metadata.ref_id = refs.length;\n refs.push(component);\n\n var members = null;\n\n function addMember(slot, data) {\n if (!data) {\n return;\n }\n if (!members) {\n members = {};\n }\n members[slot] = data;\n }\n\n // Leave arrays alone\n if (type != 'array') {\n for (var slot in component) {\n if (slot.charAt(0) == '_' ||\n (type == 'function' && component._isMockFunction &&\n slot.match(/^mock/))) {\n continue;\n }\n\n if (component.hasOwnProperty(slot) ||\n (type == 'object' && component[slot] != Object.prototype[slot])) {\n addMember(slot, _getMetadata(component[slot], refs));\n }\n }\n\n // If component is native code function, prototype might be undefined\n if (type == 'function' && component.prototype) {\n var prototype = _getMetadata(component.prototype, refs);\n if (prototype && prototype.members) {\n addMember('prototype', prototype);\n }\n }\n }\n\n if (members) {\n metadata.members = members;\n }\n\n return metadata;\n}\n\nfunction removeUnusedRefs(metadata) {\n function visit(md, f) {\n f(md);\n if (md.members) {\n for (var slot in md.members) {\n visit(md.members[slot], f);\n }\n }\n }\n\n var usedRefs = {};\n visit(metadata, function(md) {\n if (md.ref != null) {\n usedRefs[md.ref] = true;\n }\n });\n\n visit(metadata, function(md) {\n if (!usedRefs[md.ref_id]) {\n delete md.ref_id;\n }\n });\n}\n\nvar global = Function(\"return this\")();\nglobal.dirtyMocks = global.dirtyMocks || [];\n\nmodule.exports = {\n /**\n * Invokes the .mockClear method of all function mocks that have been\n * called since the last time clear was called.\n */\n clear: function() {\n var old = global.dirtyMocks;\n global.dirtyMocks = [];\n old.forEach(function(mock) {\n mock.mockClear();\n });\n },\n\n /**\n * Generates a mock based on the given metadata. Mocks treat functions\n * specially, and all mock functions have additional members, described in the\n * documentation for getMockFunction in this module.\n *\n * One important note: function prototoypes are handled specially by this\n * mocking framework. For functions with prototypes, when called as a\n * constructor, the mock will install mocked function members on the instance.\n * This allows different instances of the same constructor to have different\n * values for its mocks member and its return values.\n *\n * @param metadata Metadata for the mock in the schema returned by the\n * getMetadata method of this module.\n *\n */\n generateFromMetadata: generateFromMetadata,\n\n /**\n * Inspects the argument and returns its schema in the following recursive\n * format:\n * {\n * type: ...\n * members : {}\n * }\n *\n * Where type is one of 'array', 'object', 'function', or 'ref', and members\n * is an optional dictionary where the keys are member names and the values\n * are metadata objects. Function prototypes are defined simply by defining\n * metadata for the member.prototype of the function. The type of a function\n * prototype should always be \"object\". For instance, a simple class might be\n * defined like this:\n *\n * {\n * type: 'function',\n * members: {\n * staticMethod: {type: 'function'},\n * prototype: {\n * type: 'object',\n * members: {\n * instanceMethod: {type: 'function'}\n * }\n * }\n * }\n * }\n *\n * Metadata may also contain references to other objects defined within the\n * same metadata object. The metadata for the referent must be marked with\n * 'ref_id' key and an arbitrary value. The referer must be marked with a\n * 'ref' key that has the same value as object with ref_id that it refers to.\n * For instance, this metadata blob:\n * {\n * type: 'object',\n * ref_id: 1,\n * members: {\n * self: {ref: 1}\n * }\n * }\n *\n * defines an object with a slot named 'self' that refers back to the object.\n *\n * @param component The component for which to retrieve metadata.\n */\n getMetadata: function(component) {\n var metadata = _getMetadata(component);\n // to make it easier to work with mock metadata, only preserve references\n // that are actually used\n removeUnusedRefs(metadata);\n return metadata;\n },\n\n /**\n * Generates a stand-alone function with members that help drive unit tests or\n * confirm expectations. Specifically, functions returned by this method have\n * the following members:\n *\n * .mock:\n * An object with two members, \"calls\", and \"instances\", which are both\n * lists. The items in the \"calls\" list are the arguments with which the\n * function was called. The \"instances\" list stores the value of 'this' for\n * each call to the function. This is useful for retrieving instances from a\n * constructor.\n *\n * .mockReturnValue(value)\n * Pushes the given value onto a FIFO queue of return values for the\n * function.\n *\n * .mockDefaultReturnValue(value)\n * Sets the default return value for the function.\n *\n * .mockImplementation(function)\n * Sets a mock implementation for the function.\n *\n * .mockReturnThis()\n * Syntactic sugar for .mockImplementation(function() {return this;})\n *\n * In case both mockImplementation() and\n * mockReturnValue()/mockDefaultReturnValue() are called. The priority of\n * which to use is based on what is the last call:\n * - if the last call is mockRetrunValue() or mockDefaultReturnValue(),\n * use the specific return specific return value or default return value.\n * If specific return values are used up or no default return value is set,\n * fall back to try mockImplementation();\n * - if the last call is mockImplementation(), run the given implementation\n * and return the result.\n */\n getMockFunction: function() {\n return makeComponent({type: 'function'});\n }\n};\n", -"mock-modules":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule mock-modules\n */\n\nvar mocks = require(\"./mocks\");\nvar exportsRegistry = {};\nvar hasOwn = exportsRegistry.hasOwnProperty;\nvar explicitMockMap = {};\n\nfunction getMock(exports) {\n try {\n return mocks.generateFromMetadata(mocks.getMetadata(exports));\n } catch (err) {\n console.warn(err);\n return exports;\n }\n}\n\n// This function should be called at the bottom of any module that might\n// need to be mocked, after the final value of module.exports is known.\nexports.register = function(id, module) {\n exportsRegistry[id] = {\n module: module,\n actual: module.exports,\n mocked: null // Filled in lazily later.\n };\n\n // If doMock or doNotMock was called earlier, before the module was\n // registered, then the choice should have been recorded in\n // explicitMockMap. Now that the module is registered, we can finally\n // fulfill the request.\n if (hasOwn.call(explicitMockMap, id)) {\n if (explicitMockMap[id]) {\n doMock(id);\n } else {\n doNotMock(id);\n }\n }\n\n return exports;\n};\n\nfunction resetEntry(id) {\n if (hasOwn.call(exportsRegistry, id)) {\n delete exportsRegistry[id].module.exports;\n delete exportsRegistry[id];\n }\n}\n\nexports.dumpCache = function() {\n require(\"./mocks\").clear();\n\n // Deleting module.exports will cause the module to be lazily\n // reevaluated the next time it is required.\n for (var id in exportsRegistry) {\n resetEntry(id);\n }\n\n return exports;\n};\n\n// Call this function to ensure that require(id) returns the actual\n// exports object created by the module.\nfunction doNotMock(id) {\n explicitMockMap[id] = false;\n\n var entry = exportsRegistry[id];\n if (entry && entry.module && entry.actual) {\n entry.module.exports = entry.actual;\n }\n\n return exports;\n}\n\n// Call this function to ensure that require(id) returns a mock exports\n// object based on the actual exports object created by the module.\nfunction doMock(id) {\n explicitMockMap[id] = true;\n\n var entry = exportsRegistry[id];\n if (entry && entry.module && entry.actual) {\n // Because mocking can be expensive, create the mock exports object on\n // demand, the first time doMock is called.\n entry.mocked || (entry.mocked = getMock(entry.actual));\n entry.module.exports = entry.mocked;\n }\n\n return exports;\n}\n\nvar global = Function(\"return this\")();\nrequire(\"./test/mock-timers\").installMockTimers(global);\n\n// Exported names are different for backwards compatibility.\nexports.dontMock = doNotMock;\nexports.mock = doMock;\n", -"test/mock-timers":"var mocks = require(\"../mocks\");\n\nvar timers = {};\n// Keep a fake timestamp\n// move on the time when runTimersToTime() is called\nvar now = 0;\n\n// add a timer of type either 'timeout' or 'interval'\nfunction _setTimer(type, callback, delay) {\n var token = null;\n do {\n token = Math.floor(Math.random() * 4294967296) + 1;\n } while (timers[token]);\n timers[token] = {\n type: type,\n callback: callback,\n // Add some random msecs to the delay to mimic code execution time.\n time: now + delay + Math.floor(Math.random() * 5),\n interval: (type == 'interval' ? delay : 0)\n };\n return token;\n}\n\n// clear a timer of type either 'timeout' or 'interval'\nfunction _clearTimer(type, token) {\n if (timers[token] && timers[token].type == type) {\n delete timers[token];\n }\n}\n\nfunction _setTimeout(callback, delay) {\n return _setTimer('timeout', callback, delay);\n}\n\nfunction _setInterval(callback, delay) {\n return _setTimer('interval', callback, delay);\n}\n\nfunction _clearTimeout(token) {\n _clearTimer('timeout', token);\n}\n\nfunction _clearInterval(token) {\n _clearTimer('interval', token);\n}\n\n// Run timer of given token\nfunction _runTimer(token) {\n // Skip non-existing token\n if (timers[token]) {\n if (timers[token].type == 'timeout') {\n // for 'timeout', run callback and delete the timer\n var callback = timers[token].callback;\n delete timers[token];\n callback();\n } else if (timers[token].type == 'interval') {\n // for 'interval', run callback and set the next invoke time\n // Add some random msecs to the delay to mimic code execution time.\n timers[token].time =\n now + timers[token].interval + Math.floor(Math.random() * 5);\n timers[token].callback();\n }\n }\n}\n\nfunction _runTimersOnce() {\n // Invoke all timers once regardsless of the delay\n for (var token in timers) {\n _runTimer(token);\n }\n}\n\nfunction _runTimersToTime(delay) {\n var toRunToken = _getNextTimerToken();\n if (!toRunToken) {\n return;\n }\n\n var minTime = timers[toRunToken].time;\n if (now + delay < minTime) {\n // Termination when there's no more timers to invoke\n now += delay;\n } else {\n // Recursively invoke the next to-run timer\n delay -= (minTime - now);\n now = minTime;\n _runTimer(toRunToken);\n _runTimersToTime(delay);\n }\n}\n\nfunction _runTimersRepeatedly() {\n // Only run a generous 1000 timers and then bail, since we may have entered\n // a loop if we have more than that.\n var max_timers = 1000;\n\n var token;\n for (var ii = 0; ii < max_timers; ii++) {\n token = _getNextTimerToken();\n\n if (!token) {\n break;\n }\n\n _runTimer(token);\n }\n\n if (ii === max_timers) {\n throw new Error(\"More timers still exist after \" + max_timers + \" timers!\");\n }\n}\n\nfunction _clearTimers() {\n for (var token in timers) {\n delete timers[token];\n }\n}\n\nfunction _getNextTimerToken() {\n var nextTimerToken = null;\n var minTime = 31536000000; // One year\n // Find the next to invoke timer\n for (var token in timers) {\n if (timers[token].time < minTime) {\n nextTimerToken = token;\n minTime = timers[token].time;\n }\n }\n return nextTimerToken;\n}\n\nvar mockTimers = {\n setTimeout: _setTimeout,\n clearTimeout: _clearTimeout,\n setInterval: _setInterval,\n clearInterval: _clearInterval,\n\n /**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Iteratively run callbacks in time order during the time from now to\n * now + delay.\n * If one callback register another timer which should be run during now to\n * now + delay, the new timer will also be run in the right order.\n *\n * @param delay\n */\n runTimersToTime: _runTimersToTime,\n\n /**\n * Run all registered timer once. Newly registered timers will not be run.\n */\n runTimersOnce: _runTimersOnce,\n\n /**\n * Iteratively run callbacks until there are no timers left to call. Will\n * stop after a maximum number of iterations to avoid infinite loop.\n *\n * @param maximum iterations (optional)\n */\n runTimersRepeatedly: _runTimersRepeatedly,\n\n /**\n * Clear all timers\n */\n clearTimers: _clearTimers,\n\n /**\n * Get the number of remaining timers\n */\n getTimersCount: function() {\n return Object.keys(timers).length;\n }\n};\n\nmodule.exports.installMockTimers = function(window) {\n window._originalTimeouts = {\n setTimeout: window.setTimeout,\n clearTimeout: window.clearTimeout,\n setInterval: window.setInterval,\n clearInterval: window.clearInterval\n };\n window.setTimeout =\n mocks.getMockFunction().mockImplementation(mockTimers.setTimeout);\n window.clearTimeout =\n mocks.getMockFunction().mockImplementation(mockTimers.clearTimeout);\n window.setInterval =\n mocks.getMockFunction().mockImplementation(mockTimers.setInterval);\n window.clearInterval =\n mocks.getMockFunction().mockImplementation(mockTimers.clearInterval);\n window.mockRunTimersOnce =\n mocks.getMockFunction().mockImplementation(mockTimers.runTimersOnce);\n window.mockRunTimersToTime =\n mocks.getMockFunction().mockImplementation(mockTimers.runTimersToTime);\n window.mockRunTimersRepeatedly =\n mocks.getMockFunction().mockImplementation(mockTimers.runTimersRepeatedly);\n window.mockClearTimers =\n mocks.getMockFunction().mockImplementation(mockTimers.clearTimers);\n window.mockGetTimersCount =\n mocks.getMockFunction().mockImplementation(mockTimers.getTimersCount);\n};\n\nmodule.exports.uninstallMockTimers = function(window) {\n window.setTimeout = window._originalTimeouts.setTimeout;\n window.clearTimeout = window._originalTimeouts.clearTimeout;\n window.setInterval = window._originalTimeouts.setInterval;\n window.clearInterval = window._originalTimeouts.clearInterval;\n window._originalTimeouts = undefined;\n window.mockRunTimersOnce = undefined;\n window.mockRunTimersToTime = undefined;\n window.mockRunTimersRepeatedly = undefined;\n window.mockClearTimers = undefined;\n window.mockGetTimersCount = undefined;\n};\n\nrequire(\"../mock-modules\").register(\"test/mock-timers\", module);\n", -"LinkedStateMixin":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule LinkedStateMixin\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar ReactLink = require(\"./ReactLink\");\nvar ReactStateSetters = require(\"./ReactStateSetters\");\n\n/**\n * A simple mixin around ReactLink.forState().\n */\nvar LinkedStateMixin = {\n /**\n * Create a ReactLink that's linked to part of this component's state. The\n * ReactLink will have the current value of this.state[key] and will call\n * setState() when a change is requested.\n *\n * @param {string} key state key to update. Note: you may want to use keyOf()\n * if you're using Google Closure Compiler advanced mode.\n * @return {ReactLink} ReactLink instance linking to the state.\n */\n linkState: function(key) {\n return new ReactLink(\n this.state[key],\n ReactStateSetters.createStateKeySetter(this, key)\n );\n }\n};\n\nmodule.exports = LinkedStateMixin;\n\nrequire(\"./mock-modules\").register(\"LinkedStateMixin\", module);\n", -"React":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule React\n */\n\n\"use strict\";\n\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactCompositeComponent = require(\"./ReactCompositeComponent\");\nvar ReactCurrentOwner = require(\"./ReactCurrentOwner\");\nvar ReactDOM = require(\"./ReactDOM\");\nvar ReactDOMComponent = require(\"./ReactDOMComponent\");\nvar ReactDefaultInjection = require(\"./ReactDefaultInjection\");\nvar ReactInstanceHandles = require(\"./ReactInstanceHandles\");\nvar ReactMount = require(\"./ReactMount\");\nvar ReactMultiChild = require(\"./ReactMultiChild\");\nvar ReactPerf = require(\"./ReactPerf\");\nvar ReactPropTypes = require(\"./ReactPropTypes\");\nvar ReactServerRendering = require(\"./ReactServerRendering\");\nvar ReactTextComponent = require(\"./ReactTextComponent\");\n\nReactDefaultInjection.inject();\n\nvar React = {\n DOM: ReactDOM,\n PropTypes: ReactPropTypes,\n initializeTouchEvents: function(shouldUseTouch) {\n ReactMount.useTouchEvents = shouldUseTouch;\n },\n createClass: ReactCompositeComponent.createClass,\n constructAndRenderComponent: ReactMount.constructAndRenderComponent,\n constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID,\n renderComponent: ReactPerf.measure(\n 'React',\n 'renderComponent',\n ReactMount.renderComponent\n ),\n renderComponentToString: ReactServerRendering.renderComponentToString,\n unmountComponentAtNode: ReactMount.unmountComponentAtNode,\n unmountAndReleaseReactRootNode: ReactMount.unmountAndReleaseReactRootNode,\n isValidClass: ReactCompositeComponent.isValidClass,\n isValidComponent: ReactComponent.isValidComponent,\n __internals: {\n Component: ReactComponent,\n CurrentOwner: ReactCurrentOwner,\n DOMComponent: ReactDOMComponent,\n InstanceHandles: ReactInstanceHandles,\n Mount: ReactMount,\n MultiChild: ReactMultiChild,\n TextComponent: ReactTextComponent\n }\n};\n\n// Version exists only in the open-source version of React, not in Facebook's\n// internal version.\nReact.version = '0.6.0-alpha';\n\nmodule.exports = React;\n\nrequire(\"./mock-modules\").register(\"React\", module);\n", -"ReactLink":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactLink\n * @typechecks static-only\n */\n\n\"use strict\";\n\n/**\n * ReactLink encapsulates a common pattern in which a component wants to modify\n * a prop received from its parent. ReactLink allows the parent to pass down a\n * value coupled with a callback that, when invoked, expresses an intent to\n * modify that value. For example:\n *\n * React.createClass({\n * getInitialState: function() {\n * return {value: ''};\n * },\n * render: function() {\n * var valueLink = new ReactLink(this.state.value, this._handleValueChange);\n * return ;\n * },\n * this._handleValueChange: function(newValue) {\n * this.setState({value: newValue});\n * }\n * });\n *\n * We have provided some sugary mixins to make the creation and\n * consumption of ReactLink easier; see LinkedValueMixin and LinkedStateMixin.\n */\n\n/**\n * @param {*} value current value of the link\n * @param {function} requestChange callback to request a change\n */\nfunction ReactLink(value, requestChange) {\n this.value = value;\n this.requestChange = requestChange;\n}\n\nmodule.exports = ReactLink;\n\nrequire(\"./mock-modules\").register(\"ReactLink\", module);\n", -"ReactTransitionGroup":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactTransitionGroup\n */\n\n\"use strict\";\n\nvar React = require(\"./React\");\nvar ReactTransitionableChild = require(\"./ReactTransitionableChild\");\nvar ReactTransitionKeySet = require(\"./ReactTransitionKeySet\");\n\nvar invariant = require(\"./invariant\");\n\nvar ReactTransitionGroupMixin = {\n componentWillMount: function() {\n // _transitionGroupCurrentKeys stores the union of previous *and* next keys.\n // If this were a component we'd store it as state, however, since this must\n // be a mixin, we need to keep the result of the union of keys in each\n // call to animateChildren() which happens in render(), so we can't\n // call setState() in there.\n this._transitionGroupCurrentKeys = {};\n },\n\n /**\n * Render some children in a transitionable way.\n */\n renderTransitionableChildren: function(sourceChildren) {\n invariant(\n this.getTransitionConfig,\n 'renderTransitionableChildren(): You must provide a ' +\n 'getTransitionConfig() method.'\n );\n\n var children = {};\n var childMapping = ReactTransitionKeySet.getChildMapping(sourceChildren);\n var transitionConfig = this.getTransitionConfig();\n var currentKeys = ReactTransitionKeySet.mergeKeySets(\n this._transitionGroupCurrentKeys,\n ReactTransitionKeySet.getKeySet(sourceChildren)\n );\n\n for (var key in currentKeys) {\n // Here is how we keep the nodes in the DOM. ReactTransitionableChild\n // knows how to hold onto its child if it changes to undefined. Here, we\n // may look up an old key in the new children, and it may switch to\n // undefined. React's reconciler will keep the ReactTransitionableChild\n // instance alive such that we can animate it.\n if (childMapping[key] || transitionConfig.leave) {\n children[key] = ReactTransitionableChild({\n name: transitionConfig.name,\n enter: transitionConfig.enter,\n onDoneLeaving: this._handleDoneLeaving.bind(this, key)\n }, childMapping[key]);\n }\n }\n\n this._transitionGroupCurrentKeys = currentKeys;\n\n return children;\n },\n\n _handleDoneLeaving: function(key) {\n // When the leave animation finishes, we should blow away the actual DOM\n // node.\n delete this._transitionGroupCurrentKeys[key];\n this.forceUpdate();\n }\n};\n\nvar ReactTransitionGroup = React.createClass({\n mixins: [ReactTransitionGroupMixin],\n\n getDefaultProps: function() {\n return {\n transitionEnter: true,\n transitionLeave: true,\n component: React.DOM.span\n };\n },\n\n getTransitionConfig: function() {\n return {\n name: this.props.transitionName,\n enter: this.props.transitionEnter,\n leave: this.props.transitionLeave\n };\n },\n\n render: function() {\n return this.transferPropsTo(\n this.props.component(\n {\n transitionName: null,\n transitionEnter: null,\n transitionLeave: null,\n component: null\n },\n this.renderTransitionableChildren(this.props.children)\n )\n );\n }\n});\n\nmodule.exports = ReactTransitionGroup;\n\nrequire(\"./mock-modules\").register(\"ReactTransitionGroup\", module);\n", -"ReactTransitionKeySet":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @typechecks static-only\n * @providesModule ReactTransitionKeySet\n */\n\n\"use strict\";\n\nvar ReactChildren = require(\"./ReactChildren\");\n\nvar MERGE_KEY_SETS_TAIL_SENTINEL = {};\n\nvar ReactTransitionKeySet = {\n /**\n * Given `this.props.children`, return an object mapping key to child. Just\n * simple syntactic sugar around ReactChildren.map().\n *\n * @param {*} children `this.props.children`\n * @return {object} Mapping of key to child\n */\n getChildMapping: function(children) {\n return ReactChildren.map(children, function(child) {\n return child;\n });\n },\n\n /**\n * Simple syntactic sugar to get an object with keys of all of `children`.\n * Does not have references to the children themselves.\n *\n * @param {*} children `this.props.children`\n * @return {object} Mapping of key to the value \"true\"\n */\n getKeySet: function(children) {\n return ReactChildren.map(children, function() {\n return true;\n });\n },\n\n /**\n * When you're adding or removing children some may be added or removed in the\n * same render pass. We want ot show *both* since we want to simultaneously\n * animate elements in and out. This function takes a previous set of keys\n * and a new set of keys and merges them with its best guess of the correct\n * ordering. In the future we may expose some of the utilities in\n * ReactMultiChild to make this easy, but for now React itself does not\n * directly have this concept of the union of prevChildren and nextChildren\n * so we implement it here.\n *\n * @param {object} prev prev child keys as returned from\n * `ReactTransitionKeySet.getKeySet()`.\n * @param {object} next next child keys as returned from\n * `ReactTransitionKeySet.getKeySet()`.\n * @return {object} a key set that contains all keys in `prev` and all keys\n * in `next` in a reasonable order.\n */\n mergeKeySets: function(prev, next) {\n var keySet = {};\n var prevKeys = Object.keys(prev).concat([MERGE_KEY_SETS_TAIL_SENTINEL]);\n var nextKeys = Object.keys(next).concat([MERGE_KEY_SETS_TAIL_SENTINEL]);\n var i;\n for (i = 0; i < prevKeys.length - 1; i++) {\n var prevKey = prevKeys[i];\n if (next[prevKey]) {\n continue;\n }\n\n // This key is not in the new set. Place it in our\n // best guess where it should go. We do this by searching\n // for a key after the current one in prevKeys that is\n // still in nextKeys, and inserting right before it.\n // I know this is O(n^2), but this is not a particularly\n // hot code path.\n var insertPos = -1;\n\n for (var j = i + 1; j < prevKeys.length; j++) {\n insertPos = nextKeys.indexOf(prevKeys[j]);\n if (insertPos >= 0) {\n break;\n }\n }\n\n // Insert before insertPos\n nextKeys.splice(insertPos, 0, prevKey);\n }\n\n for (i = 0; i < nextKeys.length - 1; i++) {\n keySet[nextKeys[i]] = true;\n }\n\n return keySet;\n }\n};\n\nmodule.exports = ReactTransitionKeySet;\n\nrequire(\"./mock-modules\").register(\"ReactTransitionKeySet\", module);\n", -"ReactTransitionableChild":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactTransitionableChild\n */\n\n\"use strict\";\n\nvar React = require(\"./React\");\nvar CSSCore = require(\"./CSSCore\");\nvar ReactTransitionEvents = require(\"./ReactTransitionEvents\");\n\n// We don't remove the element from the DOM until we receive an animationend or\n// transitionend event. If the user screws up and forgets to add an animation\n// their node will be stuck in the DOM forever, so we detect if an animation\n// does not start and if it doesn't, we just call the end listener immediately.\nvar TICK = 17;\nvar NO_EVENT_TIMEOUT = 5000;\n\nvar noEventListener = null;\n\nif (true) {\n noEventListener = function() {\n console.warn(\n 'transition(): tried to perform an animation without ' +\n 'an animationend or transitionend event after timeout (' +\n NO_EVENT_TIMEOUT + 'ms). You should either disable this ' +\n 'transition in JS or add a CSS animation/transition.'\n );\n };\n}\n\n/**\n * This component is simply responsible for watching when its single child\n * changes to undefined and animating the old child out. It does this by\n * recording its old child in savedChildren when it detects this event is about\n * to occur.\n */\nvar ReactTransitionableChild = React.createClass({\n /**\n * Perform an actual DOM transition. This takes care of a few things:\n * - Adding the second CSS class to trigger the transition\n * - Listening for the finish event\n * - Cleaning up the css (unless noReset is true)\n */\n transition: function(animationType, noReset, finishCallback) {\n var node = this.getDOMNode();\n var className = this.props.name + '-' + animationType;\n var activeClassName = className + '-active';\n var noEventTimeout = null;\n\n var endListener = function() {\n if (true) {\n clearTimeout(noEventTimeout);\n }\n\n // If this gets invoked after the component is unmounted it's OK.\n if (!noReset) {\n // Usually this means you're about to remove the node if you want to\n // leave it in its animated state.\n CSSCore.removeClass(node, className);\n CSSCore.removeClass(node, activeClassName);\n }\n\n ReactTransitionEvents.removeEndEventListener(node, endListener);\n\n // Usually this optional callback is used for informing an owner of\n // a leave animation and telling it to remove the child.\n finishCallback && finishCallback();\n };\n\n ReactTransitionEvents.addEndEventListener(node, endListener);\n\n CSSCore.addClass(node, className);\n\n // Need to do this to actually trigger a transition.\n this.queueClass(activeClassName);\n\n if (true) {\n noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT);\n }\n },\n\n queueClass: function(className) {\n this.classNameQueue.push(className);\n\n if (this.props.runNextTick) {\n this.props.runNextTick(this.flushClassNameQueue);\n return;\n }\n\n if (!this.timeout) {\n this.timeout = setTimeout(this.flushClassNameQueue, TICK);\n }\n },\n\n flushClassNameQueue: function() {\n if (this.isMounted()) {\n this.classNameQueue.forEach(\n CSSCore.addClass.bind(CSSCore, this.getDOMNode())\n );\n }\n this.classNameQueue.length = 0;\n this.timeout = null;\n },\n\n componentWillMount: function() {\n this.classNameQueue = [];\n },\n\n componentWillUnmount: function() {\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n },\n\n componentWillReceiveProps: function(nextProps) {\n if (!nextProps.children && this.props.children) {\n this.savedChildren = this.props.children;\n }\n },\n\n componentDidMount: function(node) {\n if (this.props.enter) {\n this.transition('enter');\n }\n },\n\n componentDidUpdate: function(prevProps, prevState, node) {\n if (prevProps.children && !this.props.children) {\n this.transition('leave', true, this.props.onDoneLeaving);\n }\n },\n\n render: function() {\n return this.props.children || this.savedChildren;\n }\n});\n\nmodule.exports = ReactTransitionableChild;\n\nrequire(\"./mock-modules\").register(\"ReactTransitionableChild\", module);\n", -"ReactDoNotBindDeprecated":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDoNotBindDeprecated\n */\n\n\"use strict\";\n\nvar ReactDoNotBindDeprecated = {\n /**\n * Marks the method for not being automatically bound on component mounting. A\n * couple of reasons you might want to use this:\n *\n * - Automatically supporting the previous behavior in components that were\n * built with previous versions of React.\n * - Tuning performance, by avoiding binding on initial render for methods\n * that are always invoked while being preceded by `this.`. Such binds are\n * unnecessary.\n *\n * React.createClass({\n * handleClick: ReactDoNotBindDeprecated.doNotBind(function() {\n * alert(this.setState); // undefined!\n * }),\n * render: function() {\n * return Jump;\n * }\n * });\n *\n * @param {function} method Method to avoid automatically binding.\n * @public\n */\n doNotBind: function(method) {\n method.__reactDontBind = true; // Mutating\n return method;\n }\n};\n\nmodule.exports = ReactDoNotBindDeprecated;\n\nrequire(\"./mock-modules\").register(\"ReactDoNotBindDeprecated\", module);\n", -"ReactComponent":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactComponent\n */\n\n\"use strict\";\n\nvar ReactComponentEnvironment = require(\"./ReactComponentEnvironment\");\nvar ReactCurrentOwner = require(\"./ReactCurrentOwner\");\nvar ReactOwner = require(\"./ReactOwner\");\nvar ReactUpdates = require(\"./ReactUpdates\");\n\nvar invariant = require(\"./invariant\");\nvar keyMirror = require(\"./keyMirror\");\nvar merge = require(\"./merge\");\n\n/**\n * Every React component is in one of these life cycles.\n */\nvar ComponentLifeCycle = keyMirror({\n /**\n * Mounted components have a DOM node representation and are capable of\n * receiving new props.\n */\n MOUNTED: null,\n /**\n * Unmounted components are inactive and cannot receive new props.\n */\n UNMOUNTED: null\n});\n\n/**\n * Warn if there's no key explicitly set on dynamic arrays of children.\n * This allows us to keep track of children between updates.\n */\n\nvar ownerHasWarned = {};\n\n/**\n * Warn if the component doesn't have an explicit key assigned to it.\n * This component is in an array. The array could grow and shrink or be\n * reordered. All children, that hasn't already been validated, are required to\n * have a \"key\" property assigned to it.\n *\n * @internal\n * @param {ReactComponent} component Component that requires a key.\n */\nfunction validateExplicitKey(component) {\n if (component.__keyValidated__ || component.props.key != null) {\n return;\n }\n component.__keyValidated__ = true;\n\n // We can't provide friendly warnings for top level components.\n if (!ReactCurrentOwner.current) {\n return;\n }\n\n // Name of the component whose render method tried to pass children.\n var currentName = ReactCurrentOwner.current.constructor.displayName;\n if (ownerHasWarned.hasOwnProperty(currentName)) {\n return;\n }\n ownerHasWarned[currentName] = true;\n\n var message = 'Each child in an array should have a unique \"key\" prop. ' +\n 'Check the render method of ' + currentName + '.';\n if (!component.isOwnedBy(ReactCurrentOwner.current)) {\n // Name of the component that originally created this child.\n var childOwnerName =\n component.props.__owner__ &&\n component.props.__owner__.constructor.displayName;\n\n // Usually the current owner is the offender, but if it accepts\n // children as a property, it may be the creator of the child that's\n // responsible for assigning it a key.\n message += ' It was passed a child from ' + childOwnerName + '.';\n }\n\n console.warn(message);\n}\n\n/**\n * Ensure that every component either is passed in a static location or, if\n * if it's passed in an array, has an explicit key property defined.\n *\n * @internal\n * @param {*} component Statically passed child of any type.\n * @return {boolean}\n */\nfunction validateChildKeys(component) {\n if (Array.isArray(component)) {\n for (var i = 0; i < component.length; i++) {\n var child = component[i];\n if (ReactComponent.isValidComponent(child)) {\n validateExplicitKey(child);\n }\n }\n } else if (ReactComponent.isValidComponent(component)) {\n // This component was passed in a valid location.\n component.__keyValidated__ = true;\n }\n}\n\n/**\n * Components are the basic units of composition in React.\n *\n * Every component accepts a set of keyed input parameters known as \"props\" that\n * are initialized by the constructor. Once a component is mounted, the props\n * can be mutated using `setProps` or `replaceProps`.\n *\n * Every component is capable of the following operations:\n *\n * `mountComponent`\n * Initializes the component, renders markup, and registers event listeners.\n *\n * `receiveProps`\n * Updates the rendered DOM nodes given a new set of props.\n *\n * `unmountComponent`\n * Releases any resources allocated by this component.\n *\n * Components can also be \"owned\" by other components. Being owned by another\n * component means being constructed by that component. This is different from\n * being the child of a component, which means having a DOM representation that\n * is a child of the DOM representation of that component.\n *\n * @class ReactComponent\n */\nvar ReactComponent = {\n\n /**\n * @param {?object} object\n * @return {boolean} True if `object` is a valid component.\n * @final\n */\n isValidComponent: function(object) {\n return !!(\n object &&\n typeof object.mountComponentIntoNode === 'function' &&\n typeof object.receiveProps === 'function'\n );\n },\n\n /**\n * Generate a key string that identifies a component within a set.\n *\n * @param {*} component A component that could contain a manual key.\n * @param {number} index Index that is used if a manual key is not provided.\n * @return {string}\n * @internal\n */\n getKey: function(component, index) {\n if (component && component.props && component.props.key != null) {\n // Explicit key\n return '{' + component.props.key + '}';\n }\n // Implicit key determined by the index in the set\n return '[' + index + ']';\n },\n\n /**\n * @internal\n */\n LifeCycle: ComponentLifeCycle,\n\n /**\n * Injected module that provides ability to mutate individual properties.\n * Injected into the base class because many different subclasses need access\n * to this.\n *\n * @internal\n */\n DOMIDOperations: ReactComponentEnvironment.DOMIDOperations,\n\n /**\n * Optionally injectable environment dependent cleanup hook. (server vs.\n * browser etc). Example: A browser system caches DOM nodes based on component\n * ID and must remove that cache entry when this instance is unmounted.\n *\n * @private\n */\n unmountIDFromEnvironment: ReactComponentEnvironment.unmountIDFromEnvironment,\n\n /**\n * The \"image\" of a component tree, is the platform specific (typically\n * serialized) data that represents a tree of lower level UI building blocks.\n * On the web, this \"image\" is HTML markup which describes a construction of\n * low level `div` and `span` nodes. Other platforms may have different\n * encoding of this \"image\". This must be injected.\n *\n * @private\n */\n mountImageIntoNode: ReactComponentEnvironment.mountImageIntoNode,\n\n /**\n * React references `ReactReconcileTransaction` using this property in order\n * to allow dependency injection.\n *\n * @internal\n */\n ReactReconcileTransaction:\n ReactComponentEnvironment.ReactReconcileTransaction,\n\n /**\n * Base functionality for every ReactComponent constructor. Mixed into the\n * `ReactComponent` prototype, but exposed statically for easy access.\n *\n * @lends {ReactComponent.prototype}\n */\n Mixin: merge(ReactComponentEnvironment.Mixin, {\n\n /**\n * Checks whether or not this component is mounted.\n *\n * @return {boolean} True if mounted, false otherwise.\n * @final\n * @protected\n */\n isMounted: function() {\n return this._lifeCycleState === ComponentLifeCycle.MOUNTED;\n },\n\n /**\n * Sets a subset of the props.\n *\n * @param {object} partialProps Subset of the next props.\n * @param {?function} callback Called after props are updated.\n * @final\n * @public\n */\n setProps: function(partialProps, callback) {\n // Merge with `_pendingProps` if it exists, otherwise with existing props.\n this.replaceProps(\n merge(this._pendingProps || this.props, partialProps),\n callback\n );\n },\n\n /**\n * Replaces all of the props.\n *\n * @param {object} props New props.\n * @param {?function} callback Called after props are updated.\n * @final\n * @public\n */\n replaceProps: function(props, callback) {\n invariant(\n !this.props.__owner__,\n 'replaceProps(...): You called `setProps` or `replaceProps` on a ' +\n 'component with an owner. This is an anti-pattern since props will ' +\n 'get reactively updated when rendered. Instead, change the owner\\'s ' +\n '`render` method to pass the correct value as props to the component ' +\n 'where it is created.'\n );\n invariant(\n this.isMounted(),\n 'replaceProps(...): Can only update a mounted component.'\n );\n this._pendingProps = props;\n ReactUpdates.enqueueUpdate(this, callback);\n },\n\n /**\n * Base constructor for all React component.\n *\n * Subclasses that override this method should make sure to invoke\n * `ReactComponent.Mixin.construct.call(this, ...)`.\n *\n * @param {?object} initialProps\n * @param {*} children\n * @internal\n */\n construct: function(initialProps, children) {\n this.props = initialProps || {};\n // Record the component responsible for creating this component.\n this.props.__owner__ = ReactCurrentOwner.current;\n // All components start unmounted.\n this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;\n\n this._pendingProps = null;\n this._pendingCallbacks = null;\n\n // Children can be more than one argument\n var childrenLength = arguments.length - 1;\n if (childrenLength === 1) {\n if (true) {\n validateChildKeys(children);\n }\n this.props.children = children;\n } else if (childrenLength > 1) {\n var childArray = Array(childrenLength);\n for (var i = 0; i < childrenLength; i++) {\n if (true) {\n validateChildKeys(arguments[i + 1]);\n }\n childArray[i] = arguments[i + 1];\n }\n this.props.children = childArray;\n }\n },\n\n /**\n * Initializes the component, renders markup, and registers event listeners.\n *\n * NOTE: This does not insert any nodes into the DOM.\n *\n * Subclasses that override this method should make sure to invoke\n * `ReactComponent.Mixin.mountComponent.call(this, ...)`.\n *\n * @param {string} rootID DOM ID of the root node.\n * @param {ReactReconcileTransaction} transaction\n * @param {number} mountDepth number of components in the owner hierarchy.\n * @return {?string} Rendered markup to be inserted into the DOM.\n * @internal\n */\n mountComponent: function(rootID, transaction, mountDepth) {\n invariant(\n !this.isMounted(),\n 'mountComponent(%s, ...): Can only mount an unmounted component.',\n rootID\n );\n var props = this.props;\n if (props.ref != null) {\n ReactOwner.addComponentAsRefTo(this, props.ref, props.__owner__);\n }\n this._rootNodeID = rootID;\n this._lifeCycleState = ComponentLifeCycle.MOUNTED;\n this._mountDepth = mountDepth;\n // Effectively: return '';\n },\n\n /**\n * Releases any resources allocated by `mountComponent`.\n *\n * NOTE: This does not remove any nodes from the DOM.\n *\n * Subclasses that override this method should make sure to invoke\n * `ReactComponent.Mixin.unmountComponent.call(this)`.\n *\n * @internal\n */\n unmountComponent: function() {\n invariant(\n this.isMounted(),\n 'unmountComponent(): Can only unmount a mounted component.'\n );\n var props = this.props;\n if (props.ref != null) {\n ReactOwner.removeComponentAsRefFrom(this, props.ref, props.__owner__);\n }\n ReactComponent.unmountIDFromEnvironment(this._rootNodeID);\n this._rootNodeID = null;\n this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;\n },\n\n /**\n * Updates the rendered DOM nodes given a new set of props.\n *\n * Subclasses that override this method should make sure to invoke\n * `ReactComponent.Mixin.receiveProps.call(this, ...)`.\n *\n * @param {object} nextProps Next set of properties.\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n receiveProps: function(nextProps, transaction) {\n invariant(\n this.isMounted(),\n 'receiveProps(...): Can only update a mounted component.'\n );\n this._pendingProps = nextProps;\n this._performUpdateIfNecessary(transaction);\n },\n\n /**\n * Call `_performUpdateIfNecessary` within a new transaction.\n *\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n performUpdateIfNecessary: function() {\n var transaction = ReactComponent.ReactReconcileTransaction.getPooled();\n transaction.perform(this._performUpdateIfNecessary, this, transaction);\n ReactComponent.ReactReconcileTransaction.release(transaction);\n },\n\n /**\n * If `_pendingProps` is set, update the component.\n *\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n _performUpdateIfNecessary: function(transaction) {\n if (this._pendingProps == null) {\n return;\n }\n var prevProps = this.props;\n this.props = this._pendingProps;\n this._pendingProps = null;\n this.updateComponent(transaction, prevProps);\n },\n\n /**\n * Updates the component's currently mounted representation.\n *\n * @param {ReactReconcileTransaction} transaction\n * @param {object} prevProps\n * @internal\n */\n updateComponent: function(transaction, prevProps) {\n var props = this.props;\n // If either the owner or a `ref` has changed, make sure the newest owner\n // has stored a reference to `this`, and the previous owner (if different)\n // has forgotten the reference to `this`.\n if (props.__owner__ !== prevProps.__owner__ ||\n props.ref !== prevProps.ref) {\n if (prevProps.ref != null) {\n ReactOwner.removeComponentAsRefFrom(\n this, prevProps.ref, prevProps.__owner__\n );\n }\n // Correct, even if the owner is the same, and only the ref has changed.\n if (props.ref != null) {\n ReactOwner.addComponentAsRefTo(this, props.ref, props.__owner__);\n }\n }\n },\n\n /**\n * Mounts this component and inserts it into the DOM.\n *\n * @param {string} rootID DOM ID of the root node.\n * @param {DOMElement} container DOM element to mount into.\n * @param {boolean} shouldReuseMarkup If true, do not insert markup\n * @final\n * @internal\n * @see {ReactMount.renderComponent}\n */\n mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {\n var transaction = ReactComponent.ReactReconcileTransaction.getPooled();\n transaction.perform(\n this._mountComponentIntoNode,\n this,\n rootID,\n container,\n transaction,\n shouldReuseMarkup\n );\n ReactComponent.ReactReconcileTransaction.release(transaction);\n },\n\n /**\n * @param {string} rootID DOM ID of the root node.\n * @param {DOMElement} container DOM element to mount into.\n * @param {ReactReconcileTransaction} transaction\n * @param {boolean} shouldReuseMarkup If true, do not insert markup\n * @final\n * @private\n */\n _mountComponentIntoNode: function(\n rootID,\n container,\n transaction,\n shouldReuseMarkup) {\n var markup = this.mountComponent(rootID, transaction, 0);\n ReactComponent.mountImageIntoNode(markup, container, shouldReuseMarkup);\n },\n\n /**\n * Checks if this component is owned by the supplied `owner` component.\n *\n * @param {ReactComponent} owner Component to check.\n * @return {boolean} True if `owners` owns this component.\n * @final\n * @internal\n */\n isOwnedBy: function(owner) {\n return this.props.__owner__ === owner;\n },\n\n /**\n * Gets another component, that shares the same owner as this one, by ref.\n *\n * @param {string} ref of a sibling Component.\n * @return {?ReactComponent} the actual sibling Component.\n * @final\n * @internal\n */\n getSiblingByRef: function(ref) {\n var owner = this.props.__owner__;\n if (!owner || !owner.refs) {\n return null;\n }\n return owner.refs[ref];\n }\n })\n};\n\nmodule.exports = ReactComponent;\n\nrequire(\"./mock-modules\").register(\"ReactComponent\", module);\n", -"ReactCompositeComponent":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactCompositeComponent\n */\n\n\"use strict\";\n\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactCurrentOwner = require(\"./ReactCurrentOwner\");\nvar ReactOwner = require(\"./ReactOwner\");\nvar ReactPerf = require(\"./ReactPerf\");\nvar ReactPropTransferer = require(\"./ReactPropTransferer\");\nvar ReactUpdates = require(\"./ReactUpdates\");\n\nvar invariant = require(\"./invariant\");\nvar keyMirror = require(\"./keyMirror\");\nvar merge = require(\"./merge\");\nvar mixInto = require(\"./mixInto\");\nvar objMap = require(\"./objMap\");\n\n/**\n * Policies that describe methods in `ReactCompositeComponentInterface`.\n */\nvar SpecPolicy = keyMirror({\n /**\n * These methods may be defined only once by the class specification or mixin.\n */\n DEFINE_ONCE: null,\n /**\n * These methods may be defined by both the class specification and mixins.\n * Subsequent definitions will be chained. These methods must return void.\n */\n DEFINE_MANY: null,\n /**\n * These methods are overriding the base ReactCompositeComponent class.\n */\n OVERRIDE_BASE: null,\n /**\n * These methods are similar to DEFINE_MANY, except we assume they return\n * objects. We try to merge the keys of the return values of all the mixed in\n * functions. If there is a key conflict we throw.\n */\n DEFINE_MANY_MERGED: null\n});\n\n/**\n * Composite components are higher-level components that compose other composite\n * or native components.\n *\n * To create a new type of `ReactCompositeComponent`, pass a specification of\n * your new class to `React.createClass`. The only requirement of your class\n * specification is that you implement a `render` method.\n *\n * var MyComponent = React.createClass({\n * render: function() {\n * return
Hello World
;\n * }\n * });\n *\n * The class specification supports a specific protocol of methods that have\n * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for\n * more the comprehensive protocol. Any other properties and methods in the\n * class specification will available on the prototype.\n *\n * @interface ReactCompositeComponentInterface\n * @internal\n */\nvar ReactCompositeComponentInterface = {\n\n /**\n * An array of Mixin objects to include when defining your component.\n *\n * @type {array}\n * @optional\n */\n mixins: SpecPolicy.DEFINE_MANY,\n\n /**\n * Definition of prop types for this component.\n *\n * @type {object}\n * @optional\n */\n propTypes: SpecPolicy.DEFINE_ONCE,\n\n\n\n // ==== Definition methods ====\n\n /**\n * Invoked when the component is mounted. Values in the mapping will be set on\n * `this.props` if that prop is not specified (i.e. using an `in` check).\n *\n * This method is invoked before `getInitialState` and therefore cannot rely\n * on `this.state` or use `this.setState`.\n *\n * @return {object}\n * @optional\n */\n getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED,\n\n /**\n * Invoked once before the component is mounted. The return value will be used\n * as the initial value of `this.state`.\n *\n * getInitialState: function() {\n * return {\n * isOn: false,\n * fooBaz: new BazFoo()\n * }\n * }\n *\n * @return {object}\n * @optional\n */\n getInitialState: SpecPolicy.DEFINE_MANY_MERGED,\n\n /**\n * Uses props from `this.props` and state from `this.state` to render the\n * structure of the component.\n *\n * No guarantees are made about when or how often this method is invoked, so\n * it must not have side effects.\n *\n * render: function() {\n * var name = this.props.name;\n * return
Hello, {name}!
;\n * }\n *\n * @return {ReactComponent}\n * @nosideeffects\n * @required\n */\n render: SpecPolicy.DEFINE_ONCE,\n\n\n\n // ==== Delegate methods ====\n\n /**\n * Invoked when the component is initially created and about to be mounted.\n * This may have side effects, but any external subscriptions or data created\n * by this method must be cleaned up in `componentWillUnmount`.\n *\n * @optional\n */\n componentWillMount: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked when the component has been mounted and has a DOM representation.\n * However, there is no guarantee that the DOM node is in the document.\n *\n * Use this as an opportunity to operate on the DOM when the component has\n * been mounted (initialized and rendered) for the first time.\n *\n * @param {DOMElement} rootNode DOM element representing the component.\n * @optional\n */\n componentDidMount: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked before the component receives new props.\n *\n * Use this as an opportunity to react to a prop transition by updating the\n * state using `this.setState`. Current props are accessed via `this.props`.\n *\n * componentWillReceiveProps: function(nextProps) {\n * this.setState({\n * likesIncreasing: nextProps.likeCount > this.props.likeCount\n * });\n * }\n *\n * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop\n * transition may cause a state change, but the opposite is not true. If you\n * need it, you are probably looking for `componentWillUpdate`.\n *\n * @param {object} nextProps\n * @optional\n */\n componentWillReceiveProps: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked while deciding if the component should be updated as a result of\n * receiving new props and state.\n *\n * Use this as an opportunity to `return false` when you're certain that the\n * transition to the new props and state will not require a component update.\n *\n * shouldComponentUpdate: function(nextProps, nextState) {\n * return !equal(nextProps, this.props) || !equal(nextState, this.state);\n * }\n *\n * @param {object} nextProps\n * @param {?object} nextState\n * @return {boolean} True if the component should update.\n * @optional\n */\n shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,\n\n /**\n * Invoked when the component is about to update due to a transition from\n * `this.props` and `this.state` to `nextProps` and `nextState`.\n *\n * Use this as an opportunity to perform preparation before an update occurs.\n *\n * NOTE: You **cannot** use `this.setState()` in this method.\n *\n * @param {object} nextProps\n * @param {?object} nextState\n * @param {ReactReconcileTransaction} transaction\n * @optional\n */\n componentWillUpdate: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked when the component's DOM representation has been updated.\n *\n * Use this as an opportunity to operate on the DOM when the component has\n * been updated.\n *\n * @param {object} prevProps\n * @param {?object} prevState\n * @param {DOMElement} rootNode DOM element representing the component.\n * @optional\n */\n componentDidUpdate: SpecPolicy.DEFINE_MANY,\n\n /**\n * Invoked when the component is about to be removed from its parent and have\n * its DOM representation destroyed.\n *\n * Use this as an opportunity to deallocate any external resources.\n *\n * NOTE: There is no `componentDidUnmount` since your component will have been\n * destroyed by that point.\n *\n * @optional\n */\n componentWillUnmount: SpecPolicy.DEFINE_MANY,\n\n\n\n // ==== Advanced methods ====\n\n /**\n * Updates the component's currently mounted DOM representation.\n *\n * By default, this implements React's rendering and reconciliation algorithm.\n * Sophisticated clients may wish to override this.\n *\n * @param {ReactReconcileTransaction} transaction\n * @internal\n * @overridable\n */\n updateComponent: SpecPolicy.OVERRIDE_BASE\n\n};\n\n/**\n * Mapping from class specification keys to special processing functions.\n *\n * Although these are declared in the specification when defining classes\n * using `React.createClass`, they will not be on the component's prototype.\n */\nvar RESERVED_SPEC_KEYS = {\n displayName: function(Constructor, displayName) {\n Constructor.displayName = displayName;\n },\n mixins: function(Constructor, mixins) {\n if (mixins) {\n for (var i = 0; i < mixins.length; i++) {\n mixSpecIntoComponent(Constructor, mixins[i]);\n }\n }\n },\n propTypes: function(Constructor, propTypes) {\n Constructor.propTypes = propTypes;\n }\n};\n\nfunction validateMethodOverride(proto, name) {\n var specPolicy = ReactCompositeComponentInterface[name];\n\n // Disallow overriding of base class methods unless explicitly allowed.\n if (ReactCompositeComponentMixin.hasOwnProperty(name)) {\n invariant(\n specPolicy === SpecPolicy.OVERRIDE_BASE,\n 'ReactCompositeComponentInterface: You are attempting to override ' +\n '`%s` from your class specification. Ensure that your method names ' +\n 'do not overlap with React methods.',\n name\n );\n }\n\n // Disallow defining methods more than once unless explicitly allowed.\n if (proto.hasOwnProperty(name)) {\n invariant(\n specPolicy === SpecPolicy.DEFINE_MANY ||\n specPolicy === SpecPolicy.DEFINE_MANY_MERGED,\n 'ReactCompositeComponentInterface: You are attempting to define ' +\n '`%s` on your component more than once. This conflict may be due ' +\n 'to a mixin.',\n name\n );\n }\n}\n\n\nfunction validateLifeCycleOnReplaceState(instance) {\n var compositeLifeCycleState = instance._compositeLifeCycleState;\n invariant(\n instance.isMounted() ||\n compositeLifeCycleState === CompositeLifeCycle.MOUNTING,\n 'replaceState(...): Can only update a mounted or mounting component.'\n );\n invariant(\n compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&\n compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,\n 'replaceState(...): Cannot update while unmounting component or during ' +\n 'an existing state transition (such as within `render`).'\n );\n}\n\n/**\n * Custom version of `mixInto` which handles policy validation and reserved\n * specification keys when building `ReactCompositeComponent` classses.\n */\nfunction mixSpecIntoComponent(Constructor, spec) {\n var proto = Constructor.prototype;\n for (var name in spec) {\n var property = spec[name];\n if (!spec.hasOwnProperty(name) || !property) {\n continue;\n }\n validateMethodOverride(proto, name);\n\n if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {\n RESERVED_SPEC_KEYS[name](Constructor, property);\n } else {\n // Setup methods on prototype:\n // The following member methods should not be automatically bound:\n // 1. Expected ReactCompositeComponent methods (in the \"interface\").\n // 2. Overridden methods (that were mixed in).\n var isCompositeComponentMethod = name in ReactCompositeComponentInterface;\n var isInherited = name in proto;\n var markedDontBind = property.__reactDontBind;\n var isFunction = typeof property === 'function';\n var shouldAutoBind =\n isFunction &&\n !isCompositeComponentMethod &&\n !isInherited &&\n !markedDontBind;\n\n if (shouldAutoBind) {\n if (!proto.__reactAutoBindMap) {\n proto.__reactAutoBindMap = {};\n }\n proto.__reactAutoBindMap[name] = property;\n proto[name] = property;\n } else {\n if (isInherited) {\n // For methods which are defined more than once, call the existing\n // methods before calling the new property.\n if (ReactCompositeComponentInterface[name] ===\n SpecPolicy.DEFINE_MANY_MERGED) {\n proto[name] = createMergedResultFunction(proto[name], property);\n } else {\n proto[name] = createChainedFunction(proto[name], property);\n }\n } else {\n proto[name] = property;\n }\n }\n }\n }\n}\n\n/**\n * Merge two objects, but throw if both contain the same key.\n *\n * @param {object} one The first object, which is mutated.\n * @param {object} two The second object\n * @return {object} one after it has been mutated to contain everything in two.\n */\nfunction mergeObjectsWithNoDuplicateKeys(one, two) {\n invariant(\n one && two && typeof one === 'object' && typeof two === 'object',\n 'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects'\n );\n\n objMap(two, function(value, key) {\n invariant(\n one[key] === undefined,\n 'mergeObjectsWithNoDuplicateKeys(): ' +\n 'Tried to merge two objects with the same key: %s',\n key\n );\n one[key] = value;\n });\n return one;\n}\n\n/**\n * Creates a function that invokes two functions and merges their return values.\n *\n * @param {function} one Function to invoke first.\n * @param {function} two Function to invoke second.\n * @return {function} Function that invokes the two argument functions.\n * @private\n */\nfunction createMergedResultFunction(one, two) {\n return function mergedResult() {\n return mergeObjectsWithNoDuplicateKeys(\n one.apply(this, arguments),\n two.apply(this, arguments)\n );\n };\n}\n\n/**\n * Creates a function that invokes two functions and ignores their return vales.\n *\n * @param {function} one Function to invoke first.\n * @param {function} two Function to invoke second.\n * @return {function} Function that invokes the two argument functions.\n * @private\n */\nfunction createChainedFunction(one, two) {\n return function chainedFunction() {\n one.apply(this, arguments);\n two.apply(this, arguments);\n };\n}\n\n/**\n * `ReactCompositeComponent` maintains an auxiliary life cycle state in\n * `this._compositeLifeCycleState` (which can be null).\n *\n * This is different from the life cycle state maintained by `ReactComponent` in\n * `this._lifeCycleState`. The following diagram shows how the states overlap in\n * time. There are times when the CompositeLifeCycle is null - at those times it\n * is only meaningful to look at ComponentLifeCycle alone.\n *\n * Top Row: ReactComponent.ComponentLifeCycle\n * Low Row: ReactComponent.CompositeLifeCycle\n *\n * +-------+------------------------------------------------------+--------+\n * | UN | MOUNTED | UN |\n * |MOUNTED| | MOUNTED|\n * +-------+------------------------------------------------------+--------+\n * | ^--------+ +------+ +------+ +------+ +--------^ |\n * | | | | | | | | | | | |\n * | 0--|MOUNTING|-0-|RECEIV|-0-|RECEIV|-0-|RECEIV|-0-| UN |--->0 |\n * | | | |PROPS | | PROPS| | STATE| |MOUNTING| |\n * | | | | | | | | | | | |\n * | | | | | | | | | | | |\n * | +--------+ +------+ +------+ +------+ +--------+ |\n * | | | |\n * +-------+------------------------------------------------------+--------+\n */\nvar CompositeLifeCycle = keyMirror({\n /**\n * Components in the process of being mounted respond to state changes\n * differently.\n */\n MOUNTING: null,\n /**\n * Components in the process of being unmounted are guarded against state\n * changes.\n */\n UNMOUNTING: null,\n /**\n * Components that are mounted and receiving new props respond to state\n * changes differently.\n */\n RECEIVING_PROPS: null,\n /**\n * Components that are mounted and receiving new state are guarded against\n * additional state changes.\n */\n RECEIVING_STATE: null\n});\n\n/**\n * @lends {ReactCompositeComponent.prototype}\n */\nvar ReactCompositeComponentMixin = {\n\n /**\n * Base constructor for all composite component.\n *\n * @param {?object} initialProps\n * @param {*} children\n * @final\n * @internal\n */\n construct: function(initialProps, children) {\n // Children can be either an array or more than one argument\n ReactComponent.Mixin.construct.apply(this, arguments);\n this.state = null;\n this._pendingState = null;\n this._compositeLifeCycleState = null;\n },\n\n /**\n * Checks whether or not this composite component is mounted.\n * @return {boolean} True if mounted, false otherwise.\n * @protected\n * @final\n */\n isMounted: function() {\n return ReactComponent.Mixin.isMounted.call(this) &&\n this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING;\n },\n\n /**\n * Initializes the component, renders markup, and registers event listeners.\n *\n * @param {string} rootID DOM ID of the root node.\n * @param {ReactReconcileTransaction} transaction\n * @param {number} mountDepth number of components in the owner hierarchy\n * @return {?string} Rendered markup to be inserted into the DOM.\n * @final\n * @internal\n */\n mountComponent: ReactPerf.measure(\n 'ReactCompositeComponent',\n 'mountComponent',\n function(rootID, transaction, mountDepth) {\n ReactComponent.Mixin.mountComponent.call(\n this,\n rootID,\n transaction,\n mountDepth\n );\n this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;\n\n this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null;\n this._processProps(this.props);\n\n if (this.__reactAutoBindMap) {\n this._bindAutoBindMethods();\n }\n\n this.state = this.getInitialState ? this.getInitialState() : null;\n this._pendingState = null;\n this._pendingForceUpdate = false;\n\n if (this.componentWillMount) {\n this.componentWillMount();\n // When mounting, calls to `setState` by `componentWillMount` will set\n // `this._pendingState` without triggering a re-render.\n if (this._pendingState) {\n this.state = this._pendingState;\n this._pendingState = null;\n }\n }\n\n this._renderedComponent = this._renderValidatedComponent();\n\n // Done with mounting, `setState` will now trigger UI changes.\n this._compositeLifeCycleState = null;\n var markup = this._renderedComponent.mountComponent(\n rootID,\n transaction,\n mountDepth + 1\n );\n if (this.componentDidMount) {\n transaction.getReactMountReady().enqueue(this, this.componentDidMount);\n }\n return markup;\n }\n ),\n\n /**\n * Releases any resources allocated by `mountComponent`.\n *\n * @final\n * @internal\n */\n unmountComponent: function() {\n this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING;\n if (this.componentWillUnmount) {\n this.componentWillUnmount();\n }\n this._compositeLifeCycleState = null;\n\n this._defaultProps = null;\n\n ReactComponent.Mixin.unmountComponent.call(this);\n this._renderedComponent.unmountComponent();\n this._renderedComponent = null;\n\n if (this.refs) {\n this.refs = null;\n }\n\n // Some existing components rely on this.props even after they've been\n // destroyed (in event handlers).\n // TODO: this.props = null;\n // TODO: this.state = null;\n },\n\n /**\n * Sets a subset of the state. Always use this or `replaceState` to mutate\n * state. You should treat `this.state` as immutable.\n *\n * There is no guarantee that `this.state` will be immediately updated, so\n * accessing `this.state` after calling this method may return the old value.\n *\n * There is no guarantee that calls to `setState` will run synchronously,\n * as they may eventually be batched together. You can provide an optional\n * callback that will be executed when the call to setState is actually\n * completed.\n *\n * @param {object} partialState Next partial state to be merged with state.\n * @param {?function} callback Called after state is updated.\n * @final\n * @protected\n */\n setState: function(partialState, callback) {\n // Merge with `_pendingState` if it exists, otherwise with existing state.\n this.replaceState(\n merge(this._pendingState || this.state, partialState),\n callback\n );\n },\n\n /**\n * Replaces all of the state. Always use this or `setState` to mutate state.\n * You should treat `this.state` as immutable.\n *\n * There is no guarantee that `this.state` will be immediately updated, so\n * accessing `this.state` after calling this method may return the old value.\n *\n * @param {object} completeState Next state.\n * @param {?function} callback Called after state is updated.\n * @final\n * @protected\n */\n replaceState: function(completeState, callback) {\n validateLifeCycleOnReplaceState(this);\n this._pendingState = completeState;\n ReactUpdates.enqueueUpdate(this, callback);\n },\n\n /**\n * Processes props by setting default values for unspecified props and\n * asserting that the props are valid.\n *\n * @param {object} props\n * @private\n */\n _processProps: function(props) {\n var propName;\n var defaultProps = this._defaultProps;\n for (propName in defaultProps) {\n if (typeof props[propName] === 'undefined') {\n props[propName] = defaultProps[propName];\n }\n }\n var propTypes = this.constructor.propTypes;\n if (propTypes) {\n var componentName = this.constructor.displayName;\n for (propName in propTypes) {\n var checkProp = propTypes[propName];\n if (checkProp) {\n checkProp(props, propName, componentName);\n }\n }\n }\n },\n\n performUpdateIfNecessary: function() {\n var compositeLifeCycleState = this._compositeLifeCycleState;\n // Do not trigger a state transition if we are in the middle of mounting or\n // receiving props because both of those will already be doing this.\n if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING ||\n compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) {\n return;\n }\n ReactComponent.Mixin.performUpdateIfNecessary.call(this);\n },\n\n /**\n * If any of `_pendingProps`, `_pendingState`, or `_pendingForceUpdate` is\n * set, update the component.\n *\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n _performUpdateIfNecessary: function(transaction) {\n if (this._pendingProps == null &&\n this._pendingState == null &&\n !this._pendingForceUpdate) {\n return;\n }\n\n var nextProps = this.props;\n if (this._pendingProps != null) {\n nextProps = this._pendingProps;\n this._processProps(nextProps);\n this._pendingProps = null;\n\n this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;\n if (this.componentWillReceiveProps) {\n this.componentWillReceiveProps(nextProps, transaction);\n }\n }\n\n this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE;\n\n var nextState = this._pendingState || this.state;\n this._pendingState = null;\n\n if (this._pendingForceUpdate ||\n !this.shouldComponentUpdate ||\n this.shouldComponentUpdate(nextProps, nextState)) {\n this._pendingForceUpdate = false;\n // Will set `this.props` and `this.state`.\n this._performComponentUpdate(nextProps, nextState, transaction);\n } else {\n // If it's determined that a component should not update, we still want\n // to set props and state.\n this.props = nextProps;\n this.state = nextState;\n }\n\n this._compositeLifeCycleState = null;\n },\n\n /**\n * Merges new props and state, notifies delegate methods of update and\n * performs update.\n *\n * @param {object} nextProps Next object to set as properties.\n * @param {?object} nextState Next object to set as state.\n * @param {ReactReconcileTransaction} transaction\n * @private\n */\n _performComponentUpdate: function(nextProps, nextState, transaction) {\n var prevProps = this.props;\n var prevState = this.state;\n\n if (this.componentWillUpdate) {\n this.componentWillUpdate(nextProps, nextState, transaction);\n }\n\n this.props = nextProps;\n this.state = nextState;\n\n this.updateComponent(transaction, prevProps, prevState);\n\n if (this.componentDidUpdate) {\n transaction.getReactMountReady().enqueue(\n this,\n this.componentDidUpdate.bind(this, prevProps, prevState)\n );\n }\n },\n\n /**\n * Updates the component's currently mounted DOM representation.\n *\n * By default, this implements React's rendering and reconciliation algorithm.\n * Sophisticated clients may wish to override this.\n *\n * @param {ReactReconcileTransaction} transaction\n * @param {object} prevProps\n * @param {?object} prevState\n * @internal\n * @overridable\n */\n updateComponent: ReactPerf.measure(\n 'ReactCompositeComponent',\n 'updateComponent',\n function(transaction, prevProps, prevState) {\n ReactComponent.Mixin.updateComponent.call(this, transaction, prevProps);\n var currentComponent = this._renderedComponent;\n var nextComponent = this._renderValidatedComponent();\n if (currentComponent.constructor === nextComponent.constructor) {\n currentComponent.receiveProps(nextComponent.props, transaction);\n } else {\n // These two IDs are actually the same! But nothing should rely on that.\n var thisID = this._rootNodeID;\n var currentComponentID = currentComponent._rootNodeID;\n currentComponent.unmountComponent();\n this._renderedComponent = nextComponent;\n var nextMarkup = nextComponent.mountComponent(\n thisID,\n transaction,\n this._mountDepth + 1\n );\n ReactComponent.DOMIDOperations.dangerouslyReplaceNodeWithMarkupByID(\n currentComponentID,\n nextMarkup\n );\n }\n }\n ),\n\n /**\n * Forces an update. This should only be invoked when it is known with\n * certainty that we are **not** in a DOM transaction.\n *\n * You may want to call this when you know that some deeper aspect of the\n * component's state has changed but `setState` was not called.\n *\n * This will not invoke `shouldUpdateComponent`, but it will invoke\n * `componentWillUpdate` and `componentDidUpdate`.\n *\n * @param {?function} callback Called after update is complete.\n * @final\n * @protected\n */\n forceUpdate: function(callback) {\n var compositeLifeCycleState = this._compositeLifeCycleState;\n invariant(\n this.isMounted() ||\n compositeLifeCycleState === CompositeLifeCycle.MOUNTING,\n 'forceUpdate(...): Can only force an update on mounted or mounting ' +\n 'components.'\n );\n invariant(\n compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&\n compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,\n 'forceUpdate(...): Cannot force an update while unmounting component ' +\n 'or during an existing state transition (such as within `render`).'\n );\n this._pendingForceUpdate = true;\n ReactUpdates.enqueueUpdate(this, callback);\n },\n\n /**\n * @private\n */\n _renderValidatedComponent: function() {\n var renderedComponent;\n ReactCurrentOwner.current = this;\n try {\n renderedComponent = this.render();\n } catch (error) {\n // IE8 requires `catch` in order to use `finally`.\n throw error;\n } finally {\n ReactCurrentOwner.current = null;\n }\n invariant(\n ReactComponent.isValidComponent(renderedComponent),\n '%s.render(): A valid ReactComponent must be returned.',\n this.constructor.displayName || 'ReactCompositeComponent'\n );\n return renderedComponent;\n },\n\n /**\n * @private\n */\n _bindAutoBindMethods: function() {\n for (var autoBindKey in this.__reactAutoBindMap) {\n if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {\n continue;\n }\n var method = this.__reactAutoBindMap[autoBindKey];\n this[autoBindKey] = this._bindAutoBindMethod(method);\n }\n },\n\n /**\n * Binds a method to the component.\n *\n * @param {function} method Method to be bound.\n * @private\n */\n _bindAutoBindMethod: function(method) {\n var component = this;\n var boundMethod = function() {\n return method.apply(component, arguments);\n };\n if (true) {\n boundMethod.__reactBoundContext = component;\n boundMethod.__reactBoundMethod = method;\n boundMethod.__reactBoundArguments = null;\n var componentName = component.constructor.displayName;\n var _bind = boundMethod.bind;\n boundMethod.bind = function(newThis) {\n // User is trying to bind() an autobound method; we effectively will\n // ignore the value of \"this\" that the user is trying to use, so\n // let's warn.\n if (newThis !== component && newThis !== null) {\n console.warn(\n 'bind(): React component methods may only be bound to the ' +\n 'component instance. See ' + componentName\n );\n } else if (arguments.length === 1) {\n console.warn(\n 'bind(): You are binding a component method to the component. ' +\n 'React does this for you automatically in a high-performance ' +\n 'way, so you can safely remove this call. See ' + componentName\n );\n return boundMethod;\n }\n var reboundMethod = _bind.apply(boundMethod, arguments);\n reboundMethod.__reactBoundContext = component;\n reboundMethod.__reactBoundMethod = method;\n reboundMethod.__reactBoundArguments =\n Array.prototype.slice.call(arguments, 1);\n return reboundMethod;\n };\n }\n return boundMethod;\n }\n};\n\nvar ReactCompositeComponentBase = function() {};\nmixInto(ReactCompositeComponentBase, ReactComponent.Mixin);\nmixInto(ReactCompositeComponentBase, ReactOwner.Mixin);\nmixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);\nmixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);\n\n/**\n * Module for creating composite components.\n *\n * @class ReactCompositeComponent\n * @extends ReactComponent\n * @extends ReactOwner\n * @extends ReactPropTransferer\n */\nvar ReactCompositeComponent = {\n\n LifeCycle: CompositeLifeCycle,\n\n Base: ReactCompositeComponentBase,\n\n /**\n * Creates a composite component class given a class specification.\n *\n * @param {object} spec Class specification (which must define `render`).\n * @return {function} Component constructor function.\n * @public\n */\n createClass: function(spec) {\n var Constructor = function() {};\n Constructor.prototype = new ReactCompositeComponentBase();\n Constructor.prototype.constructor = Constructor;\n mixSpecIntoComponent(Constructor, spec);\n\n invariant(\n Constructor.prototype.render,\n 'createClass(...): Class specification must implement a `render` method.'\n );\n\n if (true) {\n if (Constructor.prototype.componentShouldUpdate) {\n console.warn(\n (spec.displayName || 'A component') + ' has a method called ' +\n 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +\n 'The name is phrased as a question because the function is ' +\n 'expected to return a value.'\n );\n }\n }\n\n // Reduce time spent doing lookups by setting these on the prototype.\n for (var methodName in ReactCompositeComponentInterface) {\n if (!Constructor.prototype[methodName]) {\n Constructor.prototype[methodName] = null;\n }\n }\n\n var ConvenienceConstructor = function(props, children) {\n var instance = new Constructor();\n instance.construct.apply(instance, arguments);\n return instance;\n };\n ConvenienceConstructor.componentConstructor = Constructor;\n ConvenienceConstructor.originalSpec = spec;\n return ConvenienceConstructor;\n },\n\n /**\n * Checks if a value is a valid component constructor.\n *\n * @param {*}\n * @return {boolean}\n * @public\n */\n isValidClass: function(componentClass) {\n return componentClass instanceof Function &&\n 'componentConstructor' in componentClass &&\n componentClass.componentConstructor instanceof Function;\n }\n};\n\nmodule.exports = ReactCompositeComponent;\n\nrequire(\"./mock-modules\").register(\"ReactCompositeComponent\", module);\n", -"ReactCurrentOwner":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactCurrentOwner\n */\n\n\"use strict\";\n\n/**\n * Keeps track of the current owner.\n *\n * The current owner is the component who should own any components that are\n * currently being constructed.\n *\n * The depth indicate how many composite components are above this render level.\n */\nvar ReactCurrentOwner = {\n\n /**\n * @internal\n * @type {ReactComponent}\n */\n current: null\n\n};\n\nmodule.exports = ReactCurrentOwner;\n\nrequire(\"./mock-modules\").register(\"ReactCurrentOwner\", module);\n", -"cx":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule cx\n */\n\n/**\n * This function is used to mark string literals representing CSS class names\n * so that they can be transformed statically. This allows for modularization\n * and minification of CSS class names.\n *\n * In static_upstream, this function is actually implemented, but it should\n * eventually be replaced with something more descriptive, and the transform\n * that is used in the main stack should be ported for use elsewhere.\n *\n * @param string|object className to modularize, or an object of key/values.\n * In the object case, the values are conditions that\n * determine if the className keys should be included.\n * @param [string ...] Variable list of classNames in the string case.\n * @return string Renderable space-separated CSS className.\n */\nfunction cx(classNames) {\n if (typeof classNames == 'object') {\n return Object.keys(classNames).map(function(className) {\n return classNames[className] ? className : '';\n }).join(' ');\n } else {\n return Array.prototype.join.call(arguments, ' ');\n }\n}\n\nmodule.exports = cx;\n\nrequire(\"./mock-modules\").register(\"cx\", module);\n", -"ReactPropTypes":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactPropTypes\n */\n\n\"use strict\";\n\nvar createObjectFrom = require(\"./createObjectFrom\");\nvar invariant = require(\"./invariant\");\n\n/**\n * Collection of methods that allow declaration and validation of props that are\n * supplied to React components. Example usage:\n *\n * var Props = require('ReactPropTypes');\n * var MyArticle = React.createClass({\n * propTypes: {\n * // An optional string prop named \"description\".\n * description: Props.string,\n *\n * // A required enum prop named \"category\".\n * category: Props.oneOf(['News','Photos']).isRequired,\n *\n * // A prop named \"dialog\" that requires an instance of Dialog.\n * dialog: Props.instanceOf(Dialog).isRequired\n * },\n * render: function() { ... }\n * });\n *\n * A more formal specification of how these methods are used:\n *\n * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)\n * decl := ReactPropTypes.{type}(.isRequired)?\n *\n * Each and every declaration produces a function with the same signature. This\n * allows the creation of custom validation functions. For example:\n *\n * var Props = require('ReactPropTypes');\n * var MyLink = React.createClass({\n * propTypes: {\n * // An optional string or URI prop named \"href\".\n * href: function(props, propName, componentName) {\n * var propValue = props[propName];\n * invariant(\n * propValue == null ||\n * typeof propValue === 'string' ||\n * propValue instanceof URI,\n * 'Invalid `%s` supplied to `%s`, expected string or URI.',\n * propName,\n * componentName\n * );\n * }\n * },\n * render: function() { ... }\n * });\n *\n * @internal\n */\nvar Props = {\n\n array: createPrimitiveTypeChecker('array'),\n bool: createPrimitiveTypeChecker('boolean'),\n func: createPrimitiveTypeChecker('function'),\n number: createPrimitiveTypeChecker('number'),\n object: createPrimitiveTypeChecker('object'),\n string: createPrimitiveTypeChecker('string'),\n\n oneOf: createEnumTypeChecker,\n\n instanceOf: createInstanceTypeChecker\n\n};\n\nvar ANONYMOUS = '<>';\n\nfunction createPrimitiveTypeChecker(expectedType) {\n function validatePrimitiveType(propValue, propName, componentName) {\n var propType = typeof propValue;\n if (propType === 'object' && Array.isArray(propValue)) {\n propType = 'array';\n }\n invariant(\n propType === expectedType,\n 'Invalid prop `%s` of type `%s` supplied to `%s`, expected `%s`.',\n propName,\n propType,\n componentName,\n expectedType\n );\n }\n return createChainableTypeChecker(validatePrimitiveType);\n}\n\nfunction createEnumTypeChecker(expectedValues) {\n var expectedEnum = createObjectFrom(expectedValues);\n function validateEnumType(propValue, propName, componentName) {\n invariant(\n expectedEnum[propValue],\n 'Invalid prop `%s` supplied to `%s`, expected one of %s.',\n propName,\n componentName,\n JSON.stringify(Object.keys(expectedEnum))\n );\n }\n return createChainableTypeChecker(validateEnumType);\n}\n\nfunction createInstanceTypeChecker(expectedClass) {\n function validateInstanceType(propValue, propName, componentName) {\n invariant(\n propValue instanceof expectedClass,\n 'Invalid prop `%s` supplied to `%s`, expected instance of `%s`.',\n propName,\n componentName,\n expectedClass.name || ANONYMOUS\n );\n }\n return createChainableTypeChecker(validateInstanceType);\n}\n\nfunction createChainableTypeChecker(validate) {\n function createTypeChecker(isRequired) {\n function checkType(props, propName, componentName) {\n var propValue = props[propName];\n if (propValue != null) {\n // Only validate if there is a value to check.\n validate(propValue, propName, componentName || ANONYMOUS);\n } else {\n invariant(\n !isRequired,\n 'Required prop `%s` was not specified in `%s`.',\n propName,\n componentName || ANONYMOUS\n );\n }\n }\n if (!isRequired) {\n checkType.isRequired = createTypeChecker(true);\n }\n return checkType;\n }\n return createTypeChecker(false);\n}\n\nmodule.exports = Props;\n\nrequire(\"./mock-modules\").register(\"ReactPropTypes\", module);\n", -"ReactMount":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactMount\n */\n\n\"use strict\";\n\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactInstanceHandles = require(\"./ReactInstanceHandles\");\n\nvar $ = require(\"./$\");\nvar getReactRootElementInContainer = require(\"./getReactRootElementInContainer\");\nvar invariant = require(\"./invariant\");\nvar nodeContains = require(\"./nodeContains\");\n\nvar SEPARATOR = ReactInstanceHandles.SEPARATOR;\n\nvar ATTR_NAME = 'data-reactid';\nvar nodeCache = {};\n\nvar ELEMENT_NODE_TYPE = 1;\nvar DOC_NODE_TYPE = 9;\n\n/** Mapping from reactRootID to React component instance. */\nvar instancesByReactRootID = {};\n\n/** Mapping from reactRootID to `container` nodes. */\nvar containersByReactRootID = {};\n\nif (true) {\n /** __DEV__-only mapping from reactRootID to root elements. */\n var rootElementsByReactRootID = {};\n}\n\n/**\n * @param {DOMElement} container DOM element that may contain a React component.\n * @return {?string} A \"reactRoot\" ID, if a React component is rendered.\n */\nfunction getReactRootID(container) {\n var rootElement = getReactRootElementInContainer(container);\n return rootElement && ReactMount.getID(rootElement);\n}\n\n/**\n * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form\n * element can return its control whose name or ID equals ATTR_NAME. All\n * DOM nodes support `getAttributeNode` but this can also get called on\n * other objects so just return '' if we're given something other than a\n * DOM node (such as window).\n *\n * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.\n * @return {string} ID of the supplied `domNode`.\n */\nfunction getID(node) {\n var id = internalGetID(node);\n if (id) {\n if (nodeCache.hasOwnProperty(id)) {\n var cached = nodeCache[id];\n if (cached !== node) {\n invariant(\n !isValid(cached, id),\n 'ReactMount: Two valid but unequal nodes with the same `%s`: %s',\n ATTR_NAME, id\n );\n\n nodeCache[id] = node;\n }\n } else {\n nodeCache[id] = node;\n }\n }\n\n return id;\n}\n\nfunction internalGetID(node) {\n // If node is something like a window, document, or text node, none of\n // which support attributes or a .getAttribute method, gracefully return\n // the empty string, as if the attribute were missing.\n return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';\n}\n\n/**\n * Sets the React-specific ID of the given node.\n *\n * @param {DOMElement} node The DOM node whose ID will be set.\n * @param {string} id The value of the ID attribute.\n */\nfunction setID(node, id) {\n var oldID = internalGetID(node);\n if (oldID !== id) {\n delete nodeCache[oldID];\n }\n node.setAttribute(ATTR_NAME, id);\n nodeCache[id] = node;\n}\n\n/**\n * Finds the node with the supplied React-generated DOM ID.\n *\n * @param {string} id A React-generated DOM ID.\n * @return {DOMElement} DOM node with the suppled `id`.\n * @internal\n */\nfunction getNode(id) {\n if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {\n nodeCache[id] = ReactMount.findReactNodeByID(id);\n }\n return nodeCache[id];\n}\n\n/**\n * A node is \"valid\" if it is contained by a currently mounted container.\n *\n * This means that the node does not have to be contained by a document in\n * order to be considered valid.\n *\n * @param {?DOMElement} node The candidate DOM node.\n * @param {string} id The expected ID of the node.\n * @return {boolean} Whether the node is contained by a mounted container.\n */\nfunction isValid(node, id) {\n if (node) {\n invariant(\n internalGetID(node) === id,\n 'ReactMount: Unexpected modification of `%s`',\n ATTR_NAME\n );\n\n var container = ReactMount.findReactContainerForID(id);\n if (container && nodeContains(container, node)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Causes the cache to forget about one React-specific ID.\n *\n * @param {string} id The ID to forget.\n */\nfunction purgeID(id) {\n delete nodeCache[id];\n}\n\n/**\n * Mounting is the process of initializing a React component by creatings its\n * representative DOM elements and inserting them into a supplied `container`.\n * Any prior content inside `container` is destroyed in the process.\n *\n * ReactMount.renderComponent(component, $('container'));\n *\n *
<-- Supplied `container`.\n *
<-- Rendered reactRoot of React\n * // ... component.\n *
\n *
\n *\n * Inside of `container`, the first element rendered is the \"reactRoot\".\n */\nvar ReactMount = {\n /**\n * Safety guard to prevent accidentally rendering over the entire HTML tree.\n */\n allowFullPageRender: false,\n\n /** Time spent generating markup. */\n totalInstantiationTime: 0,\n\n /** Time spent inserting markup into the DOM. */\n totalInjectionTime: 0,\n\n /** Whether support for touch events should be initialized. */\n useTouchEvents: false,\n\n /** Exposed for debugging purposes **/\n _instancesByReactRootID: instancesByReactRootID,\n\n /**\n * This is a hook provided to support rendering React components while\n * ensuring that the apparent scroll position of its `container` does not\n * change.\n *\n * @param {DOMElement} container The `container` being rendered into.\n * @param {function} renderCallback This must be called once to do the render.\n */\n scrollMonitor: function(container, renderCallback) {\n renderCallback();\n },\n\n /**\n * Ensures that the top-level event delegation listener is set up. This will\n * be invoked some time before the first time any React component is rendered.\n * @param {DOMElement} container container we're rendering into\n *\n * @private\n */\n prepareEnvironmentForDOM: function(container) {\n invariant(\n container && (\n container.nodeType === ELEMENT_NODE_TYPE ||\n container.nodeType === DOC_NODE_TYPE\n ),\n 'prepareEnvironmentForDOM(...): Target container is not a DOM element.'\n );\n var doc = container.nodeType === ELEMENT_NODE_TYPE ?\n container.ownerDocument :\n container;\n ReactEventEmitter.ensureListening(ReactMount.useTouchEvents, doc);\n },\n\n /**\n * Take a component that's already mounted into the DOM and replace its props\n * @param {ReactComponent} prevComponent component instance already in the DOM\n * @param {ReactComponent} nextComponent component instance to render\n * @param {DOMElement} container container to render into\n * @param {?function} callback function triggered on completion\n */\n _updateRootComponent: function(\n prevComponent,\n nextComponent,\n container,\n callback) {\n var nextProps = nextComponent.props;\n ReactMount.scrollMonitor(container, function() {\n prevComponent.replaceProps(nextProps, callback);\n });\n\n if (true) {\n // Record the root element in case it later gets transplanted.\n rootElementsByReactRootID[getReactRootID(container)] =\n getReactRootElementInContainer(container);\n }\n\n return prevComponent;\n },\n\n /**\n * Register a component into the instance map and start the events system.\n * @param {ReactComponent} nextComponent component instance to render\n * @param {DOMElement} container container to render into\n * @return {string} reactRoot ID prefix\n */\n _registerComponent: function(nextComponent, container) {\n ReactMount.prepareEnvironmentForDOM(container);\n\n var reactRootID = ReactMount.registerContainer(container);\n instancesByReactRootID[reactRootID] = nextComponent;\n return reactRootID;\n },\n\n /**\n * Render a new component into the DOM.\n * @param {ReactComponent} nextComponent component instance to render\n * @param {DOMElement} container container to render into\n * @param {boolean} shouldReuseMarkup if we should skip the markup insertion\n * @return {ReactComponent} nextComponent\n */\n _renderNewRootComponent: function(\n nextComponent,\n container,\n shouldReuseMarkup) {\n var reactRootID = ReactMount._registerComponent(nextComponent, container);\n nextComponent.mountComponentIntoNode(\n reactRootID,\n container,\n shouldReuseMarkup\n );\n\n if (true) {\n // Record the root element in case it later gets transplanted.\n rootElementsByReactRootID[reactRootID] =\n getReactRootElementInContainer(container);\n }\n\n return nextComponent;\n },\n\n /**\n * Renders a React component into the DOM in the supplied `container`.\n *\n * If the React component was previously rendered into `container`, this will\n * perform an update on it and only mutate the DOM as necessary to reflect the\n * latest React component.\n *\n * @param {ReactComponent} nextComponent Component instance to render.\n * @param {DOMElement} container DOM element to render into.\n * @param {?function} callback function triggered on completion\n * @return {ReactComponent} Component instance rendered in `container`.\n */\n renderComponent: function(nextComponent, container, callback) {\n var registeredComponent = instancesByReactRootID[getReactRootID(container)];\n\n if (registeredComponent) {\n if (registeredComponent.constructor === nextComponent.constructor) {\n return ReactMount._updateRootComponent(\n registeredComponent,\n nextComponent,\n container,\n callback\n );\n } else {\n ReactMount.unmountComponentAtNode(container);\n }\n }\n\n var reactRootElement = getReactRootElementInContainer(container);\n var containerHasReactMarkup =\n reactRootElement && ReactMount.isRenderedByReact(reactRootElement);\n\n var shouldReuseMarkup = containerHasReactMarkup && !registeredComponent;\n\n var component = ReactMount._renderNewRootComponent(\n nextComponent,\n container,\n shouldReuseMarkup\n );\n callback && callback();\n return component;\n },\n\n /**\n * Constructs a component instance of `constructor` with `initialProps` and\n * renders it into the supplied `container`.\n *\n * @param {function} constructor React component constructor.\n * @param {?object} props Initial props of the component instance.\n * @param {DOMElement} container DOM element to render into.\n * @return {ReactComponent} Component instance rendered in `container`.\n */\n constructAndRenderComponent: function(constructor, props, container) {\n return ReactMount.renderComponent(constructor(props), container);\n },\n\n /**\n * Constructs a component instance of `constructor` with `initialProps` and\n * renders it into a container node identified by supplied `id`.\n *\n * @param {function} componentConstructor React component constructor\n * @param {?object} props Initial props of the component instance.\n * @param {string} id ID of the DOM element to render into.\n * @return {ReactComponent} Component instance rendered in the container node.\n */\n constructAndRenderComponentByID: function(constructor, props, id) {\n return ReactMount.constructAndRenderComponent(constructor, props, $(id));\n },\n\n /**\n * Registers a container node into which React components will be rendered.\n * This also creates the \"reatRoot\" ID that will be assigned to the element\n * rendered within.\n *\n * @param {DOMElement} container DOM element to register as a container.\n * @return {string} The \"reactRoot\" ID of elements rendered within.\n */\n registerContainer: function(container) {\n var reactRootID = getReactRootID(container);\n if (reactRootID) {\n // If one exists, make sure it is a valid \"reactRoot\" ID.\n reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);\n }\n if (!reactRootID) {\n // No valid \"reactRoot\" ID found, create one.\n reactRootID = ReactInstanceHandles.createReactRootID();\n }\n containersByReactRootID[reactRootID] = container;\n return reactRootID;\n },\n\n /**\n * Unmounts and destroys the React component rendered in the `container`.\n *\n * @param {DOMElement} container DOM element containing a React component.\n * @return {boolean} True if a component was found in and unmounted from\n * `container`\n */\n unmountComponentAtNode: function(container) {\n var reactRootID = getReactRootID(container);\n var component = instancesByReactRootID[reactRootID];\n if (!component) {\n return false;\n }\n ReactMount.unmountComponentFromNode(component, container);\n delete instancesByReactRootID[reactRootID];\n delete containersByReactRootID[reactRootID];\n if (true) {\n delete rootElementsByReactRootID[reactRootID];\n }\n return true;\n },\n\n /**\n * @deprecated\n */\n unmountAndReleaseReactRootNode: function() {\n if (true) {\n console.warn(\n 'unmountAndReleaseReactRootNode() has been renamed to ' +\n 'unmountComponentAtNode() and will be removed in the next ' +\n 'version of React.'\n );\n }\n return ReactMount.unmountComponentAtNode.apply(this, arguments);\n },\n\n /**\n * Unmounts a component and removes it from the DOM.\n *\n * @param {ReactComponent} instance React component instance.\n * @param {DOMElement} container DOM element to unmount from.\n * @final\n * @internal\n * @see {ReactMount.unmountComponentAtNode}\n */\n unmountComponentFromNode: function(instance, container) {\n instance.unmountComponent();\n\n // http://jsperf.com/emptying-a-node\n while (container.lastChild) {\n container.removeChild(container.lastChild);\n }\n },\n\n /**\n * Finds the container DOM element that contains React component to which the\n * supplied DOM `id` belongs.\n *\n * @param {string} id The ID of an element rendered by a React component.\n * @return {?DOMElement} DOM element that contains the `id`.\n */\n findReactContainerForID: function(id) {\n var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);\n var container = containersByReactRootID[reactRootID];\n\n if (true) {\n var rootElement = rootElementsByReactRootID[reactRootID];\n if (rootElement && rootElement.parentNode !== container) {\n invariant(\n // Call internalGetID here because getID calls isValid which calls\n // findReactContainerForID (this function).\n internalGetID(rootElement) === reactRootID,\n 'ReactMount: Root element ID differed from reactRootID.'\n );\n\n var containerChild = container.firstChild;\n if (containerChild &&\n reactRootID === internalGetID(containerChild)) {\n // If the container has a new child with the same ID as the old\n // root element, then rootElementsByReactRootID[reactRootID] is\n // just stale and needs to be updated. The case that deserves a\n // warning is when the container is empty.\n rootElementsByReactRootID[reactRootID] = containerChild;\n } else {\n console.warn(\n 'ReactMount: Root element has been removed from its original ' +\n 'container. New container:', rootElement.parentNode\n );\n }\n }\n }\n\n return container;\n },\n\n /**\n * Finds an element rendered by React with the supplied ID.\n *\n * @param {string} id ID of a DOM node in the React component.\n * @return {DOMElement} Root DOM node of the React component.\n */\n findReactNodeByID: function(id) {\n var reactRoot = ReactMount.findReactContainerForID(id);\n return ReactMount.findComponentRoot(reactRoot, id);\n },\n\n /**\n * True if the supplied `node` is rendered by React.\n *\n * @param {*} node DOM Element to check.\n * @return {boolean} True if the DOM Element appears to be rendered by React.\n * @internal\n */\n isRenderedByReact: function(node) {\n if (node.nodeType !== 1) {\n // Not a DOMElement, therefore not a React component\n return false;\n }\n var id = ReactMount.getID(node);\n return id ? id.charAt(0) === SEPARATOR : false;\n },\n\n /**\n * Traverses up the ancestors of the supplied node to find a node that is a\n * DOM representation of a React component.\n *\n * @param {*} node\n * @return {?DOMEventTarget}\n * @internal\n */\n getFirstReactDOM: function(node) {\n var current = node;\n while (current && current.parentNode !== current) {\n if (ReactMount.isRenderedByReact(current)) {\n return current;\n }\n current = current.parentNode;\n }\n return null;\n },\n\n /**\n * Finds a node with the supplied `id` inside of the supplied `ancestorNode`.\n * Exploits the ID naming scheme to perform the search quickly.\n *\n * @param {DOMEventTarget} ancestorNode Search from this root.\n * @pararm {string} id ID of the DOM representation of the component.\n * @return {DOMEventTarget} DOM node with the supplied `id`.\n * @internal\n */\n findComponentRoot: function(ancestorNode, id) {\n var firstChildren = [ancestorNode.firstChild];\n var childIndex = 0;\n\n while (childIndex < firstChildren.length) {\n var child = firstChildren[childIndex++];\n while (child) {\n var childID = ReactMount.getID(child);\n if (childID) {\n if (id === childID) {\n return child;\n } else if (ReactInstanceHandles.isAncestorIDOf(childID, id)) {\n // If we find a child whose ID is an ancestor of the given ID,\n // then we can be sure that we only want to search the subtree\n // rooted at this child, so we can throw out the rest of the\n // search state.\n firstChildren.length = childIndex = 0;\n firstChildren.push(child.firstChild);\n break;\n } else {\n // TODO This should not be necessary if the ID hierarchy is\n // correct, but is occasionally necessary if the DOM has been\n // modified in unexpected ways.\n firstChildren.push(child.firstChild);\n }\n } else {\n // If this child had no ID, then there's a chance that it was\n // injected automatically by the browser, as when a `
2
`\n // element sprouts an extra `` child as a side effect of\n // `.innerHTML` parsing. Optimistically continue down this\n // branch, but not before examining the other siblings.\n firstChildren.push(child.firstChild);\n }\n child = child.nextSibling;\n }\n }\n\n if (true) {\n console.error(\n 'Error while invoking `findComponentRoot` with the following ' +\n 'ancestor node:',\n ancestorNode\n );\n }\n invariant(\n false,\n 'findComponentRoot(..., %s): Unable to find element. This probably ' +\n 'means the DOM was unexpectedly mutated (e.g. by the browser).',\n id,\n ReactMount.getID(ancestorNode)\n );\n },\n\n\n /**\n * React ID utilities.\n */\n\n ATTR_NAME: ATTR_NAME,\n\n getID: getID,\n\n setID: setID,\n\n getNode: getNode,\n\n purgeID: purgeID,\n\n injection: {}\n};\n\nmodule.exports = ReactMount;\n\nrequire(\"./mock-modules\").register(\"ReactMount\", module);\n", -"ReactDOM":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDOM\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar ReactDOMComponent = require(\"./ReactDOMComponent\");\n\nvar mergeInto = require(\"./mergeInto\");\nvar objMapKeyVal = require(\"./objMapKeyVal\");\n\n/**\n * Creates a new React class that is idempotent and capable of containing other\n * React components. It accepts event listeners and DOM properties that are\n * valid according to `DOMProperty`.\n *\n * - Event listeners: `onClick`, `onMouseDown`, etc.\n * - DOM properties: `className`, `name`, `title`, etc.\n *\n * The `style` property functions differently from the DOM API. It accepts an\n * object mapping of style properties to values.\n *\n * @param {string} tag Tag name (e.g. `div`).\n * @param {boolean} omitClose True if the close tag should be omitted.\n * @private\n */\nfunction createDOMComponentClass(tag, omitClose) {\n var Constructor = function() {};\n Constructor.prototype = new ReactDOMComponent(tag, omitClose);\n Constructor.prototype.constructor = Constructor;\n Constructor.displayName = tag;\n\n var ConvenienceConstructor = function(props, children) {\n var instance = new Constructor();\n instance.construct.apply(instance, arguments);\n return instance;\n };\n ConvenienceConstructor.componentConstructor = Constructor;\n return ConvenienceConstructor;\n}\n\n/**\n * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.\n * This is also accessible via `React.DOM`.\n *\n * @public\n */\nvar ReactDOM = objMapKeyVal({\n a: false,\n abbr: false,\n address: false,\n area: false,\n article: false,\n aside: false,\n audio: false,\n b: false,\n base: false,\n bdi: false,\n bdo: false,\n big: false,\n blockquote: false,\n body: false,\n br: true,\n button: false,\n canvas: false,\n caption: false,\n cite: false,\n code: false,\n col: true,\n colgroup: false,\n data: false,\n datalist: false,\n dd: false,\n del: false,\n details: false,\n dfn: false,\n div: false,\n dl: false,\n dt: false,\n em: false,\n embed: true,\n fieldset: false,\n figcaption: false,\n figure: false,\n footer: false,\n form: false, // NOTE: Injected, see `ReactDOMForm`.\n h1: false,\n h2: false,\n h3: false,\n h4: false,\n h5: false,\n h6: false,\n head: false,\n header: false,\n hr: true,\n html: false,\n i: false,\n iframe: false,\n img: true,\n input: true,\n ins: false,\n kbd: false,\n keygen: true,\n label: false,\n legend: false,\n li: false,\n link: false,\n main: false,\n map: false,\n mark: false,\n menu: false,\n menuitem: false, // NOTE: Close tag should be omitted, but causes problems.\n meta: true,\n meter: false,\n nav: false,\n noscript: false,\n object: false,\n ol: false,\n optgroup: false,\n option: false,\n output: false,\n p: false,\n param: true,\n pre: false,\n progress: false,\n q: false,\n rp: false,\n rt: false,\n ruby: false,\n s: false,\n samp: false,\n script: false,\n section: false,\n select: false,\n small: false,\n source: false,\n span: false,\n strong: false,\n style: false,\n sub: false,\n summary: false,\n sup: false,\n table: false,\n tbody: false,\n td: false,\n textarea: false, // NOTE: Injected, see `ReactDOMTextarea`.\n tfoot: false,\n th: false,\n thead: false,\n time: false,\n title: false,\n tr: false,\n track: true,\n u: false,\n ul: false,\n 'var': false,\n video: false,\n wbr: false,\n\n // SVG\n circle: false,\n g: false,\n line: false,\n path: false,\n polyline: false,\n rect: false,\n svg: false,\n text: false\n}, createDOMComponentClass);\n\nvar injection = {\n injectComponentClasses: function(componentClasses) {\n mergeInto(ReactDOM, componentClasses);\n }\n};\n\nReactDOM.injection = injection;\n\nmodule.exports = ReactDOM;\n\nrequire(\"./mock-modules\").register(\"ReactDOM\", module);\n", -"ReactReconcileTransaction":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactReconcileTransaction\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar ExecutionEnvironment = require(\"./ExecutionEnvironment\");\nvar PooledClass = require(\"./PooledClass\");\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactInputSelection = require(\"./ReactInputSelection\");\nvar ReactMountReady = require(\"./ReactMountReady\");\nvar Transaction = require(\"./Transaction\");\n\nvar mixInto = require(\"./mixInto\");\n\n/**\n * Ensures that, when possible, the selection range (currently selected text\n * input) is not disturbed by performing the transaction.\n */\nvar SELECTION_RESTORATION = {\n /**\n * @return {Selection} Selection information.\n */\n initialize: ReactInputSelection.getSelectionInformation,\n /**\n * @param {Selection} sel Selection information returned from `initialize`.\n */\n close: ReactInputSelection.restoreSelection\n};\n\n/**\n * Suppresses events (blur/focus) that could be inadvertently dispatched due to\n * high level DOM manipulations (like temporarily removing a text input from the\n * DOM).\n */\nvar EVENT_SUPPRESSION = {\n /**\n * @return {boolean} The enabled status of `ReactEventEmitter` before the\n * reconciliation.\n */\n initialize: function() {\n var currentlyEnabled = ReactEventEmitter.isEnabled();\n ReactEventEmitter.setEnabled(false);\n return currentlyEnabled;\n },\n\n /**\n * @param {boolean} previouslyEnabled Enabled status of `ReactEventEmitter`\n * before the reconciliation occured. `close` restores the previous value.\n */\n close: function(previouslyEnabled) {\n ReactEventEmitter.setEnabled(previouslyEnabled);\n }\n};\n\n/**\n * Provides a `ReactMountReady` queue for collecting `onDOMReady` callbacks\n * during the performing of the transaction.\n */\nvar ON_DOM_READY_QUEUEING = {\n /**\n * Initializes the internal `onDOMReady` queue.\n */\n initialize: function() {\n this.reactMountReady.reset();\n },\n\n /**\n * After DOM is flushed, invoke all registered `onDOMReady` callbacks.\n */\n close: function() {\n this.reactMountReady.notifyAll();\n }\n};\n\n/**\n * Executed within the scope of the `Transaction` instance. Consider these as\n * being member methods, but with an implied ordering while being isolated from\n * each other.\n */\nvar TRANSACTION_WRAPPERS = [\n SELECTION_RESTORATION,\n EVENT_SUPPRESSION,\n ON_DOM_READY_QUEUEING\n];\n\n/**\n * Currently:\n * - The order that these are listed in the transaction is critical:\n * - Suppresses events.\n * - Restores selection range.\n *\n * Future:\n * - Restore document/overflow scroll positions that were unintentionally\n * modified via DOM insertions above the top viewport boundary.\n * - Implement/integrate with customized constraint based layout system and keep\n * track of which dimensions must be remeasured.\n *\n * @class ReactReconcileTransaction\n */\nfunction ReactReconcileTransaction() {\n this.reinitializeTransaction();\n this.reactMountReady = ReactMountReady.getPooled(null);\n}\n\nvar Mixin = {\n /**\n * @see Transaction\n * @abstract\n * @final\n * @return {array} List of operation wrap proceedures.\n * TODO: convert to array\n */\n getTransactionWrappers: function() {\n if (ExecutionEnvironment.canUseDOM) {\n return TRANSACTION_WRAPPERS;\n } else {\n return [];\n }\n },\n\n /**\n * @return {object} The queue to collect `onDOMReady` callbacks with.\n * TODO: convert to ReactMountReady\n */\n getReactMountReady: function() {\n return this.reactMountReady;\n },\n\n /**\n * `PooledClass` looks for this, and will invoke this before allowing this\n * instance to be resused.\n */\n destructor: function() {\n ReactMountReady.release(this.reactMountReady);\n this.reactMountReady = null;\n }\n};\n\n\nmixInto(ReactReconcileTransaction, Transaction.Mixin);\nmixInto(ReactReconcileTransaction, Mixin);\n\nPooledClass.addPoolingTo(ReactReconcileTransaction);\n\nmodule.exports = ReactReconcileTransaction;\n\nrequire(\"./mock-modules\").register(\"ReactReconcileTransaction\", module);\n", -"ReactDefaultInjection":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDefaultInjection\n */\n\n\"use strict\";\n\nvar ReactDOM = require(\"./ReactDOM\");\nvar ReactDOMButton = require(\"./ReactDOMButton\");\nvar ReactDOMForm = require(\"./ReactDOMForm\");\nvar ReactDOMInput = require(\"./ReactDOMInput\");\nvar ReactDOMOption = require(\"./ReactDOMOption\");\nvar ReactDOMSelect = require(\"./ReactDOMSelect\");\nvar ReactDOMTextarea = require(\"./ReactDOMTextarea\");\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactEventTopLevelCallback = require(\"./ReactEventTopLevelCallback\");\nvar ReactPerf = require(\"./ReactPerf\");\n\nvar DefaultDOMPropertyConfig = require(\"./DefaultDOMPropertyConfig\");\nvar DOMProperty = require(\"./DOMProperty\");\n\nvar ChangeEventPlugin = require(\"./ChangeEventPlugin\");\nvar CompositionEventPlugin = require(\"./CompositionEventPlugin\");\nvar DefaultEventPluginOrder = require(\"./DefaultEventPluginOrder\");\nvar EnterLeaveEventPlugin = require(\"./EnterLeaveEventPlugin\");\nvar EventPluginHub = require(\"./EventPluginHub\");\nvar MobileSafariClickEventPlugin = require(\"./MobileSafariClickEventPlugin\");\nvar ReactInstanceHandles = require(\"./ReactInstanceHandles\");\nvar SelectEventPlugin = require(\"./SelectEventPlugin\");\nvar SimpleEventPlugin = require(\"./SimpleEventPlugin\");\n\nvar ReactDefaultBatchingStrategy = require(\"./ReactDefaultBatchingStrategy\");\nvar ReactUpdates = require(\"./ReactUpdates\");\n\nfunction inject() {\n ReactEventEmitter.TopLevelCallbackCreator = ReactEventTopLevelCallback;\n /**\n * Inject module for resolving DOM hierarchy and plugin ordering.\n */\n EventPluginHub.injection.injectEventPluginOrder(DefaultEventPluginOrder);\n EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles);\n\n /**\n * Some important event plugins included by default (without having to require\n * them).\n */\n EventPluginHub.injection.injectEventPluginsByName({\n SimpleEventPlugin: SimpleEventPlugin,\n EnterLeaveEventPlugin: EnterLeaveEventPlugin,\n ChangeEventPlugin: ChangeEventPlugin,\n CompositionEventPlugin: CompositionEventPlugin,\n MobileSafariClickEventPlugin: MobileSafariClickEventPlugin,\n SelectEventPlugin: SelectEventPlugin\n });\n\n ReactDOM.injection.injectComponentClasses({\n button: ReactDOMButton,\n form: ReactDOMForm,\n input: ReactDOMInput,\n option: ReactDOMOption,\n select: ReactDOMSelect,\n textarea: ReactDOMTextarea\n });\n\n DOMProperty.injection.injectDOMPropertyConfig(DefaultDOMPropertyConfig);\n\n if (true) {\n ReactPerf.injection.injectMeasure(require(\"./ReactDefaultPerf\").measure);\n }\n\n ReactUpdates.injection.injectBatchingStrategy(\n ReactDefaultBatchingStrategy\n );\n}\n\nmodule.exports = {\n inject: inject\n};\n\nrequire(\"./mock-modules\").register(\"ReactDefaultInjection\", module);\n", -"mixInto":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule mixInto\n */\n\n\"use strict\";\n\n/**\n * Simply copies properties to the prototype.\n */\nvar mixInto = function(constructor, methodBag) {\n var methodName;\n for (methodName in methodBag) {\n if (!methodBag.hasOwnProperty(methodName)) {\n continue;\n }\n constructor.prototype[methodName] = methodBag[methodName];\n }\n};\n\nmodule.exports = mixInto;\n\nrequire(\"./mock-modules\").register(\"mixInto\", module);\n", -"ReactDOMComponent":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDOMComponent\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar CSSPropertyOperations = require(\"./CSSPropertyOperations\");\nvar DOMProperty = require(\"./DOMProperty\");\nvar DOMPropertyOperations = require(\"./DOMPropertyOperations\");\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactEventEmitter = require(\"./ReactEventEmitter\");\nvar ReactMultiChild = require(\"./ReactMultiChild\");\nvar ReactMount = require(\"./ReactMount\");\nvar ReactPerf = require(\"./ReactPerf\");\n\nvar escapeTextForBrowser = require(\"./escapeTextForBrowser\");\nvar invariant = require(\"./invariant\");\nvar keyOf = require(\"./keyOf\");\nvar merge = require(\"./merge\");\nvar mixInto = require(\"./mixInto\");\n\nvar putListener = ReactEventEmitter.putListener;\nvar deleteListener = ReactEventEmitter.deleteListener;\nvar registrationNames = ReactEventEmitter.registrationNames;\n\n// For quickly matching children type, to test if can be treated as content.\nvar CONTENT_TYPES = {'string': true, 'number': true};\n\nvar STYLE = keyOf({style: null});\n\n/**\n * @param {?object} props\n */\nfunction assertValidProps(props) {\n if (!props) {\n return;\n }\n // Note the use of `==` which checks for null or undefined.\n invariant(\n props.children == null || props.dangerouslySetInnerHTML == null,\n 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'\n );\n invariant(\n props.style == null || typeof props.style === 'object',\n 'The `style` prop expects a mapping from style properties to values, ' +\n 'not a string.'\n );\n}\n\n/**\n * @constructor ReactDOMComponent\n * @extends ReactComponent\n * @extends ReactMultiChild\n */\nfunction ReactDOMComponent(tag, omitClose) {\n this._tagOpen = '<' + tag;\n this._tagClose = omitClose ? '' : '';\n this.tagName = tag.toUpperCase();\n}\n\nReactDOMComponent.Mixin = {\n\n /**\n * Generates root tag markup then recurses. This method has side effects and\n * is not idempotent.\n *\n * @internal\n * @param {string} rootID The root DOM ID for this node.\n * @param {ReactReconcileTransaction} transaction\n * @param {number} mountDepth number of components in the owner hierarchy\n * @return {string} The computed markup.\n */\n mountComponent: ReactPerf.measure(\n 'ReactDOMComponent',\n 'mountComponent',\n function(rootID, transaction, mountDepth) {\n ReactComponent.Mixin.mountComponent.call(\n this,\n rootID,\n transaction,\n mountDepth\n );\n assertValidProps(this.props);\n return (\n this._createOpenTagMarkup() +\n this._createContentMarkup(transaction) +\n this._tagClose\n );\n }\n ),\n\n /**\n * Creates markup for the open tag and all attributes.\n *\n * This method has side effects because events get registered.\n *\n * Iterating over object properties is faster than iterating over arrays.\n * @see http://jsperf.com/obj-vs-arr-iteration\n *\n * @private\n * @return {string} Markup of opening tag.\n */\n _createOpenTagMarkup: function() {\n var props = this.props;\n var ret = this._tagOpen;\n\n for (var propKey in props) {\n if (!props.hasOwnProperty(propKey)) {\n continue;\n }\n var propValue = props[propKey];\n if (propValue == null) {\n continue;\n }\n if (registrationNames[propKey]) {\n putListener(this._rootNodeID, propKey, propValue);\n } else {\n if (propKey === STYLE) {\n if (propValue) {\n propValue = props.style = merge(props.style);\n }\n propValue = CSSPropertyOperations.createMarkupForStyles(propValue);\n }\n var markup =\n DOMPropertyOperations.createMarkupForProperty(propKey, propValue);\n if (markup) {\n ret += ' ' + markup;\n }\n }\n }\n\n var escapedID = escapeTextForBrowser(this._rootNodeID);\n return ret + ' ' + ReactMount.ATTR_NAME + '=\"' + escapedID + '\">';\n },\n\n /**\n * Creates markup for the content between the tags.\n *\n * @private\n * @param {ReactReconcileTransaction} transaction\n * @return {string} Content markup.\n */\n _createContentMarkup: function(transaction) {\n // Intentional use of != to avoid catching zero/false.\n var innerHTML = this.props.dangerouslySetInnerHTML;\n if (innerHTML != null) {\n if (innerHTML.__html != null) {\n return innerHTML.__html;\n }\n } else {\n var contentToUse =\n CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;\n var childrenToUse = contentToUse != null ? null : this.props.children;\n if (contentToUse != null) {\n return escapeTextForBrowser(contentToUse);\n } else if (childrenToUse != null) {\n var mountImages = this.mountChildren(\n childrenToUse,\n transaction\n );\n return mountImages.join('');\n }\n }\n return '';\n },\n\n receiveProps: function(nextProps, transaction) {\n assertValidProps(nextProps);\n ReactComponent.Mixin.receiveProps.call(this, nextProps, transaction);\n },\n\n /**\n * Updates a native DOM component after it has already been allocated and\n * attached to the DOM. Reconciles the root DOM node, then recurses.\n *\n * @param {ReactReconcileTransaction} transaction\n * @param {object} prevProps\n * @internal\n * @overridable\n */\n updateComponent: ReactPerf.measure(\n 'ReactDOMComponent',\n 'updateComponent',\n function(transaction, prevProps) {\n ReactComponent.Mixin.updateComponent.call(this, transaction, prevProps);\n this._updateDOMProperties(prevProps);\n this._updateDOMChildren(prevProps, transaction);\n }\n ),\n\n /**\n * Reconciles the properties by detecting differences in property values and\n * updating the DOM as necessary. This function is probably the single most\n * critical path for performance optimization.\n *\n * TODO: Benchmark whether checking for changed values in memory actually\n * improves performance (especially statically positioned elements).\n * TODO: Benchmark the effects of putting this at the top since 99% of props\n * do not change for a given reconciliation.\n * TODO: Benchmark areas that can be improved with caching.\n *\n * @private\n * @param {object} lastProps\n */\n _updateDOMProperties: function(lastProps) {\n var nextProps = this.props;\n var propKey;\n var styleName;\n var styleUpdates;\n for (propKey in lastProps) {\n if (nextProps.hasOwnProperty(propKey) ||\n !lastProps.hasOwnProperty(propKey)) {\n continue;\n }\n if (propKey === STYLE) {\n var lastStyle = lastProps[propKey];\n for (styleName in lastStyle) {\n if (lastStyle.hasOwnProperty(styleName)) {\n styleUpdates = styleUpdates || {};\n styleUpdates[styleName] = '';\n }\n }\n } else if (registrationNames[propKey]) {\n deleteListener(this._rootNodeID, propKey);\n } else if (\n DOMProperty.isStandardName[propKey] ||\n DOMProperty.isCustomAttribute(propKey)) {\n ReactComponent.DOMIDOperations.deletePropertyByID(\n this._rootNodeID,\n propKey\n );\n }\n }\n for (propKey in nextProps) {\n var nextProp = nextProps[propKey];\n var lastProp = lastProps[propKey];\n if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {\n continue;\n }\n if (propKey === STYLE) {\n if (nextProp) {\n nextProp = nextProps.style = merge(nextProp);\n }\n if (lastProp) {\n // Unset styles on `lastProp` but not on `nextProp`.\n for (styleName in lastProp) {\n if (lastProp.hasOwnProperty(styleName) &&\n !nextProp.hasOwnProperty(styleName)) {\n styleUpdates = styleUpdates || {};\n styleUpdates[styleName] = '';\n }\n }\n // Update styles that changed since `lastProp`.\n for (styleName in nextProp) {\n if (nextProp.hasOwnProperty(styleName) &&\n lastProp[styleName] !== nextProp[styleName]) {\n styleUpdates = styleUpdates || {};\n styleUpdates[styleName] = nextProp[styleName];\n }\n }\n } else {\n // Relies on `updateStylesByID` not mutating `styleUpdates`.\n styleUpdates = nextProp;\n }\n } else if (registrationNames[propKey]) {\n putListener(this._rootNodeID, propKey, nextProp);\n } else if (\n DOMProperty.isStandardName[propKey] ||\n DOMProperty.isCustomAttribute(propKey)) {\n ReactComponent.DOMIDOperations.updatePropertyByID(\n this._rootNodeID,\n propKey,\n nextProp\n );\n }\n }\n if (styleUpdates) {\n ReactComponent.DOMIDOperations.updateStylesByID(\n this._rootNodeID,\n styleUpdates\n );\n }\n },\n\n /**\n * Reconciles the children with the various properties that affect the\n * children content.\n *\n * @param {object} lastProps\n * @param {ReactReconcileTransaction} transaction\n */\n _updateDOMChildren: function(lastProps, transaction) {\n var nextProps = this.props;\n\n var lastContent =\n CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;\n var nextContent =\n CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;\n\n var lastHtml =\n lastProps.dangerouslySetInnerHTML &&\n lastProps.dangerouslySetInnerHTML.__html;\n var nextHtml =\n nextProps.dangerouslySetInnerHTML &&\n nextProps.dangerouslySetInnerHTML.__html;\n\n // Note the use of `!=` which checks for null or undefined.\n var lastChildren = lastContent != null ? null : lastProps.children;\n var nextChildren = nextContent != null ? null : nextProps.children;\n\n // If we're switching from children to content/html or vice versa, remove\n // the old content\n var lastHasContentOrHtml = lastContent != null || lastHtml != null;\n var nextHasContentOrHtml = nextContent != null || nextHtml != null;\n if (lastChildren != null && nextChildren == null) {\n this.updateChildren(null, transaction);\n } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {\n this.updateTextContent('');\n }\n\n if (nextContent != null) {\n if (lastContent !== nextContent) {\n this.updateTextContent('' + nextContent);\n }\n } else if (nextHtml != null) {\n if (lastHtml !== nextHtml) {\n ReactComponent.DOMIDOperations.updateInnerHTMLByID(\n this._rootNodeID,\n nextHtml\n );\n }\n } else if (nextChildren != null) {\n this.updateChildren(nextChildren, transaction);\n }\n },\n\n /**\n * Destroys all event registrations for this instance. Does not remove from\n * the DOM. That must be done by the parent.\n *\n * @internal\n */\n unmountComponent: function() {\n ReactEventEmitter.deleteAllListeners(this._rootNodeID);\n ReactComponent.Mixin.unmountComponent.call(this);\n this.unmountChildren();\n }\n\n};\n\nmixInto(ReactDOMComponent, ReactComponent.Mixin);\nmixInto(ReactDOMComponent, ReactDOMComponent.Mixin);\nmixInto(ReactDOMComponent, ReactMultiChild.Mixin);\n\nmodule.exports = ReactDOMComponent;\n\nrequire(\"./mock-modules\").register(\"ReactDOMComponent\", module);\n", -"ReactMultiChild":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactMultiChild\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar ReactComponent = require(\"./ReactComponent\");\nvar ReactMultiChildUpdateTypes = require(\"./ReactMultiChildUpdateTypes\");\n\nvar flattenChildren = require(\"./flattenChildren\");\n\n/**\n * Given a `curChild` and `newChild`, determines if `curChild` should be\n * updated as opposed to being destroyed or replaced.\n *\n * @param {?ReactComponent} curChild\n * @param {?ReactComponent} newChild\n * @return {boolean} True if `curChild` should be updated with `newChild`.\n * @protected\n */\nfunction shouldUpdateChild(curChild, newChild) {\n return curChild && newChild && curChild.constructor === newChild.constructor;\n}\n\n/**\n * Updating children of a component may trigger recursive updates. The depth is\n * used to batch recursive updates to render markup more efficiently.\n *\n * @type {number}\n * @private\n */\nvar updateDepth = 0;\n\n/**\n * Queue of update configuration objects.\n *\n * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`.\n *\n * @type {array}\n * @private\n */\nvar updateQueue = [];\n\n/**\n * Queue of markup to be rendered.\n *\n * @type {array}\n * @private\n */\nvar markupQueue = [];\n\n/**\n * Enqueues markup to be rendered and inserted at a supplied index.\n *\n * @param {string} parentID ID of the parent component.\n * @param {string} markup Markup that renders into an element.\n * @param {number} toIndex Destination index.\n * @private\n */\nfunction enqueueMarkup(parentID, markup, toIndex) {\n // NOTE: Null values reduce hidden classes.\n updateQueue.push({\n parentID: parentID,\n parentNode: null,\n type: ReactMultiChildUpdateTypes.INSERT_MARKUP,\n markupIndex: markupQueue.push(markup) - 1,\n fromIndex: null,\n textContent: null,\n toIndex: toIndex\n });\n}\n\n/**\n * Enqueues moving an existing element to another index.\n *\n * @param {string} parentID ID of the parent component.\n * @param {number} fromIndex Source index of the existing element.\n * @param {number} toIndex Destination index of the element.\n * @private\n */\nfunction enqueueMove(parentID, fromIndex, toIndex) {\n // NOTE: Null values reduce hidden classes.\n updateQueue.push({\n parentID: parentID,\n parentNode: null,\n type: ReactMultiChildUpdateTypes.MOVE_EXISTING,\n markupIndex: null,\n textContent: null,\n fromIndex: fromIndex,\n toIndex: toIndex\n });\n}\n\n/**\n * Enqueues removing an element at an index.\n *\n * @param {string} parentID ID of the parent component.\n * @param {number} fromIndex Index of the element to remove.\n * @private\n */\nfunction enqueueRemove(parentID, fromIndex) {\n // NOTE: Null values reduce hidden classes.\n updateQueue.push({\n parentID: parentID,\n parentNode: null,\n type: ReactMultiChildUpdateTypes.REMOVE_NODE,\n markupIndex: null,\n textContent: null,\n fromIndex: fromIndex,\n toIndex: null\n });\n}\n\n/**\n * Enqueues setting the text content.\n *\n * @param {string} parentID ID of the parent component.\n * @param {string} textContent Text content to set.\n * @private\n */\nfunction enqueueTextContent(parentID, textContent) {\n // NOTE: Null values reduce hidden classes.\n updateQueue.push({\n parentID: parentID,\n parentNode: null,\n type: ReactMultiChildUpdateTypes.TEXT_CONTENT,\n markupIndex: null,\n textContent: textContent,\n fromIndex: null,\n toIndex: null\n });\n}\n\n/**\n * Processes any enqueued updates.\n *\n * @private\n */\nfunction processQueue() {\n if (updateQueue.length) {\n ReactComponent.DOMIDOperations.dangerouslyProcessChildrenUpdates(\n updateQueue,\n markupQueue\n );\n clearQueue();\n }\n}\n\n/**\n * Clears any enqueued updates.\n *\n * @private\n */\nfunction clearQueue() {\n updateQueue.length = 0;\n markupQueue.length = 0;\n}\n\n/**\n * ReactMultiChild are capable of reconciling multiple children.\n *\n * @class ReactMultiChild\n * @internal\n */\nvar ReactMultiChild = {\n\n /**\n * Provides common functionality for components that must reconcile multiple\n * children. This is used by `ReactDOMComponent` to mount, update, and\n * unmount child components.\n *\n * @lends {ReactMultiChild.prototype}\n */\n Mixin: {\n\n /**\n * Generates a \"mount image\" for each of the supplied children. In the case\n * of `ReactDOMComponent`, a mount image is a string of markup.\n *\n * @param {?object} nestedChildren Nested child maps.\n * @return {array} An array of mounted representations.\n * @internal\n */\n mountChildren: function(nestedChildren, transaction) {\n var children = flattenChildren(nestedChildren);\n var mountImages = [];\n var index = 0;\n this._renderedChildren = children;\n for (var name in children) {\n var child = children[name];\n if (children.hasOwnProperty(name) && child) {\n // Inlined for performance, see `ReactInstanceHandles.createReactID`.\n var rootID = this._rootNodeID + '.' + name;\n var mountImage = child.mountComponent(\n rootID,\n transaction,\n this._mountDepth + 1\n );\n child._mountImage = mountImage;\n child._mountIndex = index;\n mountImages.push(mountImage);\n index++;\n }\n }\n return mountImages;\n },\n\n /**\n * Replaces any rendered children with a text content string.\n *\n * @param {string} nextContent String of content.\n * @internal\n */\n updateTextContent: function(nextContent) {\n updateDepth++;\n try {\n var prevChildren = this._renderedChildren;\n // Remove any rendered children.\n for (var name in prevChildren) {\n if (prevChildren.hasOwnProperty(name) &&\n prevChildren[name]) {\n this._unmountChildByName(prevChildren[name], name);\n }\n }\n // Set new text content.\n this.setTextContent(nextContent);\n } catch (error) {\n updateDepth--;\n updateDepth || clearQueue();\n throw error;\n }\n updateDepth--;\n updateDepth || processQueue();\n },\n\n /**\n * Updates the rendered children with new children.\n *\n * @param {?object} nextNestedChildren Nested child maps.\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n updateChildren: function(nextNestedChildren, transaction) {\n updateDepth++;\n try {\n this._updateChildren(nextNestedChildren, transaction);\n } catch (error) {\n updateDepth--;\n updateDepth || clearQueue();\n throw error;\n }\n updateDepth--;\n updateDepth || processQueue();\n },\n\n /**\n * Improve performance by isolating this hot code path from the try/catch\n * block in `updateChildren`.\n *\n * @param {?object} nextNestedChildren Nested child maps.\n * @param {ReactReconcileTransaction} transaction\n * @final\n * @protected\n */\n _updateChildren: function(nextNestedChildren, transaction) {\n var nextChildren = flattenChildren(nextNestedChildren);\n var prevChildren = this._renderedChildren;\n if (!nextChildren && !prevChildren) {\n return;\n }\n var name;\n // `nextIndex` will increment for each child in `nextChildren`, but\n // `lastIndex` will be the last index visited in `prevChildren`.\n var lastIndex = 0;\n var nextIndex = 0;\n for (name in nextChildren) {\n if (!nextChildren.hasOwnProperty(name)) {\n continue;\n }\n var prevChild = prevChildren && prevChildren[name];\n var nextChild = nextChildren[name];\n if (shouldUpdateChild(prevChild, nextChild)) {\n this.moveChild(prevChild, nextIndex, lastIndex);\n lastIndex = Math.max(prevChild._mountIndex, lastIndex);\n prevChild.receiveProps(nextChild.props, transaction);\n prevChild._mountIndex = nextIndex;\n } else {\n if (prevChild) {\n // Update `lastIndex` before `_mountIndex` gets unset by unmounting.\n lastIndex = Math.max(prevChild._mountIndex, lastIndex);\n this._unmountChildByName(prevChild, name);\n }\n if (nextChild) {\n this._mountChildByNameAtIndex(\n nextChild, name, nextIndex, transaction\n );\n }\n }\n if (nextChild) {\n nextIndex++;\n }\n }\n // Remove children that are no longer present.\n for (name in prevChildren) {\n if (prevChildren.hasOwnProperty(name) &&\n prevChildren[name] &&\n !(nextChildren && nextChildren[name])) {\n this._unmountChildByName(prevChildren[name], name);\n }\n }\n },\n\n /**\n * Unmounts all rendered children. This should be used to clean up children\n * when this component is unmounted.\n *\n * @internal\n */\n unmountChildren: function() {\n var renderedChildren = this._renderedChildren;\n for (var name in renderedChildren) {\n var renderedChild = renderedChildren[name];\n if (renderedChild && renderedChild.unmountComponent) {\n renderedChild.unmountComponent();\n }\n }\n this._renderedChildren = null;\n },\n\n /**\n * Moves a child component to the supplied index.\n *\n * @param {ReactComponent} child Component to move.\n * @param {number} toIndex Destination index of the element.\n * @param {number} lastIndex Last index visited of the siblings of `child`.\n * @protected\n */\n moveChild: function(child, toIndex, lastIndex) {\n // If the index of `child` is less than `lastIndex`, then it needs to\n // be moved. Otherwise, we do not need to move it because a child will be\n // inserted or moved before `child`.\n if (child._mountIndex < lastIndex) {\n enqueueMove(this._rootNodeID, child._mountIndex, toIndex);\n }\n },\n\n /**\n * Creates a child component.\n *\n * @param {ReactComponent} child Component to create.\n * @protected\n */\n createChild: function(child) {\n enqueueMarkup(this._rootNodeID, child._mountImage, child._mountIndex);\n },\n\n /**\n * Removes a child component.\n *\n * @param {ReactComponent} child Child to remove.\n * @protected\n */\n removeChild: function(child) {\n enqueueRemove(this._rootNodeID, child._mountIndex);\n },\n\n /**\n * Sets this text content string.\n *\n * @param {string} textContent Text content to set.\n * @protected\n */\n setTextContent: function(textContent) {\n enqueueTextContent(this._rootNodeID, textContent);\n },\n\n /**\n * Mounts a child with the supplied name.\n *\n * NOTE: This is part of `updateChildren` and is here for readability.\n *\n * @param {ReactComponent} child Component to mount.\n * @param {string} name Name of the child.\n * @param {number} index Index at which to insert the child.\n * @param {ReactReconcileTransaction} transaction\n * @private\n */\n _mountChildByNameAtIndex: function(child, name, index, transaction) {\n // Inlined for performance, see `ReactInstanceHandles.createReactID`.\n var rootID = this._rootNodeID + '.' + name;\n var mountImage = child.mountComponent(\n rootID,\n transaction,\n this._mountDepth + 1\n );\n child._mountImage = mountImage;\n child._mountIndex = index;\n this.createChild(child);\n this._renderedChildren = this._renderedChildren || {};\n this._renderedChildren[name] = child;\n },\n\n /**\n * Unmounts a rendered child by name.\n *\n * NOTE: This is part of `updateChildren` and is here for readability.\n *\n * @param {ReactComponent} child Component to unmount.\n * @param {string} name Name of the child in `this._renderedChildren`.\n * @private\n */\n _unmountChildByName: function(child, name) {\n if (ReactComponent.isValidComponent(child)) {\n this.removeChild(child);\n child._mountImage = null;\n child._mountIndex = null;\n child.unmountComponent();\n delete this._renderedChildren[name];\n }\n }\n\n }\n\n};\n\nmodule.exports = ReactMultiChild;\n\nrequire(\"./mock-modules\").register(\"ReactMultiChild\", module);\n", -"ReactEventEmitter":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactEventEmitter\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar EventConstants = require(\"./EventConstants\");\nvar EventListener = require(\"./EventListener\");\nvar EventPluginHub = require(\"./EventPluginHub\");\nvar ExecutionEnvironment = require(\"./ExecutionEnvironment\");\nvar ReactEventEmitterMixin = require(\"./ReactEventEmitterMixin\");\nvar ViewportMetrics = require(\"./ViewportMetrics\");\n\nvar invariant = require(\"./invariant\");\nvar isEventSupported = require(\"./isEventSupported\");\nvar merge = require(\"./merge\");\n\n/**\n * Summary of `ReactEventEmitter` event handling:\n *\n * - Top-level delegation is used to trap native browser events. We normalize\n * and de-duplicate events to account for browser quirks.\n *\n * - Forward these native events (with the associated top-level type used to\n * trap it) to `EventPluginHub`, which in turn will ask plugins if they want\n * to extract any synthetic events.\n *\n * - The `EventPluginHub` will then process each event by annotating them with\n * \"dispatches\", a sequence of listeners and IDs that care about that event.\n *\n * - The `EventPluginHub` then dispatches the events.\n *\n * Overview of React and the event system:\n *\n * .\n * +------------+ .\n * | DOM | .\n * +------------+ . +-----------+\n * + . +--------+|SimpleEvent|\n * | . | |Plugin |\n * +-----|------+ . v +-----------+\n * | | | . +--------------+ +------------+\n * | +-----------.--->|EventPluginHub| | Event |\n * | | . | | +-----------+ | Propagators|\n * | ReactEvent | . | | |TapEvent | |------------|\n * | Emitter | . | |<---+|Plugin | |other plugin|\n * | | . | | +-----------+ | utilities |\n * | +-----------.---------+ | +------------+\n * | | | . +----|---------+\n * +-----|------+ . | ^ +-----------+\n * | . | | |Enter/Leave|\n * + . | +-------+|Plugin |\n * +-------------+ . v +-----------+\n * | application | . +----------+\n * |-------------| . | callback |\n * | | . | registry |\n * | | . +----------+\n * +-------------+ .\n * .\n * React Core . General Purpose Event Plugin System\n */\n\n/**\n * Traps top-level events by using event bubbling.\n *\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {string} handlerBaseName Event name (e.g. \"click\").\n * @param {DOMEventTarget} element Element on which to attach listener.\n * @internal\n */\nfunction trapBubbledEvent(topLevelType, handlerBaseName, element) {\n EventListener.listen(\n element,\n handlerBaseName,\n ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(\n topLevelType\n )\n );\n}\n\n/**\n * Traps a top-level event by using event capturing.\n *\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {string} handlerBaseName Event name (e.g. \"click\").\n * @param {DOMEventTarget} element Element on which to attach listener.\n * @internal\n */\nfunction trapCapturedEvent(topLevelType, handlerBaseName, element) {\n EventListener.capture(\n element,\n handlerBaseName,\n ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(\n topLevelType\n )\n );\n}\n\n/**\n * Listens to window scroll and resize events. We cache scroll values so that\n * application code can access them without triggering reflows.\n *\n * NOTE: Scroll events do not bubble.\n *\n * @private\n * @see http://www.quirksmode.org/dom/events/scroll.html\n */\nfunction registerScrollValueMonitoring() {\n var refresh = ViewportMetrics.refreshScrollValues;\n EventListener.listen(window, 'scroll', refresh);\n EventListener.listen(window, 'resize', refresh);\n}\n\n/**\n * `ReactEventEmitter` is used to attach top-level event listeners. For example:\n *\n * ReactEventEmitter.putListener('myID', 'onClick', myFunction);\n *\n * This would allocate a \"registration\" of `('onClick', myFunction)` on 'myID'.\n *\n * @internal\n */\nvar ReactEventEmitter = merge(ReactEventEmitterMixin, {\n\n /**\n * React references `ReactEventTopLevelCallback` using this property in order\n * to allow dependency injection.\n */\n TopLevelCallbackCreator: null,\n\n /**\n * Ensures that top-level event delegation listeners are installed.\n *\n * There are issues with listening to both touch events and mouse events on\n * the top-level, so we make the caller choose which one to listen to. (If\n * there's a touch top-level listeners, anchors don't receive clicks for some\n * reason, and only in some cases).\n *\n * @param {boolean} touchNotMouse Listen to touch events instead of mouse.\n * @param {DOMDocument} contentDocument DOM document to listen on\n */\n ensureListening: function(touchNotMouse, contentDocument) {\n invariant(\n ExecutionEnvironment.canUseDOM,\n 'ensureListening(...): Cannot toggle event listening in a Worker ' +\n 'thread. This is likely a bug in the framework. Please report ' +\n 'immediately.'\n );\n invariant(\n ReactEventEmitter.TopLevelCallbackCreator,\n 'ensureListening(...): Cannot be called without a top level callback ' +\n 'creator being injected.'\n );\n // Call out to base implementation.\n ReactEventEmitterMixin.ensureListening.call(\n ReactEventEmitter,\n {\n touchNotMouse: touchNotMouse,\n contentDocument: contentDocument\n }\n );\n },\n\n /**\n * Sets whether or not any created callbacks should be enabled.\n *\n * @param {boolean} enabled True if callbacks should be enabled.\n */\n setEnabled: function(enabled) {\n invariant(\n ExecutionEnvironment.canUseDOM,\n 'setEnabled(...): Cannot toggle event listening in a Worker thread. ' +\n 'This is likely a bug in the framework. Please report immediately.'\n );\n if (ReactEventEmitter.TopLevelCallbackCreator) {\n ReactEventEmitter.TopLevelCallbackCreator.setEnabled(enabled);\n }\n },\n\n /**\n * @return {boolean} True if callbacks are enabled.\n */\n isEnabled: function() {\n return !!(\n ReactEventEmitter.TopLevelCallbackCreator &&\n ReactEventEmitter.TopLevelCallbackCreator.isEnabled()\n );\n },\n\n /**\n * We listen for bubbled touch events on the document object.\n *\n * Firefox v8.01 (and possibly others) exhibited strange behavior when\n * mounting `onmousemove` events at some node that was not the document\n * element. The symptoms were that if your mouse is not moving over something\n * contained within that mount point (for example on the background) the\n * top-level listeners for `onmousemove` won't be called. However, if you\n * register the `mousemove` on the document object, then it will of course\n * catch all `mousemove`s. This along with iOS quirks, justifies restricting\n * top-level listeners to the document object only, at least for these\n * movement types of events and possibly all events.\n *\n * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html\n *\n * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but\n * they bubble to document.\n *\n * @param {boolean} touchNotMouse Listen to touch events instead of mouse.\n * @param {DOMDocument} contentDocument Document which owns the container\n * @private\n * @see http://www.quirksmode.org/dom/events/keys.html.\n */\n listenAtTopLevel: function(touchNotMouse, contentDocument) {\n invariant(\n !contentDocument._isListening,\n 'listenAtTopLevel(...): Cannot setup top-level listener more than once.'\n );\n var topLevelTypes = EventConstants.topLevelTypes;\n var mountAt = contentDocument;\n\n registerScrollValueMonitoring();\n trapBubbledEvent(topLevelTypes.topMouseOver, 'mouseover', mountAt);\n trapBubbledEvent(topLevelTypes.topMouseDown, 'mousedown', mountAt);\n trapBubbledEvent(topLevelTypes.topMouseUp, 'mouseup', mountAt);\n trapBubbledEvent(topLevelTypes.topMouseMove, 'mousemove', mountAt);\n trapBubbledEvent(topLevelTypes.topMouseOut, 'mouseout', mountAt);\n trapBubbledEvent(topLevelTypes.topClick, 'click', mountAt);\n trapBubbledEvent(topLevelTypes.topDoubleClick, 'dblclick', mountAt);\n if (touchNotMouse) {\n trapBubbledEvent(topLevelTypes.topTouchStart, 'touchstart', mountAt);\n trapBubbledEvent(topLevelTypes.topTouchEnd, 'touchend', mountAt);\n trapBubbledEvent(topLevelTypes.topTouchMove, 'touchmove', mountAt);\n trapBubbledEvent(topLevelTypes.topTouchCancel, 'touchcancel', mountAt);\n }\n trapBubbledEvent(topLevelTypes.topKeyUp, 'keyup', mountAt);\n trapBubbledEvent(topLevelTypes.topKeyPress, 'keypress', mountAt);\n trapBubbledEvent(topLevelTypes.topKeyDown, 'keydown', mountAt);\n trapBubbledEvent(topLevelTypes.topInput, 'input', mountAt);\n trapBubbledEvent(topLevelTypes.topChange, 'change', mountAt);\n trapBubbledEvent(\n topLevelTypes.topSelectionChange,\n 'selectionchange',\n mountAt\n );\n\n trapBubbledEvent(\n topLevelTypes.topCompositionEnd,\n 'compositionend',\n mountAt\n );\n trapBubbledEvent(\n topLevelTypes.topCompositionStart,\n 'compositionstart',\n mountAt\n );\n trapBubbledEvent(\n topLevelTypes.topCompositionUpdate,\n 'compositionupdate',\n mountAt\n );\n\n if (isEventSupported('drag')) {\n trapBubbledEvent(topLevelTypes.topDrag, 'drag', mountAt);\n trapBubbledEvent(topLevelTypes.topDragEnd, 'dragend', mountAt);\n trapBubbledEvent(topLevelTypes.topDragEnter, 'dragenter', mountAt);\n trapBubbledEvent(topLevelTypes.topDragExit, 'dragexit', mountAt);\n trapBubbledEvent(topLevelTypes.topDragLeave, 'dragleave', mountAt);\n trapBubbledEvent(topLevelTypes.topDragOver, 'dragover', mountAt);\n trapBubbledEvent(topLevelTypes.topDragStart, 'dragstart', mountAt);\n trapBubbledEvent(topLevelTypes.topDrop, 'drop', mountAt);\n }\n\n if (isEventSupported('wheel')) {\n trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt);\n } else if (isEventSupported('mousewheel')) {\n trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt);\n } else {\n // Firefox needs to capture a different mouse scroll event.\n // @see http://www.quirksmode.org/dom/events/tests/scroll.html\n trapBubbledEvent(topLevelTypes.topWheel, 'DOMMouseScroll', mountAt);\n }\n\n // IE<9 does not support capturing so just trap the bubbled event there.\n if (isEventSupported('scroll', true)) {\n trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt);\n } else {\n trapBubbledEvent(topLevelTypes.topScroll, 'scroll', window);\n }\n\n if (isEventSupported('focus', true)) {\n trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt);\n trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);\n } else if (isEventSupported('focusin')) {\n // IE has `focusin` and `focusout` events which bubble.\n // @see\n // http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html\n trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);\n trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);\n }\n\n if (isEventSupported('copy')) {\n trapBubbledEvent(topLevelTypes.topCopy, 'copy', mountAt);\n trapBubbledEvent(topLevelTypes.topCut, 'cut', mountAt);\n trapBubbledEvent(topLevelTypes.topPaste, 'paste', mountAt);\n }\n },\n\n registrationNames: EventPluginHub.registrationNames,\n\n putListener: EventPluginHub.putListener,\n\n getListener: EventPluginHub.getListener,\n\n deleteListener: EventPluginHub.deleteListener,\n\n deleteAllListeners: EventPluginHub.deleteAllListeners,\n\n trapBubbledEvent: trapBubbledEvent,\n\n trapCapturedEvent: trapCapturedEvent\n\n});\n\n\nmodule.exports = ReactEventEmitter;\n\nrequire(\"./mock-modules\").register(\"ReactEventEmitter\", module);\n", -"DOMPropertyOperations":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule DOMPropertyOperations\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar DOMProperty = require(\"./DOMProperty\");\n\nvar escapeTextForBrowser = require(\"./escapeTextForBrowser\");\nvar memoizeStringOnly = require(\"./memoizeStringOnly\");\n\nvar processAttributeNameAndPrefix = memoizeStringOnly(function(name) {\n return escapeTextForBrowser(name) + '=\"';\n});\n\nif (true) {\n var reactProps = {\n __owner__: true,\n children: true,\n dangerouslySetInnerHTML: true,\n key: true,\n ref: true\n };\n var warnedProperties = {};\n\n var warnUnknownProperty = function(name) {\n if (reactProps[name] || warnedProperties[name]) {\n return;\n }\n\n warnedProperties[name] = true;\n var lowerCasedName = name.toLowerCase();\n\n // data-* attributes should be lowercase; suggest the lowercase version\n var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ?\n lowerCasedName : DOMProperty.getPossibleStandardName[lowerCasedName];\n\n // For now, only warn when we have a suggested correction. This prevents\n // logging too much when using transferPropsTo.\n if (standardName != null) {\n console.warn(\n 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?'\n );\n }\n\n };\n}\n\n/**\n * Operations for dealing with DOM properties.\n */\nvar DOMPropertyOperations = {\n\n /**\n * Creates markup for a property.\n *\n * @param {string} name\n * @param {*} value\n * @return {?string} Markup string, or null if the property was invalid.\n */\n createMarkupForProperty: function(name, value) {\n if (DOMProperty.isStandardName[name]) {\n if (value == null || DOMProperty.hasBooleanValue[name] && !value) {\n return '';\n }\n var attributeName = DOMProperty.getAttributeName[name];\n return processAttributeNameAndPrefix(attributeName) +\n escapeTextForBrowser(value) + '\"';\n } else if (DOMProperty.isCustomAttribute(name)) {\n if (value == null) {\n return '';\n }\n return processAttributeNameAndPrefix(name) +\n escapeTextForBrowser(value) + '\"';\n } else if (true) {\n warnUnknownProperty(name);\n }\n return null;\n },\n\n /**\n * Sets the value for a property on a node.\n *\n * @param {DOMElement} node\n * @param {string} name\n * @param {*} value\n */\n setValueForProperty: function(node, name, value) {\n if (DOMProperty.isStandardName[name]) {\n var mutationMethod = DOMProperty.getMutationMethod[name];\n if (mutationMethod) {\n mutationMethod(node, value);\n } else if (DOMProperty.mustUseAttribute[name]) {\n if (DOMProperty.hasBooleanValue[name] && !value) {\n node.removeAttribute(DOMProperty.getAttributeName[name]);\n } else {\n node.setAttribute(DOMProperty.getAttributeName[name], '' + value);\n }\n } else {\n var propName = DOMProperty.getPropertyName[name];\n if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) {\n node[propName] = value;\n }\n }\n } else if (DOMProperty.isCustomAttribute(name)) {\n node.setAttribute(name, '' + value);\n } else if (true) {\n warnUnknownProperty(name);\n }\n },\n\n /**\n * Deletes the value for a property on a node.\n *\n * @param {DOMElement} node\n * @param {string} name\n */\n deleteValueForProperty: function(node, name) {\n if (DOMProperty.isStandardName[name]) {\n var mutationMethod = DOMProperty.getMutationMethod[name];\n if (mutationMethod) {\n mutationMethod(node, undefined);\n } else if (DOMProperty.mustUseAttribute[name]) {\n node.removeAttribute(DOMProperty.getAttributeName[name]);\n } else {\n var propName = DOMProperty.getPropertyName[name];\n node[propName] = DOMProperty.getDefaultValueForProperty(\n node.nodeName,\n name\n );\n }\n } else if (DOMProperty.isCustomAttribute(name)) {\n node.removeAttribute(name);\n } else if (true) {\n warnUnknownProperty(name);\n }\n }\n\n};\n\nmodule.exports = DOMPropertyOperations;\n\nrequire(\"./mock-modules\").register(\"DOMPropertyOperations\", module);\n", -"ReactDOMIDOperations":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactDOMIDOperations\n * @typechecks static-only\n */\n\n/*jslint evil: true */\n\n\"use strict\";\n\nvar CSSPropertyOperations = require(\"./CSSPropertyOperations\");\nvar DOMChildrenOperations = require(\"./DOMChildrenOperations\");\nvar DOMPropertyOperations = require(\"./DOMPropertyOperations\");\nvar ReactMount = require(\"./ReactMount\");\n\nvar getTextContentAccessor = require(\"./getTextContentAccessor\");\nvar invariant = require(\"./invariant\");\n\n/**\n * Errors for properties that should not be updated with `updatePropertyById()`.\n *\n * @type {object}\n * @private\n */\nvar INVALID_PROPERTY_ERRORS = {\n dangerouslySetInnerHTML:\n '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',\n style: '`style` must be set using `updateStylesByID()`.'\n};\n\n/**\n * The DOM property to use when setting text content.\n *\n * @type {string}\n * @private\n */\nvar textContentAccessor = getTextContentAccessor() || 'NA';\n\nvar LEADING_SPACE = /^ /;\n\n/**\n * Operations used to process updates to DOM nodes. This is made injectable via\n * `ReactComponent.DOMIDOperations`.\n */\nvar ReactDOMIDOperations = {\n\n /**\n * Updates a DOM node with new property values. This should only be used to\n * update DOM properties in `DOMProperty`.\n *\n * @param {string} id ID of the node to update.\n * @param {string} name A valid property name, see `DOMProperty`.\n * @param {*} value New value of the property.\n * @internal\n */\n updatePropertyByID: function(id, name, value) {\n var node = ReactMount.getNode(id);\n invariant(\n !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),\n 'updatePropertyByID(...): %s',\n INVALID_PROPERTY_ERRORS[name]\n );\n\n // If we're updating to null or undefined, we should remove the property\n // from the DOM node instead of inadvertantly setting to a string. This\n // brings us in line with the same behavior we have on initial render.\n if (value != null) {\n DOMPropertyOperations.setValueForProperty(node, name, value);\n } else {\n DOMPropertyOperations.deleteValueForProperty(node, name);\n }\n },\n\n /**\n * Updates a DOM node to remove a property. This should only be used to remove\n * DOM properties in `DOMProperty`.\n *\n * @param {string} id ID of the node to update.\n * @param {string} name A property name to remove, see `DOMProperty`.\n * @internal\n */\n deletePropertyByID: function(id, name, value) {\n var node = ReactMount.getNode(id);\n invariant(\n !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),\n 'updatePropertyByID(...): %s',\n INVALID_PROPERTY_ERRORS[name]\n );\n DOMPropertyOperations.deleteValueForProperty(node, name, value);\n },\n\n /**\n * This should almost never be used instead of `updatePropertyByID()` due to\n * the extra object allocation required by the API. That said, this is useful\n * for batching up several operations across worker thread boundaries.\n *\n * @param {string} id ID of the node to update.\n * @param {object} properties A mapping of valid property names.\n * @internal\n * @see {ReactDOMIDOperations.updatePropertyByID}\n */\n updatePropertiesByID: function(id, properties) {\n for (var name in properties) {\n if (!properties.hasOwnProperty(name)) {\n continue;\n }\n ReactDOMIDOperations.updatePropertiesByID(id, name, properties[name]);\n }\n },\n\n /**\n * Updates a DOM node with new style values. If a value is specified as '',\n * the corresponding style property will be unset.\n *\n * @param {string} id ID of the node to update.\n * @param {object} styles Mapping from styles to values.\n * @internal\n */\n updateStylesByID: function(id, styles) {\n var node = ReactMount.getNode(id);\n CSSPropertyOperations.setValueForStyles(node, styles);\n },\n\n /**\n * Updates a DOM node's innerHTML.\n *\n * @param {string} id ID of the node to update.\n * @param {string} html An HTML string.\n * @internal\n */\n updateInnerHTMLByID: function(id, html) {\n var node = ReactMount.getNode(id);\n // HACK: IE8- normalize whitespace in innerHTML, removing leading spaces.\n // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html\n node.innerHTML = html.replace(LEADING_SPACE, ' ');\n },\n\n /**\n * Updates a DOM node's text content set by `props.content`.\n *\n * @param {string} id ID of the node to update.\n * @param {string} content Text content.\n * @internal\n */\n updateTextContentByID: function(id, content) {\n var node = ReactMount.getNode(id);\n node[textContentAccessor] = content;\n },\n\n /**\n * Replaces a DOM node that exists in the document with markup.\n *\n * @param {string} id ID of child to be replaced.\n * @param {string} markup Dangerous markup to inject in place of child.\n * @internal\n * @see {Danger.dangerouslyReplaceNodeWithMarkup}\n */\n dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {\n var node = ReactMount.getNode(id);\n DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);\n },\n\n /**\n * Updates a component's children by processing a series of updates.\n *\n * @param {array} updates List of update configurations.\n * @param {array} markup List of markup strings.\n * @internal\n */\n dangerouslyProcessChildrenUpdates: function(updates, markup) {\n for (var i = 0; i < updates.length; i++) {\n updates[i].parentNode = ReactMount.getNode(updates[i].parentID);\n }\n DOMChildrenOperations.processUpdates(updates, markup);\n }\n\n};\n\nmodule.exports = ReactDOMIDOperations;\n\nrequire(\"./mock-modules\").register(\"ReactDOMIDOperations\", module);\n", -"keyOf":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule keyOf\n */\n\n/**\n * Allows extraction of a minified key. Let's the build system minify keys\n * without loosing the ability to dynamically use key strings as values\n * themselves. Pass in an object with a single key/val pair and it will return\n * you the string key of that single record. Suppose you want to grab the\n * value for a key 'className' inside of an object. Key/val minification may\n * have aliased that key to be 'xa12'. keyOf({className: null}) will return\n * 'xa12' in that case. Resolve keys you want to use once at startup time, then\n * reuse those resolutions.\n */\nvar keyOf = function(oneKeyObj) {\n var key;\n for (key in oneKeyObj) {\n if (!oneKeyObj.hasOwnProperty(key)) {\n continue;\n }\n return key;\n }\n return null;\n};\n\n\nmodule.exports = keyOf;\n\nrequire(\"./mock-modules\").register(\"keyOf\", module);\n", -"EventPluginHub":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule EventPluginHub\n */\n\n\"use strict\";\n\nvar CallbackRegistry = require(\"./CallbackRegistry\");\nvar EventPluginRegistry = require(\"./EventPluginRegistry\");\nvar EventPluginUtils = require(\"./EventPluginUtils\");\nvar EventPropagators = require(\"./EventPropagators\");\nvar ExecutionEnvironment = require(\"./ExecutionEnvironment\");\n\nvar accumulate = require(\"./accumulate\");\nvar forEachAccumulated = require(\"./forEachAccumulated\");\nvar invariant = require(\"./invariant\");\n\n/**\n * Internal queue of events that have accumulated their dispatches and are\n * waiting to have their dispatches executed.\n */\nvar eventQueue = null;\n\n/**\n * Dispatches an event and releases it back into the pool, unless persistent.\n *\n * @param {?object} event Synthetic event to be dispatched.\n * @private\n */\nvar executeDispatchesAndRelease = function(event) {\n if (event) {\n var executeDispatch = EventPluginUtils.executeDispatch;\n // Plugins can provide custom behavior when dispatching events.\n var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event);\n if (PluginModule && PluginModule.executeDispatch) {\n executeDispatch = PluginModule.executeDispatch;\n }\n EventPluginUtils.executeDispatchesInOrder(event, executeDispatch);\n\n if (!event.isPersistent()) {\n event.constructor.release(event);\n }\n }\n};\n\n/**\n * This is a unified interface for event plugins to be installed and configured.\n *\n * Event plugins can implement the following properties:\n *\n * `extractEvents` {function(string, DOMEventTarget, string, object): *}\n * Required. When a top-level event is fired, this method is expected to\n * extract synthetic events that will in turn be queued and dispatched.\n *\n * `eventTypes` {object}\n * Optional, plugins that fire events must publish a mapping of registration\n * names that are used to register listeners. Values of this mapping must\n * be objects that contain `registrationName` or `phasedRegistrationNames`.\n *\n * `executeDispatch` {function(object, function, string)}\n * Optional, allows plugins to override how an event gets dispatched. By\n * default, the listener is simply invoked.\n *\n * Each plugin that is injected into `EventsPluginHub` is immediately operable.\n *\n * @public\n */\nvar EventPluginHub = {\n\n /**\n * Methods for injecting dependencies.\n */\n injection: {\n\n /**\n * @param {object} InjectedInstanceHandle\n * @public\n */\n injectInstanceHandle: EventPropagators.injection.injectInstanceHandle,\n\n /**\n * @param {array} InjectedEventPluginOrder\n * @public\n */\n injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,\n\n /**\n * @param {object} injectedNamesToPlugins Map from names to plugin modules.\n */\n injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName\n\n },\n\n registrationNames: EventPluginRegistry.registrationNames,\n\n putListener: CallbackRegistry.putListener,\n\n getListener: CallbackRegistry.getListener,\n\n deleteListener: CallbackRegistry.deleteListener,\n\n deleteAllListeners: CallbackRegistry.deleteAllListeners,\n\n /**\n * Allows registered plugins an opportunity to extract events from top-level\n * native browser events.\n *\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {DOMEventTarget} topLevelTarget The listening component root node.\n * @param {string} topLevelTargetID ID of `topLevelTarget`.\n * @param {object} nativeEvent Native browser event.\n * @return {*} An accumulation of synthetic events.\n * @internal\n */\n extractEvents: function(\n topLevelType,\n topLevelTarget,\n topLevelTargetID,\n nativeEvent) {\n var events;\n var plugins = EventPluginRegistry.plugins;\n for (var i = 0, l = plugins.length; i < l; i++) {\n // Not every plugin in the ordering may be loaded at runtime.\n var possiblePlugin = plugins[i];\n if (possiblePlugin) {\n var extractedEvents = possiblePlugin.extractEvents(\n topLevelType,\n topLevelTarget,\n topLevelTargetID,\n nativeEvent\n );\n if (extractedEvents) {\n events = accumulate(events, extractedEvents);\n }\n }\n }\n return events;\n },\n\n /**\n * Enqueues a synthetic event that should be dispatched when\n * `processEventQueue` is invoked.\n *\n * @param {*} events An accumulation of synthetic events.\n * @internal\n */\n enqueueEvents: function(events) {\n if (events) {\n eventQueue = accumulate(eventQueue, events);\n }\n },\n\n /**\n * Dispatches all synthetic events on the event queue.\n *\n * @internal\n */\n processEventQueue: function() {\n // Set `eventQueue` to null before processing it so that we can tell if more\n // events get enqueued while processing.\n var processingEventQueue = eventQueue;\n eventQueue = null;\n forEachAccumulated(processingEventQueue, executeDispatchesAndRelease);\n invariant(\n !eventQueue,\n 'processEventQueue(): Additional events were enqueued while processing ' +\n 'an event queue. Support for this has not yet been implemented.'\n );\n }\n\n};\n\nif (ExecutionEnvironment.canUseDOM) {\n window.EventPluginHub = EventPluginHub;\n}\n\nmodule.exports = EventPluginHub;\n\nrequire(\"./mock-modules\").register(\"EventPluginHub\", module);\n", -"TapEventPlugin":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule TapEventPlugin\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar EventPluginUtils = require(\"./EventPluginUtils\");\nvar EventPropagators = require(\"./EventPropagators\");\nvar SyntheticUIEvent = require(\"./SyntheticUIEvent\");\nvar TouchEventUtils = require(\"./TouchEventUtils\");\nvar ViewportMetrics = require(\"./ViewportMetrics\");\n\nvar keyOf = require(\"./keyOf\");\n\nvar isStartish = EventPluginUtils.isStartish;\nvar isEndish = EventPluginUtils.isEndish;\n\n/**\n * Number of pixels that are tolerated in between a `touchStart` and `touchEnd`\n * in order to still be considered a 'tap' event.\n */\nvar tapMoveThreshold = 10;\nvar startCoords = {x: null, y: null};\n\nvar Axis = {\n x: {page: 'pageX', client: 'clientX', envScroll: 'currentPageScrollLeft'},\n y: {page: 'pageY', client: 'clientY', envScroll: 'currentPageScrollTop'}\n};\n\nfunction getAxisCoordOfEvent(axis, nativeEvent) {\n var singleTouch = TouchEventUtils.extractSingleTouch(nativeEvent);\n if (singleTouch) {\n return singleTouch[axis.page];\n }\n return axis.page in nativeEvent ?\n nativeEvent[axis.page] :\n nativeEvent[axis.client] + ViewportMetrics[axis.envScroll];\n}\n\nfunction getDistance(coords, nativeEvent) {\n var pageX = getAxisCoordOfEvent(Axis.x, nativeEvent);\n var pageY = getAxisCoordOfEvent(Axis.y, nativeEvent);\n return Math.pow(\n Math.pow(pageX - coords.x, 2) + Math.pow(pageY - coords.y, 2),\n 0.5\n );\n}\n\nvar eventTypes = {\n touchTap: {\n phasedRegistrationNames: {\n bubbled: keyOf({onTouchTap: null}),\n captured: keyOf({onTouchTapCapture: null})\n }\n }\n};\n\nvar TapEventPlugin = {\n\n tapMoveThreshold: tapMoveThreshold,\n\n eventTypes: eventTypes,\n\n /**\n * @param {string} topLevelType Record from `EventConstants`.\n * @param {DOMEventTarget} topLevelTarget The listening component root node.\n * @param {string} topLevelTargetID ID of `topLevelTarget`.\n * @param {object} nativeEvent Native browser event.\n * @return {*} An accumulation of synthetic events.\n * @see {EventPluginHub.extractEvents}\n */\n extractEvents: function(\n topLevelType,\n topLevelTarget,\n topLevelTargetID,\n nativeEvent) {\n if (!isStartish(topLevelType) && !isEndish(topLevelType)) {\n return null;\n }\n var event = null;\n var distance = getDistance(startCoords, nativeEvent);\n if (isEndish(topLevelType) && distance < tapMoveThreshold) {\n event = SyntheticUIEvent.getPooled(\n eventTypes.touchTap,\n topLevelTargetID,\n nativeEvent\n );\n }\n if (isStartish(topLevelType)) {\n startCoords.x = getAxisCoordOfEvent(Axis.x, nativeEvent);\n startCoords.y = getAxisCoordOfEvent(Axis.y, nativeEvent);\n } else if (isEndish(topLevelType)) {\n startCoords.x = 0;\n startCoords.y = 0;\n }\n EventPropagators.accumulateTwoPhaseDispatches(event);\n return event;\n }\n\n};\n\nmodule.exports = TapEventPlugin;\n\nrequire(\"./mock-modules\").register(\"TapEventPlugin\", module);\n", -"ReactInstanceHandles":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactInstanceHandles\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar invariant = require(\"./invariant\");\n\nvar SEPARATOR = '.';\nvar SEPARATOR_LENGTH = SEPARATOR.length;\n\n/**\n * Maximum depth of traversals before we consider the possibility of a bad ID.\n */\nvar MAX_TREE_DEPTH = 100;\n\n/**\n * Size of the reactRoot ID space. We generate random numbers for React root\n * IDs and if there's a collision the events and DOM update system will\n * get confused. If we assume 100 React components per page, and a user\n * loads 1 page per minute 24/7 for 50 years, with a mount point space of\n * 9,999,999 the likelihood of never having a collision is 99.997%.\n */\nvar GLOBAL_MOUNT_POINT_MAX = 9999999;\n\n/**\n * Creates a DOM ID prefix to use when mounting React components.\n *\n * @param {number} index A unique integer\n * @return {string} React root ID.\n * @internal\n */\nfunction getReactRootIDString(index) {\n return SEPARATOR + 'r[' + index.toString(36) + ']';\n}\n\n/**\n * Checks if a character in the supplied ID is a separator or the end.\n *\n * @param {string} id A React DOM ID.\n * @param {number} index Index of the character to check.\n * @return {boolean} True if the character is a separator or end of the ID.\n * @private\n */\nfunction isBoundary(id, index) {\n return id.charAt(index) === SEPARATOR || index === id.length;\n}\n\n/**\n * Checks if the supplied string is a valid React DOM ID.\n *\n * @param {string} id A React DOM ID, maybe.\n * @return {boolean} True if the string is a valid React DOM ID.\n * @private\n */\nfunction isValidID(id) {\n return id === '' || (\n id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR\n );\n}\n\n/**\n * Checks if the first ID is an ancestor of or equal to the second ID.\n *\n * @param {string} ancestorID\n * @param {string} descendantID\n * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`.\n * @internal\n */\nfunction isAncestorIDOf(ancestorID, descendantID) {\n return (\n descendantID.indexOf(ancestorID) === 0 &&\n isBoundary(descendantID, ancestorID.length)\n );\n}\n\n/**\n * Gets the parent ID of the supplied React DOM ID, `id`.\n *\n * @param {string} id ID of a component.\n * @return {string} ID of the parent, or an empty string.\n * @private\n */\nfunction getParentID(id) {\n return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';\n}\n\n/**\n * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the\n * supplied `destinationID`. If they are equal, the ID is returned.\n *\n * @param {string} ancestorID ID of an ancestor node of `destinationID`.\n * @param {string} destinationID ID of the destination node.\n * @return {string} Next ID on the path from `ancestorID` to `destinationID`.\n * @private\n */\nfunction getNextDescendantID(ancestorID, destinationID) {\n invariant(\n isValidID(ancestorID) && isValidID(destinationID),\n 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.',\n ancestorID,\n destinationID\n );\n invariant(\n isAncestorIDOf(ancestorID, destinationID),\n 'getNextDescendantID(...): React has made an invalid assumption about ' +\n 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.',\n ancestorID,\n destinationID\n );\n if (ancestorID === destinationID) {\n return ancestorID;\n }\n // Skip over the ancestor and the immediate separator. Traverse until we hit\n // another separator or we reach the end of `destinationID`.\n var start = ancestorID.length + SEPARATOR_LENGTH;\n for (var i = start; i < destinationID.length; i++) {\n if (isBoundary(destinationID, i)) {\n break;\n }\n }\n return destinationID.substr(0, i);\n}\n\n/**\n * Gets the nearest common ancestor ID of two IDs.\n *\n * Using this ID scheme, the nearest common ancestor ID is the longest common\n * prefix of the two IDs that immediately preceded a \"marker\" in both strings.\n *\n * @param {string} oneID\n * @param {string} twoID\n * @return {string} Nearest common ancestor ID, or the empty string if none.\n * @private\n */\nfunction getFirstCommonAncestorID(oneID, twoID) {\n var minLength = Math.min(oneID.length, twoID.length);\n if (minLength === 0) {\n return '';\n }\n var lastCommonMarkerIndex = 0;\n // Use `<=` to traverse until the \"EOL\" of the shorter string.\n for (var i = 0; i <= minLength; i++) {\n if (isBoundary(oneID, i) && isBoundary(twoID, i)) {\n lastCommonMarkerIndex = i;\n } else if (oneID.charAt(i) !== twoID.charAt(i)) {\n break;\n }\n }\n var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);\n invariant(\n isValidID(longestCommonID),\n 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s',\n oneID,\n twoID,\n longestCommonID\n );\n return longestCommonID;\n}\n\n/**\n * Traverses the parent path between two IDs (either up or down). The IDs must\n * not be the same, and there must exist a parent path between them.\n *\n * @param {?string} start ID at which to start traversal.\n * @param {?string} stop ID at which to end traversal.\n * @param {function} cb Callback to invoke each ID with.\n * @param {?boolean} skipFirst Whether or not to skip the first node.\n * @param {?boolean} skipLast Whether or not to skip the last node.\n * @private\n */\nfunction traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {\n start = start || '';\n stop = stop || '';\n invariant(\n start !== stop,\n 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.',\n start\n );\n var traverseUp = isAncestorIDOf(stop, start);\n invariant(\n traverseUp || isAncestorIDOf(start, stop),\n 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' +\n 'not have a parent path.',\n start,\n stop\n );\n // Traverse from `start` to `stop` one depth at a time.\n var depth = 0;\n var traverse = traverseUp ? getParentID : getNextDescendantID;\n for (var id = start; /* until break */; id = traverse(id, stop)) {\n if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {\n cb(id, traverseUp, arg);\n }\n if (id === stop) {\n // Only break //after// visiting `stop`.\n break;\n }\n invariant(\n depth++ < MAX_TREE_DEPTH,\n 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' +\n 'traversing the React DOM ID tree. This may be due to malformed IDs: %s',\n start, stop\n );\n }\n}\n\n/**\n * Manages the IDs assigned to DOM representations of React components. This\n * uses a specific scheme in order to traverse the DOM efficiently (e.g. in\n * order to simulate events).\n *\n * @internal\n */\nvar ReactInstanceHandles = {\n\n createReactRootID: function() {\n return getReactRootIDString(\n Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX)\n );\n },\n\n /**\n * Constructs a React ID by joining a root ID with a name.\n *\n * @param {string} rootID Root ID of a parent component.\n * @param {string} name A component's name (as flattened children).\n * @return {string} A React ID.\n * @internal\n */\n createReactID: function(rootID, name) {\n return rootID + SEPARATOR + name;\n },\n\n /**\n * Gets the DOM ID of the React component that is the root of the tree that\n * contains the React component with the supplied DOM ID.\n *\n * @param {string} id DOM ID of a React component.\n * @return {?string} DOM ID of the React component that is the root.\n * @internal\n */\n getReactRootIDFromNodeID: function(id) {\n var regexResult = /\\.r\\[[^\\]]+\\]/.exec(id);\n return regexResult && regexResult[0];\n },\n\n /**\n * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that\n * should would receive a `mouseEnter` or `mouseLeave` event.\n *\n * NOTE: Does not invoke the callback on the nearest common ancestor because\n * nothing \"entered\" or \"left\" that element.\n *\n * @param {string} leaveID ID being left.\n * @param {string} enterID ID being entered.\n * @param {function} cb Callback to invoke on each entered/left ID.\n * @param {*} upArg Argument to invoke the callback with on left IDs.\n * @param {*} downArg Argument to invoke the callback with on entered IDs.\n * @internal\n */\n traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) {\n var ancestorID = getFirstCommonAncestorID(leaveID, enterID);\n if (ancestorID !== leaveID) {\n traverseParentPath(leaveID, ancestorID, cb, upArg, false, true);\n }\n if (ancestorID !== enterID) {\n traverseParentPath(ancestorID, enterID, cb, downArg, true, false);\n }\n },\n\n /**\n * Simulates the traversal of a two-phase, capture/bubble event dispatch.\n *\n * NOTE: This traversal happens on IDs without touching the DOM.\n *\n * @param {string} targetID ID of the target node.\n * @param {function} cb Callback to invoke.\n * @param {*} arg Argument to invoke the callback with.\n * @internal\n */\n traverseTwoPhase: function(targetID, cb, arg) {\n if (targetID) {\n traverseParentPath('', targetID, cb, arg, true, false);\n traverseParentPath(targetID, '', cb, arg, false, true);\n }\n },\n\n /**\n * Exposed for unit testing.\n * @private\n */\n _getFirstCommonAncestorID: getFirstCommonAncestorID,\n\n /**\n * Exposed for unit testing.\n * @private\n */\n _getNextDescendantID: getNextDescendantID,\n\n isAncestorIDOf: isAncestorIDOf,\n\n SEPARATOR: SEPARATOR\n\n};\n\nmodule.exports = ReactInstanceHandles;\n\nrequire(\"./mock-modules\").register(\"ReactInstanceHandles\", module);\n", -"objMapKeyVal":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule objMapKeyVal\n */\n\n\"use strict\";\n\n/**\n * Behaves the same as `objMap` but invokes func with the key first, and value\n * second. Use `objMap` unless you need this special case.\n * Invokes func as:\n *\n * func(key, value, iteration)\n *\n * @param {?object} obj Object to map keys over\n * @param {!function} func Invoked for each key/val pair.\n * @param {?*} context\n * @return {?object} Result of mapping or null if obj is falsey\n */\nfunction objMapKeyVal(obj, func, context) {\n if (!obj) {\n return null;\n }\n var i = 0;\n var ret = {};\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n ret[key] = func.call(context, key, obj[key], i++);\n }\n }\n return ret;\n}\n\nmodule.exports = objMapKeyVal;\n\nrequire(\"./mock-modules\").register(\"objMapKeyVal\", module);\n", -"getTestDocument":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule getTestDocument\n */\n\n/**\n * We need to work around the fact that we have two different\n * test implementations: once that breaks if we clobber document\n * (open-source) and one that doesn't support createHTMLDocument()\n * (jst).\n */\nfunction getTestDocument() {\n if (document.implementation &&\n document.implementation.createHTMLDocument) {\n return document.implementation.createHTMLDocument('test doc');\n }\n return null;\n}\n\nmodule.exports = getTestDocument;\n\nrequire(\"./mock-modules\").register(\"getTestDocument\", module);\n", -"ReactStateSetters":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactStateSetters\n */\n\n\"use strict\";\n\nvar ReactStateSetters = {\n /**\n * Returns a function that calls the provided function, and uses the result\n * of that to set the component's state.\n *\n * @param {ReactCompositeComponent} component\n * @param {function} funcReturningState Returned callback uses this to\n * determine how to update state.\n * @return {function} callback that when invoked uses funcReturningState to\n * determined the object literal to setState.\n */\n createStateSetter: function(component, funcReturningState) {\n return function(a, b, c, d, e, f) {\n var partialState = funcReturningState.call(component, a, b, c, d, e, f);\n if (partialState) {\n component.setState(partialState);\n }\n };\n },\n\n /**\n * Returns a single-argument callback that can be used to update a single\n * key in the component's state.\n *\n * Note: this is memoized function, which makes it inexpensive to call.\n *\n * @param {ReactCompositeComponent} component\n * @param {string} key The key in the state that you should update.\n * @return {function} callback of 1 argument which calls setState() with\n * the provided keyName and callback argument.\n */\n createStateKeySetter: function(component, key) {\n // Memoize the setters.\n var cache = component.__keySetters || (component.__keySetters = {});\n return cache[key] || (cache[key] = createStateKeySetter(component, key));\n }\n};\n\nfunction createStateKeySetter(component, key) {\n // Partial state is allocated outside of the function closure so it can be\n // reused with every call, avoiding memory allocation when this function\n // is called.\n var partialState = {};\n return function stateKeySetter(value) {\n partialState[key] = value;\n component.setState(partialState);\n };\n}\n\nReactStateSetters.Mixin = {\n /**\n * Returns a function that calls the provided function, and uses the result\n * of that to set the component's state.\n *\n * For example, these statements are equivalent:\n *\n * this.setState({x: 1});\n * this.createStateSetter(function(xValue) {\n * return {x: xValue};\n * })(1);\n *\n * @param {function} funcReturningState Returned callback uses this to\n * determine how to update state.\n * @return {function} callback that when invoked uses funcReturningState to\n * determined the object literal to setState.\n */\n createStateSetter: function(funcReturningState) {\n return ReactStateSetters.createStateSetter(this, funcReturningState);\n },\n\n /**\n * Returns a single-argument callback that can be used to update a single\n * key in the component's state.\n *\n * For example, these statements are equivalent:\n *\n * this.setState({x: 1});\n * this.createStateKeySetter('x')(1);\n *\n * Note: this is memoized function, which makes it inexpensive to call.\n *\n * @param {string} key The key in the state that you should update.\n * @return {function} callback of 1 argument which calls setState() with\n * the provided keyName and callback argument.\n */\n createStateKeySetter: function(key) {\n return ReactStateSetters.createStateKeySetter(this, key);\n }\n};\n\nmodule.exports = ReactStateSetters;\n\nrequire(\"./mock-modules\").register(\"ReactStateSetters\", module);\n", -"ReactUpdates":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule ReactUpdates\n */\n\n\"use strict\";\n\nvar invariant = require(\"./invariant\");\n\nvar dirtyComponents = [];\n\nvar batchingStrategy = null;\n\nfunction ensureBatchingStrategy() {\n invariant(batchingStrategy, 'ReactUpdates: must inject a batching strategy');\n}\n\nfunction batchedUpdates(callback, param) {\n ensureBatchingStrategy();\n batchingStrategy.batchedUpdates(callback, param);\n}\n\n/**\n * Array comparator for ReactComponents by owner depth\n *\n * @param {ReactComponent} c1 first component you're comparing\n * @param {ReactComponent} c2 second component you're comparing\n * @return {number} Return value usable by Array.prototype.sort().\n */\nfunction mountDepthComparator(c1, c2) {\n return c1._mountDepth - c2._mountDepth;\n}\n\nfunction runBatchedUpdates() {\n // Since reconciling a component higher in the owner hierarchy usually (not\n // always -- see shouldComponentUpdate()) will reconcile children, reconcile\n // them before their children by sorting the array.\n\n dirtyComponents.sort(mountDepthComparator);\n\n for (var i = 0; i < dirtyComponents.length; i++) {\n // If a component is unmounted before pending changes apply, ignore them\n // TODO: Queue unmounts in the same list to avoid this happening at all\n var component = dirtyComponents[i];\n if (component.isMounted()) {\n // If performUpdateIfNecessary happens to enqueue any new updates, we\n // shouldn't execute the callbacks until the next render happens, so\n // stash the callbacks first\n var callbacks = component._pendingCallbacks;\n component._pendingCallbacks = null;\n component.performUpdateIfNecessary();\n if (callbacks) {\n for (var j = 0; j < callbacks.length; j++) {\n callbacks[j].call(component);\n }\n }\n }\n }\n}\n\nfunction clearDirtyComponents() {\n dirtyComponents.length = 0;\n}\n\nfunction flushBatchedUpdates() {\n // Run these in separate functions so the JIT can optimize\n try {\n runBatchedUpdates();\n } catch (e) {\n // IE 8 requires catch to use finally.\n throw e;\n } finally {\n clearDirtyComponents();\n }\n}\n\n/**\n * Mark a component as needing a rerender, adding an optional callback to a\n * list of functions which will be executed once the rerender occurs.\n */\nfunction enqueueUpdate(component, callback) {\n invariant(\n !callback || typeof callback === \"function\",\n 'enqueueUpdate(...): You called `setProps`, `replaceProps`, ' +\n '`setState`, `replaceState`, or `forceUpdate` with a callback that ' +\n 'isn\\'t callable.'\n );\n ensureBatchingStrategy();\n\n if (!batchingStrategy.isBatchingUpdates) {\n component.performUpdateIfNecessary();\n callback && callback();\n return;\n }\n\n dirtyComponents.push(component);\n\n if (callback) {\n if (component._pendingCallbacks) {\n component._pendingCallbacks.push(callback);\n } else {\n component._pendingCallbacks = [callback];\n }\n }\n}\n\nvar ReactUpdatesInjection = {\n injectBatchingStrategy: function(_batchingStrategy) {\n invariant(\n _batchingStrategy,\n 'ReactUpdates: must provide a batching strategy'\n );\n invariant(\n typeof _batchingStrategy.batchedUpdates === 'function',\n 'ReactUpdates: must provide a batchedUpdates() function'\n );\n invariant(\n typeof _batchingStrategy.isBatchingUpdates === 'boolean',\n 'ReactUpdates: must provide an isBatchingUpdates boolean attribute'\n );\n batchingStrategy = _batchingStrategy;\n }\n};\n\nvar ReactUpdates = {\n batchedUpdates: batchedUpdates,\n enqueueUpdate: enqueueUpdate,\n flushBatchedUpdates: flushBatchedUpdates,\n injection: ReactUpdatesInjection\n};\n\nmodule.exports = ReactUpdates;\n\nrequire(\"./mock-modules\").register(\"ReactUpdates\", module);\n", -"CSSPropertyOperations":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule CSSPropertyOperations\n * @typechecks static-only\n */\n\n\"use strict\";\n\nvar CSSProperty = require(\"./CSSProperty\");\n\nvar dangerousStyleValue = require(\"./dangerousStyleValue\");\nvar escapeTextForBrowser = require(\"./escapeTextForBrowser\");\nvar hyphenate = require(\"./hyphenate\");\nvar memoizeStringOnly = require(\"./memoizeStringOnly\");\n\nvar processStyleName = memoizeStringOnly(function(styleName) {\n return escapeTextForBrowser(hyphenate(styleName));\n});\n\n/**\n * Operations for dealing with CSS properties.\n */\nvar CSSPropertyOperations = {\n\n /**\n * Serializes a mapping of style properties for use as inline styles:\n *\n * > createMarkupForStyles({width: '200px', height: 0})\n * \"width:200px;height:0;\"\n *\n * Undefined values are ignored so that declarative programming is easier.\n *\n * @param {object} styles\n * @return {?string}\n */\n createMarkupForStyles: function(styles) {\n var serialized = '';\n for (var styleName in styles) {\n if (!styles.hasOwnProperty(styleName)) {\n continue;\n }\n var styleValue = styles[styleName];\n if (styleValue != null) {\n serialized += processStyleName(styleName) + ':';\n serialized += dangerousStyleValue(styleName, styleValue) + ';';\n }\n }\n return serialized || null;\n },\n\n /**\n * Sets the value for multiple styles on a node. If a value is specified as\n * '' (empty string), the corresponding style property will be unset.\n *\n * @param {DOMElement} node\n * @param {object} styles\n */\n setValueForStyles: function(node, styles) {\n var style = node.style;\n for (var styleName in styles) {\n if (!styles.hasOwnProperty(styleName)) {\n continue;\n }\n var styleValue = dangerousStyleValue(styleName, styles[styleName]);\n if (styleValue) {\n style[styleName] = styleValue;\n } else {\n var expansion = CSSProperty.shorthandPropertyExpansions[styleName];\n if (expansion) {\n // Shorthand property that IE8 won't like unsetting, so unset each\n // component to placate it\n for (var individualStyleName in expansion) {\n style[individualStyleName] = '';\n }\n } else {\n style[styleName] = '';\n }\n }\n }\n }\n\n};\n\nmodule.exports = CSSPropertyOperations;\n\nrequire(\"./mock-modules\").register(\"CSSPropertyOperations\", module);\n", -"DOMProperty":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule DOMProperty\n * @typechecks static-only\n */\n\n/*jslint bitwise: true */\n\n\"use strict\";\n\nvar invariant = require(\"./invariant\");\n\nvar DOMPropertyInjection = {\n /**\n * Mapping from normalized, camelcased property names to a configuration that\n * specifies how the associated DOM property should be accessed or rendered.\n */\n MUST_USE_ATTRIBUTE: 0x1,\n MUST_USE_PROPERTY: 0x2,\n HAS_BOOLEAN_VALUE: 0x4,\n HAS_SIDE_EFFECTS: 0x8,\n\n /**\n * Inject some specialized knowledge about the DOM. This takes a config object\n * with the following properties:\n *\n * isCustomAttribute: function that given an attribute name will return true\n * if it can be inserted into the DOM verbatim. Useful for data-* or aria-*\n * attributes where it's impossible to enumerate all of the possible\n * attribute names,\n *\n * Properties: object mapping DOM property name to one of the\n * DOMPropertyInjection constants or null. If your attribute isn't in here,\n * it won't get written to the DOM.\n *\n * DOMAttributeNames: object mapping React attribute name to the DOM\n * attribute name. Attribute names not specified use the **lowercase**\n * normalized name.\n *\n * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.\n * Property names not specified use the normalized name.\n *\n * DOMMutationMethods: Properties that require special mutation methods. If\n * `value` is undefined, the mutation method should unset the property.\n *\n * @param {object} domPropertyConfig the config as described above.\n */\n injectDOMPropertyConfig: function(domPropertyConfig) {\n var Properties = domPropertyConfig.Properties || {};\n var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};\n var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};\n var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};\n\n if (domPropertyConfig.isCustomAttribute) {\n DOMProperty._isCustomAttributeFunctions.push(\n domPropertyConfig.isCustomAttribute\n );\n }\n\n for (var propName in Properties) {\n invariant(\n !DOMProperty.isStandardName[propName],\n 'injectDOMPropertyConfig(...): You\\'re trying to inject DOM property ' +\n '\\'%s\\' which has already been injected. You may be accidentally ' +\n 'injecting the same DOM property config twice, or you may be ' +\n 'injecting two configs that have conflicting property names.',\n propName\n );\n\n DOMProperty.isStandardName[propName] = true;\n\n var lowerCased = propName.toLowerCase();\n DOMProperty.getPossibleStandardName[lowerCased] = propName;\n\n var attributeName = DOMAttributeNames[propName];\n if (attributeName) {\n DOMProperty.getPossibleStandardName[attributeName] = propName;\n }\n\n DOMProperty.getAttributeName[propName] = attributeName || lowerCased;\n\n DOMProperty.getPropertyName[propName] =\n DOMPropertyNames[propName] || propName;\n\n var mutationMethod = DOMMutationMethods[propName];\n if (mutationMethod) {\n DOMProperty.getMutationMethod[propName] = mutationMethod;\n }\n\n var propConfig = Properties[propName];\n DOMProperty.mustUseAttribute[propName] =\n propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE;\n DOMProperty.mustUseProperty[propName] =\n propConfig & DOMPropertyInjection.MUST_USE_PROPERTY;\n DOMProperty.hasBooleanValue[propName] =\n propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE;\n DOMProperty.hasSideEffects[propName] =\n propConfig & DOMPropertyInjection.HAS_SIDE_EFFECTS;\n\n invariant(\n !DOMProperty.mustUseAttribute[propName] ||\n !DOMProperty.mustUseProperty[propName],\n 'DOMProperty: Cannot use require using both attribute and property: %s',\n propName\n );\n invariant(\n DOMProperty.mustUseProperty[propName] ||\n !DOMProperty.hasSideEffects[propName],\n 'DOMProperty: Properties that have side effects must use property: %s',\n propName\n );\n }\n }\n};\nvar defaultValueCache = {};\n\n/**\n * DOMProperty exports lookup objects that can be used like functions:\n *\n * > DOMProperty.isValid['id']\n * true\n * > DOMProperty.isValid['foobar']\n * undefined\n *\n * Although this may be confusing, it performs better in general.\n *\n * @see http://jsperf.com/key-exists\n * @see http://jsperf.com/key-missing\n */\nvar DOMProperty = {\n\n /**\n * Checks whether a property name is a standard property.\n * @type {Object}\n */\n isStandardName: {},\n\n /**\n * Mapping from lowercase property names to the properly cased version, used\n * to warn in the case of missing properties.\n * @type {Object}\n */\n getPossibleStandardName: {},\n\n /**\n * Mapping from normalized names to attribute names that differ. Attribute\n * names are used when rendering markup or with `*Attribute()`.\n * @type {Object}\n */\n getAttributeName: {},\n\n /**\n * Mapping from normalized names to properties on DOM node instances.\n * (This includes properties that mutate due to external factors.)\n * @type {Object}\n */\n getPropertyName: {},\n\n /**\n * Mapping from normalized names to mutation methods. This will only exist if\n * mutation cannot be set simply by the property or `setAttribute()`.\n * @type {Object}\n */\n getMutationMethod: {},\n\n /**\n * Whether the property must be accessed and mutated as an object property.\n * @type {Object}\n */\n mustUseAttribute: {},\n\n /**\n * Whether the property must be accessed and mutated using `*Attribute()`.\n * (This includes anything that fails ` in `.)\n * @type {Object}\n */\n mustUseProperty: {},\n\n /**\n * Whether the property should be removed when set to a falsey value.\n * @type {Object}\n */\n hasBooleanValue: {},\n\n /**\n * Whether or not setting a value causes side effects such as triggering\n * resources to be loaded or text selection changes. We must ensure that\n * the value is only set if it has changed.\n * @type {Object}\n */\n hasSideEffects: {},\n\n /**\n * All of the isCustomAttribute() functions that have been injected.\n */\n _isCustomAttributeFunctions: [],\n\n /**\n * Checks whether a property name is a custom attribute.\n * @method\n */\n isCustomAttribute: function(attributeName) {\n return DOMProperty._isCustomAttributeFunctions.some(\n function(isCustomAttributeFn) {\n return isCustomAttributeFn.call(null, attributeName);\n }\n );\n },\n\n /**\n * Returns the default property value for a DOM property (i.e., not an\n * attribute). Most default values are '' or false, but not all. Worse yet,\n * some (in particular, `type`) vary depending on the type of element.\n *\n * TODO: Is it better to grab all the possible properties when creating an\n * element to avoid having to create the same element twice?\n */\n getDefaultValueForProperty: function(nodeName, prop) {\n var nodeDefaults = defaultValueCache[nodeName];\n var testElement;\n if (!nodeDefaults) {\n defaultValueCache[nodeName] = nodeDefaults = {};\n }\n if (!(prop in nodeDefaults)) {\n testElement = document.createElement(nodeName);\n nodeDefaults[prop] = testElement[prop];\n }\n return nodeDefaults[prop];\n },\n\n injection: DOMPropertyInjection\n};\n\nmodule.exports = DOMProperty;\n\nrequire(\"./mock-modules\").register(\"DOMProperty\", module);\n", -"Danger":"/**\n * Copyright 2013 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule Danger\n * @typechecks static-only\n */\n\n/*jslint evil: true, sub: true */\n\n\"use strict\";\n\nvar ExecutionEnvironment = require(\"./ExecutionEnvironment\");\n\nvar createNodesFromMarkup = require(\"./createNodesFromMarkup\");\nvar emptyFunction = require(\"./emptyFunction\");\nvar getMarkupWrap = require(\"./getMarkupWrap\");\nvar invariant = require(\"./invariant\");\nvar mutateHTMLNodeWithMarkup = require(\"./mutateHTMLNodeWithMarkup\");\n\nvar OPEN_TAG_NAME_EXP = /^(<[^ \\/>]+)/;\nvar RESULT_INDEX_ATTR = 'data-danger-index';\n\n/**\n * Extracts the `nodeName` from a string of markup.\n *\n * NOTE: Extracting the `nodeName` does not require a regular expression match\n * because we make assumptions about React-generated markup (i.e. there are no\n * spaces surrounding the opening tag and there is at least one attribute).\n *\n * @param {string} markup String of markup.\n * @return {string} Node name of the supplied markup.\n * @see http://jsperf.com/extract-nodename\n */\nfunction getNodeName(markup) {\n return markup.substring(1, markup.indexOf(' '));\n}\n\nvar Danger = {\n\n /**\n * Renders markup into an array of nodes. The markup is expected to render\n * into a list of root nodes. Also, the length of `resultList` and\n * `markupList` should be the same.\n *\n * @param {array} markupList List of markup strings to render.\n * @return {array} List of rendered nodes.\n * @internal\n */\n dangerouslyRenderMarkup: function(markupList) {\n invariant(\n ExecutionEnvironment.canUseDOM,\n 'dangerouslyRenderMarkup(...): Cannot render markup in a Worker ' +\n 'thread. This is likely a bug in the framework. Please report ' +\n 'immediately.'\n );\n var nodeName;\n var markupByNodeName = {};\n // Group markup by `nodeName` if a wrap is necessary, else by '*'.\n for (var i = 0; i < markupList.length; i++) {\n invariant(\n markupList[i],\n 'dangerouslyRenderMarkup(...): Missing markup.'\n );\n nodeName = getNodeName(markupList[i]);\n nodeName = getMarkupWrap(nodeName) ? nodeName : '*';\n markupByNodeName[nodeName] = markupByNodeName[nodeName] || [];\n markupByNodeName[nodeName][i] = markupList[i];\n }\n var resultList = [];\n var resultListAssignmentCount = 0;\n for (nodeName in markupByNodeName) {\n if (!markupByNodeName.hasOwnProperty(nodeName)) {\n continue;\n }\n var markupListByNodeName = markupByNodeName[nodeName];\n\n // This for-in loop skips the holes of the sparse array. The order of\n // iteration should follow the order of assignment, which happens to match\n // numerical index order, but we don't rely on that.\n for (var resultIndex in markupListByNodeName) {\n if (markupListByNodeName.hasOwnProperty(resultIndex)) {\n var markup = markupListByNodeName[resultIndex];\n\n // Push the requested markup with an additional RESULT_INDEX_ATTR\n // attribute. If the markup does not start with a < character, it\n // will be discarded below (with an appropriate console.error).\n markupListByNodeName[resultIndex] = markup.replace(\n OPEN_TAG_NAME_EXP,\n // This index will be parsed back out below.\n '$1 ' + RESULT_INDEX_ATTR + '=\"' + resultIndex + '\" '\n );\n }\n }\n\n // Render each group of markup with similar wrapping `nodeName`.\n var renderNodes = createNodesFromMarkup(\n markupListByNodeName.join(''),\n emptyFunction // Do nothing special with From b922d8d8a6ee5a6db47401086bf109f6ac056036 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 16:43:20 -0500 Subject: [PATCH 41/47] move browser test libs to lib folder --- test/{ => lib}/jasmine-execute.js | 0 test/{ => lib}/reportTestResults.browser.js | 0 test/{ => lib}/testImageURL.browser.js | 0 test/sauce-harness.html | 6 +++--- 4 files changed, 3 insertions(+), 3 deletions(-) rename test/{ => lib}/jasmine-execute.js (100%) rename test/{ => lib}/reportTestResults.browser.js (100%) rename test/{ => lib}/testImageURL.browser.js (100%) diff --git a/test/jasmine-execute.js b/test/lib/jasmine-execute.js similarity index 100% rename from test/jasmine-execute.js rename to test/lib/jasmine-execute.js diff --git a/test/reportTestResults.browser.js b/test/lib/reportTestResults.browser.js similarity index 100% rename from test/reportTestResults.browser.js rename to test/lib/reportTestResults.browser.js diff --git a/test/testImageURL.browser.js b/test/lib/testImageURL.browser.js similarity index 100% rename from test/testImageURL.browser.js rename to test/lib/testImageURL.browser.js diff --git a/test/sauce-harness.html b/test/sauce-harness.html index af3f51aa44758..de8c0aaf9a36f 100644 --- a/test/sauce-harness.html +++ b/test/sauce-harness.html @@ -11,13 +11,13 @@ '../node_modules/jasmine-tapreporter/src/tapreporter.js', '../vendor/jasmine-jsreporter/jasmine-jsreporter.js', - 'testImageURL.browser.js', - 'reportTestResults.browser.js', + 'lib/testImageURL.browser.js', + 'lib/reportTestResults.browser.js', '../build/react.js', '../build/react-test.js', 'the-files-to-test.generated.js', - 'jasmine-execute.js' + 'lib/jasmine-execute.js' ]; if (typeof Function.prototype.bind == 'undefined') { From c9401be38eb817c16f4e3adf8a1cefd4d9a79279 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 16:44:03 -0500 Subject: [PATCH 42/47] replace phantom-harness runner with webdriver --- Gruntfile.js | 8 +-- grunt/config/phantom.js | 11 ---- grunt/tasks/phantom.js | 68 ------------------- test/index.html | 23 ------- test/phantom-harness.js | 141 ---------------------------------------- 5 files changed, 2 insertions(+), 249 deletions(-) delete mode 100644 grunt/config/phantom.js delete mode 100644 grunt/tasks/phantom.js delete mode 100644 test/index.html delete mode 100644 test/phantom-harness.js diff --git a/Gruntfile.js b/Gruntfile.js index 81f09ab87cbac..7357e051aa7df 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -4,7 +4,6 @@ var exec = require('child_process').exec; var jsxTask = require('./grunt/tasks/jsx'); var browserifyTask = require('./grunt/tasks/browserify'); var populistTask = require('./grunt/tasks/populist'); -var phantomTask = require('./grunt/tasks/phantom'); var webdriverPhantomJSTask = require('./grunt/tasks/webdriver-phantomjs'); var webdriverJasmineTasks = require('./grunt/tasks/webdriver-jasmine'); var npmTask = require('./grunt/tasks/npm'); @@ -18,7 +17,6 @@ module.exports = function(grunt) { jsx: require('./grunt/config/jsx/jsx'), browserify: require('./grunt/config/browserify'), populist: require('./grunt/config/populist'), - phantom: require('./grunt/config/phantom'), connect: require('./grunt/config/server')(grunt), "webdriver-jasmine": require('./grunt/config/webdriver-jasmine.js'), npm: require('./grunt/config/npm'), @@ -44,8 +42,6 @@ module.exports = function(grunt) { grunt.registerMultiTask('populist', populistTask); - grunt.registerMultiTask('phantom', phantomTask); - grunt.registerMultiTask('webdriver-jasmine', webdriverJasmineTasks); grunt.registerMultiTask('npm', npmTask); @@ -79,12 +75,12 @@ module.exports = function(grunt) { grunt.registerTask('webdriver-phantomjs', webdriverPhantomJSTask); - grunt.registerTask('test:webdriver', [ + grunt.registerTask('test:webdriver:phantomjs', [ 'connect', 'webdriver-phantomjs', 'webdriver-jasmine:local' ]); - grunt.registerTask('test', ['build:test', 'build:basic', 'phantom:run']); + grunt.registerTask('test', ['build:test', 'build:basic', 'test:webdriver:phantomjs']); grunt.registerTask('npm:test', ['build', 'npm:pack']); // Optimized build task that does all of our builds. The subtasks will be run diff --git a/grunt/config/phantom.js b/grunt/config/phantom.js deleted file mode 100644 index 36cbc0f3ded11..0000000000000 --- a/grunt/config/phantom.js +++ /dev/null @@ -1,11 +0,0 @@ -var grunt = require("grunt"); - -exports.run = { - port: 8080, - harness: "test/phantom-harness.js", - // Run `grunt test --debug` to enable in-browser testing. - debug: !!grunt.option("debug"), - tests: [ - "**/__tests__/*-test.js" - ] -}; diff --git a/grunt/tasks/phantom.js b/grunt/tasks/phantom.js deleted file mode 100644 index d5c66eb2589a8..0000000000000 --- a/grunt/tasks/phantom.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict'; - -var assert = require("assert"); -var grunt = require("grunt"); -var spawn = grunt.util.spawn; -var semver = require("semver"); -var MIN_VERSION = "1.9.0"; -var phantomjs = require("phantomjs").path; - -function checkVersion(error, result, code) { - if (error) { - throw error; - } - assert.strictEqual(code, 0); - - var version = result.stdout; - - assert.ok( - semver.valid(version), - "Invalid PhantomJS version: " + version - ); - - assert.ok( - semver.gte(version, MIN_VERSION), - "PhantomJS v" + version + " too old; need to install " + - "v" + MIN_VERSION + " or higher." - ); -} - -function run(config, done) { - var args = [ - config.harness, - "--port", config.port - ]; - - if (config.debug) { - args.push("--debug"); - } - - args.push("--tests"); - grunt.file.expand({ - nonull: true, - cwd: "src" - }, config.tests || []).forEach(function(file) { - args.push(file.replace(/\.js$/i, "")); - }); - - var child = spawn({ - cmd: phantomjs, - args: args - }, done); - - child.stdout.pipe(process.stdout); - child.stderr.pipe(process.stderr); -} - -module.exports = function() { - var config = this.data; - var done = this.async(); - - spawn({ - cmd: phantomjs, - args: ["--version"] - }, function(error, result, code) { - checkVersion(error, result, code); - run(config, done); - }); -}; diff --git a/test/index.html b/test/index.html deleted file mode 100644 index 97fbfb0479764..0000000000000 --- a/test/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - diff --git a/test/phantom-harness.js b/test/phantom-harness.js deleted file mode 100644 index 66197fa52eee6..0000000000000 --- a/test/phantom-harness.js +++ /dev/null @@ -1,141 +0,0 @@ -var slice = Array.prototype.slice; -var argv = slice.call(require("system").args); - -// Hard to believe PhantomJS has no equivalent of Node's "path" module. -var fs = require("fs"); -var splat = [fs.workingDirectory, argv[0]] - .join(fs.separator) - .split(fs.separator); - -var harness = splat.pop(); -if (harness !== "phantom-harness.js") { - console.error("wrong harness: " + harness); - phantom.exit(-1); -} - -var cwd = splat.join(fs.separator); -fs.changeWorkingDirectory(cwd); - -// Hard to believe PhantomJS has no option parsing module. -var port = 8080; -var debug = false; -var tests = []; -var rest = []; -while (argv.length > 0) { - var arg = argv.pop(); - if (arg === "--port") { - port = +rest.pop(); - } else if (arg === "--debug") { - debug = true; - } else if (arg === "--tests") { - while (rest.length > 0) - tests.push(rest.pop()); - } - rest.push(arg); -} - -// Dynamically enable the individual tests. -var indexHtml = fs.read("index.html").replace( - /^(\s*)ENABLE_TESTS_HERE/m, - function(placeholder, leadingSpace) { - return leadingSpace + tests.map(function(testID) { - return "harness.enableTest(" + JSON.stringify(testID) + ");"; - }).join("\n" + leadingSpace); - } -); - -var server = require("webserver").create(); -server.listen(port, function(req, res) { - var file = req.url.replace(/^\/+/, ""); - file = file.split('?')[0]; - file = file.replace('build/', ''); - file = file.replace('src/test/', ''); - - var content; - - switch (file) { - case "jasmine.js": - case "react.js": - case "react-test.js": - file = "../build/" + file; - break; - - case "phantomjs-shims.js": - case "worker.js": - file = "../src/test/" + file; - break; - - case "jasmine.css": - file = "../vendor/jasmine/" + file; - break; - - case "": - default: - file = "index.html"; - content = indexHtml; // Prevents calling fs.read again. - break; - } - - if (/\.css$/i.test(file)) { - res.setHeader("Content-Type", "text/css"); - } else if (/\.js/i.test(file)) { - res.setHeader("Content-Type", "text/javascript"); - } else { - res.setHeader("Content-Type", "text/html"); - } - - res.statusCode = 200; - res.write(content || fs.read(file)); - res.close(); -}); - -var url = "http://localhost:" + port; -var green = "\033[32m"; -var cyan = "\033[36m"; -var reset = "\033[0m"; - -if (debug) { - console.log(green); - console.log("PhantomJS received the " + cyan + "--debug" + green + " option."); - console.log("Load " + cyan + url + green + " in your browser to execute " + - "the test suite."); - console.log("Type " + cyan + "control-C" + green + " to terminate the " + - "PhantomJS process."); - console.log(reset); - - // Leave PhantomJS running until killed with control-C... - -} else { - var page = require("webpage").create(); - var timeoutSecs = 60; - - page.onCallback = function(data) { - switch (data.type) { - case "console": - console[data.method].apply(console, data.args); - break; - - case "exit": - // PhantomJS crashes sometimes unless we call phantom.exit in its own - // event loop tick. - setTimeout(function() { - phantom.exit(data.code); - }, 10); - break; - } - }; - - page.open(url, function(status) { - if (status !== "success") { - console.error("failed to open " + url); - phantom.exit(-1); - } - - setTimeout(function() { - console.error( - "PhantomJS tests timed out after " + - timeoutSecs + " seconds."); - phantom.exit(-1); - }, timeoutSecs * 1e3); - }); -} From 19a5505c5085a7e8eb056d0d960dab6824c6d80d Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 17:00:25 -0500 Subject: [PATCH 43/47] making phantomjs version less specific --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6b982e35e3478..7cf8992686cf8 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "grunt-contrib-copy": "~0.4.1", "grunt-contrib-jshint": "~0.6.0", "optimist": "~0.6.0", - "phantomjs": "~1.9.1-4", + "phantomjs": "~1.9", "recast": "~0.4.16", "semver": "~2.1.0", "uglify-js": "~2.4.0", From 0a120bb5d0200623e9629872a8dd3f3b4ad436f2 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 17:12:20 -0500 Subject: [PATCH 44/47] cleanup loadNpmTasks --- Gruntfile.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 7357e051aa7df..c46d9a6ba4475 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -27,9 +27,12 @@ module.exports = function(grunt) { grunt.config.set('compress', require('./grunt/config/compress')); - for (var key in grunt.file.readJSON("package.json").devDependencies) { - if (key !== "grunt" && key.indexOf("grunt") === 0) grunt.loadNpmTasks(key); - } + Object.keys(grunt.file.readJSON('package.json').devDependencies) + .filter(function(npmTaskName){ return npmTaskName.indexOf('grunt-') === 0;}) + .forEach(function(npmTaskName){ + grunt.loadNpmTasks(npmTaskName); + }) + ; // Alias 'jshint' to 'lint' to better match the workflow we know grunt.registerTask('lint', ['jshint']); From 5fa707534aea4727e28295339442dd1e811f4457 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 17:15:38 -0500 Subject: [PATCH 45/47] ignore generated file Running the tests shouldn't make git status dirty. --- .gitignore | 1 + test/the-files-to-test.generated.js | 62 ----------------------------- 2 files changed, 1 insertion(+), 62 deletions(-) delete mode 100644 test/the-files-to-test.generated.js diff --git a/.gitignore b/.gitignore index 6cd44a5569183..e69b58bd049c0 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ docs/js/live_editor.js docs/js/examples docs/downloads examples/shared/*.js +test/the-files-to-test.generated.js diff --git a/test/the-files-to-test.generated.js b/test/the-files-to-test.generated.js deleted file mode 100644 index 44aaa1663cc45..0000000000000 --- a/test/the-files-to-test.generated.js +++ /dev/null @@ -1,62 +0,0 @@ -// Generated by "grunt/tasks/populist.js" at "2013-10-28T21:07:06.694Z" - -harness.enableTest("addons/link/__tests__/LinkedStateMixin-test"); -harness.enableTest("addons/transitions/__tests__/ReactTransitionGroup-test"); -harness.enableTest("addons/transitions/__tests__/ReactTransitionKeySet-test"); -harness.enableTest("addons/transitions/__tests__/ReactTransitionableChild-test"); -harness.enableTest("core/__tests__/ReactBind-test"); -harness.enableTest("core/__tests__/ReactComponent-test"); -harness.enableTest("core/__tests__/ReactComponentLifeCycle-test"); -harness.enableTest("core/__tests__/ReactCompositeComponent-test"); -harness.enableTest("core/__tests__/ReactCompositeComponentDOMMinimalism-test"); -harness.enableTest("core/__tests__/ReactCompositeComponentMixin-test"); -harness.enableTest("core/__tests__/ReactCompositeComponentSpec-test"); -harness.enableTest("core/__tests__/ReactCompositeComponentState-test"); -harness.enableTest("core/__tests__/ReactDOM-test"); -harness.enableTest("core/__tests__/ReactDOMComponent-test"); -harness.enableTest("core/__tests__/ReactDOMIDOperations-test"); -harness.enableTest("core/__tests__/ReactEventEmitter-test"); -harness.enableTest("core/__tests__/ReactIdentity-test"); -harness.enableTest("core/__tests__/ReactInstanceHandles-test"); -harness.enableTest("core/__tests__/ReactMount-test"); -harness.enableTest("core/__tests__/ReactMountDestruction-test"); -harness.enableTest("core/__tests__/ReactMultiChild-test"); -harness.enableTest("core/__tests__/ReactMultiChildReconcile-test"); -harness.enableTest("core/__tests__/ReactMultiChildText-test"); -harness.enableTest("core/__tests__/ReactPropTransferer-test"); -harness.enableTest("core/__tests__/ReactPropTypes-test"); -harness.enableTest("core/__tests__/ReactRenderDocument-test"); -harness.enableTest("core/__tests__/ReactStateSetters-test"); -harness.enableTest("core/__tests__/ReactUpdates-test"); -harness.enableTest("core/__tests__/refs-destruction-test"); -harness.enableTest("core/__tests__/refs-test"); -harness.enableTest("dom/__tests__/CSSPropertyOperations-test"); -harness.enableTest("dom/__tests__/DOMPropertyOperations-test"); -harness.enableTest("dom/__tests__/Danger-test"); -harness.enableTest("dom/__tests__/getNodeForCharacterOffset-test"); -harness.enableTest("dom/__tests__/mutateHTMLNodeWithMarkup-test"); -harness.enableTest("dom/components/__tests__/ReactDOMButton-test"); -harness.enableTest("dom/components/__tests__/ReactDOMInput-test"); -harness.enableTest("dom/components/__tests__/ReactDOMSelect-test"); -harness.enableTest("dom/components/__tests__/ReactDOMTextarea-test"); -harness.enableTest("environment/__tests__/ReactServerRendering-test"); -harness.enableTest("environment/__tests__/ReactWebWorker-test"); -harness.enableTest("event/__tests__/EventPluginRegistry-test"); -harness.enableTest("event/synthetic/__tests__/SyntheticEvent-test"); -harness.enableTest("event/synthetic/__tests__/SyntheticWheelEvent-test"); -harness.enableTest("eventPlugins/__tests__/AnalyticsEventPlugin-test"); -harness.enableTest("eventPlugins/__tests__/ResponderEventPlugin-test"); -harness.enableTest("utils/__tests__/ImmutableObject-test"); -harness.enableTest("utils/__tests__/OrderedMap-test"); -harness.enableTest("utils/__tests__/ReactChildren-test"); -harness.enableTest("utils/__tests__/Transaction-test"); -harness.enableTest("utils/__tests__/escapeTextForBrowser-test"); -harness.enableTest("utils/__tests__/joinClasses-test"); -harness.enableTest("utils/__tests__/keyMirror-test"); -harness.enableTest("utils/__tests__/memoizeStringOnly-test"); -harness.enableTest("utils/__tests__/mergeFuncs-test"); -harness.enableTest("utils/__tests__/onlyChild-test"); -harness.enableTest("utils/__tests__/sliceChildren-test"); -harness.enableTest("utils/__tests__/traverseAllChildren-test"); -harness.enableTest("vendor/error/__tests__/erx-test"); -harness.enableTest("vendor/error/__tests__/ex-test"); From f289e9862a1819c3a1c6dcdec5b654b3ee75ea04 Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Wed, 6 Nov 2013 17:29:00 -0500 Subject: [PATCH 46/47] rename sauce-harness to index --- grunt/config/webdriver-jasmine.js | 2 +- test/{sauce-harness.html => index.html} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test/{sauce-harness.html => index.html} (100%) diff --git a/grunt/config/webdriver-jasmine.js b/grunt/config/webdriver-jasmine.js index 747b7214eb54c..1b3a58b4a3876 100644 --- a/grunt/config/webdriver-jasmine.js +++ b/grunt/config/webdriver-jasmine.js @@ -5,7 +5,7 @@ exports.local = { webdriver: { remote: { protocol: 'http:', hostname: '127.0.0.1', port: 9515, path: '/' } }, - url: "http://127.0.0.1:9999/test/sauce-harness.html", + url: "http://127.0.0.1:9999/test/index.html", onComplete: function(report){ var browser = this; if (!report.passed){ diff --git a/test/sauce-harness.html b/test/index.html similarity index 100% rename from test/sauce-harness.html rename to test/index.html From 241d57aa9eb2d74bb400bd9e5339fe0a6b58ccff Mon Sep 17 00:00:00 2001 From: Thomas Aylott Date: Thu, 7 Nov 2013 13:12:31 -0500 Subject: [PATCH 47/47] allow directory browsing --- grunt/config/server.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grunt/config/server.js b/grunt/config/server.js index d73e724266717..cfa4506dcf7e8 100644 --- a/grunt/config/server.js +++ b/grunt/config/server.js @@ -37,7 +37,8 @@ module.exports = function(grunt){ connect.bodyParser(), testResultLoggerMiddleware, - connect.static(options.base) + connect.static(options.base), + connect.directory(options.base) ]; }, }