summaryrefslogtreecommitdiff
path: root/frontend/delta/js/React/react-0.5.0-alpha.js
Unidiff
Diffstat (limited to 'frontend/delta/js/React/react-0.5.0-alpha.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/React/react-0.5.0-alpha.js13239
1 files changed, 13239 insertions, 0 deletions
diff --git a/frontend/delta/js/React/react-0.5.0-alpha.js b/frontend/delta/js/React/react-0.5.0-alpha.js
new file mode 100644
index 0000000..375b430
--- a/dev/null
+++ b/frontend/delta/js/React/react-0.5.0-alpha.js
@@ -0,0 +1,13239 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24/**
25 * React v0.5.0-alpha
26 */
27(function(e){if("function"==typeof bootstrap)bootstrap("react",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeReact=e}else"undefined"!=typeof window?window.React=e():global.React=e()})(function(){var define,ses,bootstrap,module,exports;
28return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
29/**
30 * Copyright 2013 Facebook, Inc.
31 *
32 * Licensed under the Apache License, Version 2.0 (the "License");
33 * you may not use this file except in compliance with the License.
34 * You may obtain a copy of the License at
35 *
36 * http://www.apache.org/licenses/LICENSE-2.0
37 *
38 * Unless required by applicable law or agreed to in writing, software
39 * distributed under the License is distributed on an "AS IS" BASIS,
40 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41 * See the License for the specific language governing permissions and
42 * limitations under the License.
43 *
44 * @providesModule $
45 * @typechecks
46 */
47
48var ge = require("./ge");
49var ex = require("./ex");
50
51/**
52 * Find a node by ID.
53 *
54 * If your application code depends on the existence of the element, use $,
55 * which will throw if the element doesn't exist.
56 *
57 * If you're not sure whether or not the element exists, use ge instead, and
58 * manually check for the element's existence in your application code.
59 *
60 * @param {string|DOMDocument|DOMElement|DOMTextNode|Comment} id
61 * @return {DOMDocument|DOMElement|DOMTextNode|Comment}
62 */
63function $(id) {
64 var element = ge(id);
65 if (!element) {
66 throw new Error(ex(
67 'Tried to get element with id of "%s" but it is not present on the page.',
68 id
69 ));
70 }
71 return element;
72}
73
74module.exports = $;
75
76},{"./ex":79,"./ge":83}],2:[function(require,module,exports){
77/**
78 * Copyright 2013 Facebook, Inc.
79 *
80 * Licensed under the Apache License, Version 2.0 (the "License");
81 * you may not use this file except in compliance with the License.
82 * You may obtain a copy of the License at
83 *
84 * http://www.apache.org/licenses/LICENSE-2.0
85 *
86 * Unless required by applicable law or agreed to in writing, software
87 * distributed under the License is distributed on an "AS IS" BASIS,
88 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
89 * See the License for the specific language governing permissions and
90 * limitations under the License.
91 *
92 * @providesModule CSSProperty
93 */
94
95"use strict";
96
97/**
98 * CSS properties which accept numbers but are not in units of "px".
99 */
100var isUnitlessNumber = {
101 fillOpacity: true,
102 fontWeight: true,
103 opacity: true,
104 orphans: true,
105 zIndex: true,
106 zoom: true
107};
108
109/**
110 * Most style properties can be unset by doing .style[prop] = '' but IE8
111 * doesn't like doing that with shorthand properties so for the properties that
112 * IE8 breaks on, which are listed here, we instead unset each of the
113 * individual properties. See http://bugs.jquery.com/ticket/12385.
114 * The 4-value 'clock' properties like margin, padding, border-width seem to
115 * behave without any problems. Curiously, list-style works too without any
116 * special prodding.
117 */
118var shorthandPropertyExpansions = {
119 background: {
120 backgroundImage: true,
121 backgroundPosition: true,
122 backgroundRepeat: true,
123 backgroundColor: true
124 },
125 border: {
126 borderWidth: true,
127 borderStyle: true,
128 borderColor: true
129 },
130 borderBottom: {
131 borderBottomWidth: true,
132 borderBottomStyle: true,
133 borderBottomColor: true
134 },
135 borderLeft: {
136 borderLeftWidth: true,
137 borderLeftStyle: true,
138 borderLeftColor: true
139 },
140 borderRight: {
141 borderRightWidth: true,
142 borderRightStyle: true,
143 borderRightColor: true
144 },
145 borderTop: {
146 borderTopWidth: true,
147 borderTopStyle: true,
148 borderTopColor: true
149 },
150 font: {
151 fontStyle: true,
152 fontVariant: true,
153 fontWeight: true,
154 fontSize: true,
155 lineHeight: true,
156 fontFamily: true
157 }
158};
159
160var CSSProperty = {
161 isUnitlessNumber: isUnitlessNumber,
162 shorthandPropertyExpansions: shorthandPropertyExpansions
163};
164
165module.exports = CSSProperty;
166
167},{}],3:[function(require,module,exports){
168/**
169 * Copyright 2013 Facebook, Inc.
170 *
171 * Licensed under the Apache License, Version 2.0 (the "License");
172 * you may not use this file except in compliance with the License.
173 * You may obtain a copy of the License at
174 *
175 * http://www.apache.org/licenses/LICENSE-2.0
176 *
177 * Unless required by applicable law or agreed to in writing, software
178 * distributed under the License is distributed on an "AS IS" BASIS,
179 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
180 * See the License for the specific language governing permissions and
181 * limitations under the License.
182 *
183 * @providesModule CSSPropertyOperations
184 * @typechecks static-only
185 */
186
187"use strict";
188
189var CSSProperty = require("./CSSProperty");
190
191var dangerousStyleValue = require("./dangerousStyleValue");
192var escapeTextForBrowser = require("./escapeTextForBrowser");
193var hyphenate = require("./hyphenate");
194var memoizeStringOnly = require("./memoizeStringOnly");
195
196var processStyleName = memoizeStringOnly(function(styleName) {
197 return escapeTextForBrowser(hyphenate(styleName));
198});
199
200/**
201 * Operations for dealing with CSS properties.
202 */
203var CSSPropertyOperations = {
204
205 /**
206 * Serializes a mapping of style properties for use as inline styles:
207 *
208 * > createMarkupForStyles({width: '200px', height: 0})
209 * "width:200px;height:0;"
210 *
211 * Undefined values are ignored so that declarative programming is easier.
212 *
213 * @param {object} styles
214 * @return {?string}
215 */
216 createMarkupForStyles: function(styles) {
217 var serialized = '';
218 for (var styleName in styles) {
219 if (!styles.hasOwnProperty(styleName)) {
220 continue;
221 }
222 var styleValue = styles[styleName];
223 if (styleValue != null) {
224 serialized += processStyleName(styleName) + ':';
225 serialized += dangerousStyleValue(styleName, styleValue) + ';';
226 }
227 }
228 return serialized || null;
229 },
230
231 /**
232 * Sets the value for multiple styles on a node. If a value is specified as
233 * '' (empty string), the corresponding style property will be unset.
234 *
235 * @param {DOMElement} node
236 * @param {object} styles
237 */
238 setValueForStyles: function(node, styles) {
239 var style = node.style;
240 for (var styleName in styles) {
241 if (!styles.hasOwnProperty(styleName)) {
242 continue;
243 }
244 var styleValue = dangerousStyleValue(styleName, styles[styleName]);
245 if (styleValue) {
246 style[styleName] = styleValue;
247 } else {
248 var expansion = CSSProperty.shorthandPropertyExpansions[styleName];
249 if (expansion) {
250 // Shorthand property that IE8 won't like unsetting, so unset each
251 // component to placate it
252 for (var individualStyleName in expansion) {
253 style[individualStyleName] = '';
254 }
255 } else {
256 style[styleName] = '';
257 }
258 }
259 }
260 }
261
262};
263
264module.exports = CSSPropertyOperations;
265
266},{"./CSSProperty":2,"./dangerousStyleValue":76,"./escapeTextForBrowser":78,"./hyphenate":88,"./memoizeStringOnly":94}],4:[function(require,module,exports){
267/**
268 * Copyright 2013 Facebook, Inc.
269 *
270 * Licensed under the Apache License, Version 2.0 (the "License");
271 * you may not use this file except in compliance with the License.
272 * You may obtain a copy of the License at
273 *
274 * http://www.apache.org/licenses/LICENSE-2.0
275 *
276 * Unless required by applicable law or agreed to in writing, software
277 * distributed under the License is distributed on an "AS IS" BASIS,
278 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
279 * See the License for the specific language governing permissions and
280 * limitations under the License.
281 *
282 * @providesModule CallbackRegistry
283 * @typechecks static-only
284 */
285
286"use strict";
287
288var listenerBank = {};
289
290/**
291 * Stores "listeners" by `registrationName`/`id`. There should be at most one
292 * "listener" per `registrationName`/`id` in the `listenerBank`.
293 *
294 * Access listeners via `listenerBank[registrationName][id]`.
295 *
296 * @class CallbackRegistry
297 * @internal
298 */
299var CallbackRegistry = {
300
301 /**
302 * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent.
303 *
304 * @param {string} id ID of the DOM element.
305 * @param {string} registrationName Name of listener (e.g. `onClick`).
306 * @param {?function} listener The callback to store.
307 */
308 putListener: function(id, registrationName, listener) {
309 var bankForRegistrationName =
310 listenerBank[registrationName] || (listenerBank[registrationName] = {});
311 bankForRegistrationName[id] = listener;
312 },
313
314 /**
315 * @param {string} id ID of the DOM element.
316 * @param {string} registrationName Name of listener (e.g. `onClick`).
317 * @return {?function} The stored callback.
318 */
319 getListener: function(id, registrationName) {
320 var bankForRegistrationName = listenerBank[registrationName];
321 return bankForRegistrationName && bankForRegistrationName[id];
322 },
323
324 /**
325 * Deletes a listener from the registration bank.
326 *
327 * @param {string} id ID of the DOM element.
328 * @param {string} registrationName Name of listener (e.g. `onClick`).
329 */
330 deleteListener: function(id, registrationName) {
331 var bankForRegistrationName = listenerBank[registrationName];
332 if (bankForRegistrationName) {
333 delete bankForRegistrationName[id];
334 }
335 },
336
337 /**
338 * Deletes all listeners for the DOM element with the supplied ID.
339 *
340 * @param {string} id ID of the DOM element.
341 */
342 deleteAllListeners: function(id) {
343 for (var registrationName in listenerBank) {
344 delete listenerBank[registrationName][id];
345 }
346 },
347
348 /**
349 * This is needed for tests only. Do not use!
350 */
351 __purge: function() {
352 listenerBank = {};
353 }
354
355};
356
357module.exports = CallbackRegistry;
358
359},{}],5:[function(require,module,exports){
360/**
361 * Copyright 2013 Facebook, Inc.
362 *
363 * Licensed under the Apache License, Version 2.0 (the "License");
364 * you may not use this file except in compliance with the License.
365 * You may obtain a copy of the License at
366 *
367 * http://www.apache.org/licenses/LICENSE-2.0
368 *
369 * Unless required by applicable law or agreed to in writing, software
370 * distributed under the License is distributed on an "AS IS" BASIS,
371 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
372 * See the License for the specific language governing permissions and
373 * limitations under the License.
374 *
375 * @providesModule ChangeEventPlugin
376 */
377
378"use strict";
379
380var EventConstants = require("./EventConstants");
381var EventPluginHub = require("./EventPluginHub");
382var EventPropagators = require("./EventPropagators");
383var ExecutionEnvironment = require("./ExecutionEnvironment");
384var SyntheticEvent = require("./SyntheticEvent");
385
386var isEventSupported = require("./isEventSupported");
387var keyOf = require("./keyOf");
388
389var topLevelTypes = EventConstants.topLevelTypes;
390
391var eventTypes = {
392 change: {
393 phasedRegistrationNames: {
394 bubbled: keyOf({onChange: null}),
395 captured: keyOf({onChangeCapture: null})
396 }
397 }
398};
399
400/**
401 * For IE shims
402 */
403var activeElement = null;
404var activeElementID = null;
405var activeElementValue = null;
406var activeElementValueProp = null;
407
408
409/**
410 * SECTION: handle `change` event
411 */
412function shouldUseChangeEvent(elem) {
413 return (
414 elem.nodeName === 'SELECT' ||
415 (elem.nodeName === 'INPUT' && elem.type === 'file')
416 );
417}
418
419var doesChangeEventBubble = false;
420if (ExecutionEnvironment.canUseDOM) {
421 // See `handleChange` comment below
422 doesChangeEventBubble = isEventSupported('change') && (
423 !('documentMode' in document) || document.documentMode > 8
424 );
425}
426
427function manualDispatchChangeEvent(nativeEvent) {
428 var event = SyntheticEvent.getPooled(
429 eventTypes.change,
430 activeElementID,
431 nativeEvent
432 );
433 EventPropagators.accumulateTwoPhaseDispatches(event);
434
435 // If change bubbled, we'd just bind to it like all the other events
436 // and have it go through ReactEventTopLevelCallback. Since it doesn't, we
437 // manually listen for the change event and so we have to enqueue and
438 // process the abstract event manually.
439 EventPluginHub.enqueueEvents(event);
440 EventPluginHub.processEventQueue();
441}
442
443function startWatchingForChangeEventIE8(target, targetID) {
444 activeElement = target;
445 activeElementID = targetID;
446 activeElement.attachEvent('onchange', manualDispatchChangeEvent);
447}
448
449function stopWatchingForChangeEventIE8() {
450 if (!activeElement) {
451 return;
452 }
453 activeElement.detachEvent('onchange', manualDispatchChangeEvent);
454 activeElement = null;
455 activeElementID = null;
456}
457
458function getTargetIDForChangeEvent(
459 topLevelType,
460 topLevelTarget,
461 topLevelTargetID) {
462 if (topLevelType === topLevelTypes.topChange) {
463 return topLevelTargetID;
464 }
465}
466function handleEventsForChangeEventIE8(
467 topLevelType,
468 topLevelTarget,
469 topLevelTargetID) {
470 if (topLevelType === topLevelTypes.topFocus) {
471 // stopWatching() should be a noop here but we call it just in case we
472 // missed a blur event somehow.
473 stopWatchingForChangeEventIE8();
474 startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID);
475 } else if (topLevelType === topLevelTypes.topBlur) {
476 stopWatchingForChangeEventIE8();
477 }
478}
479
480
481/**
482 * SECTION: handle `input` event
483 */
484var isInputEventSupported = false;
485if (ExecutionEnvironment.canUseDOM) {
486 // IE9 claims to support the input event but fails to trigger it when
487 // deleting text, so we ignore its input events
488 isInputEventSupported = isEventSupported('input') && (
489 !('documentMode' in document) || document.documentMode > 9
490 );
491}
492
493
494/**
495 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
496 */
497var supportedInputTypes = {
498 'color': true,
499 'date': true,
500 'datetime': true,
501 'datetime-local': true,
502 'email': true,
503 'month': true,
504 'number': true,
505 'password': true,
506 'range': true,
507 'search': true,
508 'tel': true,
509 'text': true,
510 'time': true,
511 'url': true,
512 'week': true
513};
514
515function shouldUseInputEvent(elem) {
516 return (
517 (elem.nodeName === 'INPUT' && supportedInputTypes[elem.type]) ||
518 elem.nodeName === 'TEXTAREA'
519 );
520}
521
522/**
523 * (For old IE.) Replacement getter/setter for the `value` property that gets
524 * set on the active element.
525 */
526var newValueProp = {
527 get: function() {
528 return activeElementValueProp.get.call(this);
529 },
530 set: function(val) {
531 // Cast to a string so we can do equality checks.
532 activeElementValue = '' + val;
533 activeElementValueProp.set.call(this, val);
534 }
535};
536
537/**
538 * (For old IE.) Starts tracking propertychange events on the passed-in element
539 * and override the value property so that we can distinguish user events from
540 * value changes in JS.
541 */
542function startWatchingForValueChange(target, targetID) {
543 activeElement = target;
544 activeElementID = targetID;
545 activeElementValue = target.value;
546 activeElementValueProp = Object.getOwnPropertyDescriptor(
547 target.constructor.prototype,
548 'value'
549 );
550
551 Object.defineProperty(activeElement, 'value', newValueProp);
552 activeElement.attachEvent('onpropertychange', handlePropertyChange);
553}
554
555/**
556 * (For old IE.) Removes the event listeners from the currently-tracked element,
557 * if any exists.
558 */
559function stopWatchingForValueChange() {
560 if (!activeElement) {
561 return;
562 }
563
564 // delete restores the original property definition
565 delete activeElement.value;
566 activeElement.detachEvent('onpropertychange', handlePropertyChange);
567
568 activeElement = null;
569 activeElementID = null;
570 activeElementValue = null;
571 activeElementValueProp = null;
572}
573
574/**
575 * (For old IE.) Handles a propertychange event, sending a `change` event if
576 * the value of the active element has changed.
577 */
578function handlePropertyChange(nativeEvent) {
579 if (nativeEvent.propertyName !== 'value') {
580 return;
581 }
582 var value = nativeEvent.srcElement.value;
583 if (value === activeElementValue) {
584 return;
585 }
586 activeElementValue = value;
587
588 manualDispatchChangeEvent(nativeEvent);
589}
590
591/**
592 * If a `change` event should be fired, returns the target's ID.
593 */
594function getTargetIDForInputEvent(
595 topLevelType,
596 topLevelTarget,
597 topLevelTargetID) {
598 if (topLevelType === topLevelTypes.topInput) {
599 // In modern browsers (i.e., not IE8 or IE9), the input event is exactly
600 // what we want so fall through here and trigger an abstract event
601 return topLevelTargetID;
602 }
603}
604
605// For IE8 and IE9.
606function handleEventsForInputEventIE(
607 topLevelType,
608 topLevelTarget,
609 topLevelTargetID) {
610 if (topLevelType === topLevelTypes.topFocus) {
611 // In IE8, we can capture almost all .value changes by adding a
612 // propertychange handler and looking for events with propertyName
613 // equal to 'value'
614 // In IE9, propertychange fires for most input events but is buggy and
615 // doesn't fire when text is deleted, but conveniently, selectionchange
616 // appears to fire in all of the remaining cases so we catch those and
617 // forward the event if the value has changed
618 // In either case, we don't want to call the event handler if the value
619 // is changed from JS so we redefine a setter for `.value` that updates
620 // our activeElementValue variable, allowing us to ignore those changes
621 //
622 // stopWatching() should be a noop here but we call it just in case we
623 // missed a blur event somehow.
624 stopWatchingForValueChange();
625 startWatchingForValueChange(topLevelTarget, topLevelTargetID);
626 } else if (topLevelType === topLevelTypes.topBlur) {
627 stopWatchingForValueChange();
628 }
629}
630
631// For IE8 and IE9.
632function getTargetIDForInputEventIE(
633 topLevelType,
634 topLevelTarget,
635 topLevelTargetID) {
636 if (topLevelType === topLevelTypes.topSelectionChange ||
637 topLevelType === topLevelTypes.topKeyUp ||
638 topLevelType === topLevelTypes.topKeyDown) {
639 // On the selectionchange event, the target is just document which isn't
640 // helpful for us so just check activeElement instead.
641 //
642 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
643 // propertychange on the first input event after setting `value` from a
644 // script and fires only keydown, keypress, keyup. Catching keyup usually
645 // gets it and catching keydown lets us fire an event for the first
646 // keystroke if user does a key repeat (it'll be a little delayed: right
647 // before the second keystroke). Other input methods (e.g., paste) seem to
648 // fire selectionchange normally.
649 if (activeElement && activeElement.value !== activeElementValue) {
650 activeElementValue = activeElement.value;
651 return activeElementID;
652 }
653 }
654}
655
656
657/**
658 * SECTION: handle `click` event
659 */
660function shouldUseClickEvent(elem) {
661 // Use the `click` event to detect changes to checkbox and radio inputs.
662 // This approach works across all browsers, whereas `change` does not fire
663 // until `blur` in IE8.
664 return (
665 elem.nodeName === 'INPUT' &&
666 (elem.type === 'checkbox' || elem.type === 'radio')
667 );
668}
669
670function getTargetIDForClickEvent(
671 topLevelType,
672 topLevelTarget,
673 topLevelTargetID) {
674 if (topLevelType === topLevelTypes.topClick) {
675 return topLevelTargetID;
676 }
677}
678
679/**
680 * This plugin creates an `onChange` event that normalizes change events
681 * across form elements. This event fires at a time when it's possible to
682 * change the element's value without seeing a flicker.
683 *
684 * Supported elements are:
685 * - input (see `supportedInputTypes`)
686 * - textarea
687 * - select
688 */
689var ChangeEventPlugin = {
690
691 eventTypes: eventTypes,
692
693 /**
694 * @param {string} topLevelType Record from `EventConstants`.
695 * @param {DOMEventTarget} topLevelTarget The listening component root node.
696 * @param {string} topLevelTargetID ID of `topLevelTarget`.
697 * @param {object} nativeEvent Native browser event.
698 * @return {*} An accumulation of synthetic events.
699 * @see {EventPluginHub.extractEvents}
700 */
701 extractEvents: function(
702 topLevelType,
703 topLevelTarget,
704 topLevelTargetID,
705 nativeEvent) {
706
707 var getTargetIDFunc, handleEventFunc;
708 if (shouldUseChangeEvent(topLevelTarget)) {
709 if (doesChangeEventBubble) {
710 getTargetIDFunc = getTargetIDForChangeEvent;
711 } else {
712 handleEventFunc = handleEventsForChangeEventIE8;
713 }
714 } else if (shouldUseInputEvent(topLevelTarget)) {
715 if (isInputEventSupported) {
716 getTargetIDFunc = getTargetIDForInputEvent;
717 } else {
718 getTargetIDFunc = getTargetIDForInputEventIE;
719 handleEventFunc = handleEventsForInputEventIE;
720 }
721 } else if (shouldUseClickEvent(topLevelTarget)) {
722 getTargetIDFunc = getTargetIDForClickEvent;
723 }
724
725 if (getTargetIDFunc) {
726 var targetID = getTargetIDFunc(
727 topLevelType,
728 topLevelTarget,
729 topLevelTargetID
730 );
731 if (targetID) {
732 var event = SyntheticEvent.getPooled(
733 eventTypes.change,
734 targetID,
735 nativeEvent
736 );
737 EventPropagators.accumulateTwoPhaseDispatches(event);
738 return event;
739 }
740 }
741
742 if (handleEventFunc) {
743 handleEventFunc(
744 topLevelType,
745 topLevelTarget,
746 topLevelTargetID
747 );
748 }
749 }
750
751};
752
753module.exports = ChangeEventPlugin;
754
755},{"./EventConstants":13,"./EventPluginHub":15,"./EventPropagators":18,"./ExecutionEnvironment":19,"./SyntheticEvent":60,"./isEventSupported":90,"./keyOf":93}],6:[function(require,module,exports){
756/**
757 * Copyright 2013 Facebook, Inc.
758 *
759 * Licensed under the Apache License, Version 2.0 (the "License");
760 * you may not use this file except in compliance with the License.
761 * You may obtain a copy of the License at
762 *
763 * http://www.apache.org/licenses/LICENSE-2.0
764 *
765 * Unless required by applicable law or agreed to in writing, software
766 * distributed under the License is distributed on an "AS IS" BASIS,
767 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
768 * See the License for the specific language governing permissions and
769 * limitations under the License.
770 *
771 * @providesModule DOMChildrenOperations
772 * @typechecks static-only
773 */
774
775"use strict";
776
777var Danger = require("./Danger");
778var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
779
780var getTextContentAccessor = require("./getTextContentAccessor");
781
782/**
783 * The DOM property to use when setting text content.
784 *
785 * @type {string}
786 * @private
787 */
788var textContentAccessor = getTextContentAccessor() || 'NA';
789
790/**
791 * Inserts `childNode` as a child of `parentNode` at the `index`.
792 *
793 * @param {DOMElement} parentNode Parent node in which to insert.
794 * @param {DOMElement} childNode Child node to insert.
795 * @param {number} index Index at which to insert the child.
796 * @internal
797 */
798function insertChildAt(parentNode, childNode, index) {
799 var childNodes = parentNode.childNodes;
800 if (childNodes[index] === childNode) {
801 return;
802 }
803 // If `childNode` is already a child of `parentNode`, remove it so that
804 // computing `childNodes[index]` takes into account the removal.
805 if (childNode.parentNode === parentNode) {
806 parentNode.removeChild(childNode);
807 }
808 if (index >= childNodes.length) {
809 parentNode.appendChild(childNode);
810 } else {
811 parentNode.insertBefore(childNode, childNodes[index]);
812 }
813}
814
815/**
816 * Operations for updating with DOM children.
817 */
818var DOMChildrenOperations = {
819
820 dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,
821
822 /**
823 * Updates a component's children by processing a series of updates. The
824 * update configurations are each expected to have a `parentNode` property.
825 *
826 * @param {array<object>} updates List of update configurations.
827 * @param {array<string>} markupList List of markup strings.
828 * @internal
829 */
830 processUpdates: function(updates, markupList) {
831 var update;
832 // Mapping from parent IDs to initial child orderings.
833 var initialChildren = null;
834 // List of children that will be moved or removed.
835 var updatedChildren = null;
836
837 for (var i = 0; update = updates[i]; i++) {
838 if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING ||
839 update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) {
840 var updatedIndex = update.fromIndex;
841 var updatedChild = update.parentNode.childNodes[updatedIndex];
842 var parentID = update.parentID;
843
844 initialChildren = initialChildren || {};
845 initialChildren[parentID] = initialChildren[parentID] || [];
846 initialChildren[parentID][updatedIndex] = updatedChild;
847
848 updatedChildren = updatedChildren || [];
849 updatedChildren.push(updatedChild);
850 }
851 }
852
853 var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList);
854
855 // Remove updated children first so that `toIndex` is consistent.
856 if (updatedChildren) {
857 for (var j = 0; j < updatedChildren.length; j++) {
858 updatedChildren[j].parentNode.removeChild(updatedChildren[j]);
859 }
860 }
861
862 for (var k = 0; update = updates[k]; k++) {
863 switch (update.type) {
864 case ReactMultiChildUpdateTypes.INSERT_MARKUP:
865 insertChildAt(
866 update.parentNode,
867 renderedMarkup[update.markupIndex],
868 update.toIndex
869 );
870 break;
871 case ReactMultiChildUpdateTypes.MOVE_EXISTING:
872 insertChildAt(
873 update.parentNode,
874 initialChildren[update.parentID][update.fromIndex],
875 update.toIndex
876 );
877 break;
878 case ReactMultiChildUpdateTypes.TEXT_CONTENT:
879 update.parentNode[textContentAccessor] = update.textContent;
880 break;
881 case ReactMultiChildUpdateTypes.REMOVE_NODE:
882 // Already removed by the for-loop above.
883 break;
884 }
885 }
886 }
887
888};
889
890module.exports = DOMChildrenOperations;
891
892},{"./Danger":9,"./ReactMultiChildUpdateTypes":47,"./getTextContentAccessor":87}],7:[function(require,module,exports){
893/**
894 * Copyright 2013 Facebook, Inc.
895 *
896 * Licensed under the Apache License, Version 2.0 (the "License");
897 * you may not use this file except in compliance with the License.
898 * You may obtain a copy of the License at
899 *
900 * http://www.apache.org/licenses/LICENSE-2.0
901 *
902 * Unless required by applicable law or agreed to in writing, software
903 * distributed under the License is distributed on an "AS IS" BASIS,
904 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
905 * See the License for the specific language governing permissions and
906 * limitations under the License.
907 *
908 * @providesModule DOMProperty
909 * @typechecks static-only
910 */
911
912/*jslint bitwise: true */
913
914"use strict";
915
916var invariant = require("./invariant");
917
918var DOMPropertyInjection = {
919 /**
920 * Mapping from normalized, camelcased property names to a configuration that
921 * specifies how the associated DOM property should be accessed or rendered.
922 */
923 MUST_USE_ATTRIBUTE: 0x1,
924 MUST_USE_PROPERTY: 0x2,
925 HAS_BOOLEAN_VALUE: 0x4,
926 HAS_SIDE_EFFECTS: 0x8,
927
928 /**
929 * Inject some specialized knowledge about the DOM. This takes a config object
930 * with the following properties:
931 *
932 * isCustomAttribute: function that given an attribute name will return true
933 * if it can be inserted into the DOM verbatim. Useful for data-* or aria-*
934 * attributes where it's impossible to enumerate all of the possible
935 * attribute names,
936 *
937 * Properties: object mapping DOM property name to one of the
938 * DOMPropertyInjection constants or null. If your attribute isn't in here,
939 * it won't get written to the DOM.
940 *
941 * DOMAttributeNames: object mapping React attribute name to the DOM
942 * attribute name. Attribute names not specified use the **lowercase**
943 * normalized name.
944 *
945 * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.
946 * Property names not specified use the normalized name.
947 *
948 * DOMMutationMethods: Properties that require special mutation methods. If
949 * `value` is undefined, the mutation method should unset the property.
950 *
951 * @param {object} domPropertyConfig the config as described above.
952 */
953 injectDOMPropertyConfig: function(domPropertyConfig) {
954 var Properties = domPropertyConfig.Properties || {};
955 var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};
956 var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};
957 var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};
958
959 if (domPropertyConfig.isCustomAttribute) {
960 DOMProperty._isCustomAttributeFunctions.push(
961 domPropertyConfig.isCustomAttribute
962 );
963 }
964
965 for (var propName in Properties) {
966 invariant(
967 !DOMProperty.isStandardName[propName],
968 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' +
969 '\'%s\' which has already been injected. You may be accidentally ' +
970 'injecting the same DOM property config twice, or you may be ' +
971 'injecting two configs that have conflicting property names.',
972 propName
973 );
974
975 DOMProperty.isStandardName[propName] = true;
976
977 var lowerCased = propName.toLowerCase();
978 DOMProperty.getPossibleStandardName[lowerCased] = propName;
979
980 var attributeName = DOMAttributeNames[propName];
981 if (attributeName) {
982 DOMProperty.getPossibleStandardName[attributeName] = propName;
983 }
984
985 DOMProperty.getAttributeName[propName] = attributeName || lowerCased;
986
987 DOMProperty.getPropertyName[propName] =
988 DOMPropertyNames[propName] || propName;
989
990 var mutationMethod = DOMMutationMethods[propName];
991 if (mutationMethod) {
992 DOMProperty.getMutationMethod[propName] = mutationMethod;
993 }
994
995 var propConfig = Properties[propName];
996 DOMProperty.mustUseAttribute[propName] =
997 propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE;
998 DOMProperty.mustUseProperty[propName] =
999 propConfig & DOMPropertyInjection.MUST_USE_PROPERTY;
1000 DOMProperty.hasBooleanValue[propName] =
1001 propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE;
1002 DOMProperty.hasSideEffects[propName] =
1003 propConfig & DOMPropertyInjection.HAS_SIDE_EFFECTS;
1004
1005 invariant(
1006 !DOMProperty.mustUseAttribute[propName] ||
1007 !DOMProperty.mustUseProperty[propName],
1008 'DOMProperty: Cannot use require using both attribute and property: %s',
1009 propName
1010 );
1011 invariant(
1012 DOMProperty.mustUseProperty[propName] ||
1013 !DOMProperty.hasSideEffects[propName],
1014 'DOMProperty: Properties that have side effects must use property: %s',
1015 propName
1016 );
1017 }
1018 }
1019};
1020var defaultValueCache = {};
1021
1022/**
1023 * DOMProperty exports lookup objects that can be used like functions:
1024 *
1025 * > DOMProperty.isValid['id']
1026 * true
1027 * > DOMProperty.isValid['foobar']
1028 * undefined
1029 *
1030 * Although this may be confusing, it performs better in general.
1031 *
1032 * @see http://jsperf.com/key-exists
1033 * @see http://jsperf.com/key-missing
1034 */
1035var DOMProperty = {
1036
1037 /**
1038 * Checks whether a property name is a standard property.
1039 * @type {Object}
1040 */
1041 isStandardName: {},
1042
1043 /**
1044 * Mapping from lowercase property names to the properly cased version, used
1045 * to warn in the case of missing properties.
1046 * @type {Object}
1047 */
1048 getPossibleStandardName: {},
1049
1050 /**
1051 * Mapping from normalized names to attribute names that differ. Attribute
1052 * names are used when rendering markup or with `*Attribute()`.
1053 * @type {Object}
1054 */
1055 getAttributeName: {},
1056
1057 /**
1058 * Mapping from normalized names to properties on DOM node instances.
1059 * (This includes properties that mutate due to external factors.)
1060 * @type {Object}
1061 */
1062 getPropertyName: {},
1063
1064 /**
1065 * Mapping from normalized names to mutation methods. This will only exist if
1066 * mutation cannot be set simply by the property or `setAttribute()`.
1067 * @type {Object}
1068 */
1069 getMutationMethod: {},
1070
1071 /**
1072 * Whether the property must be accessed and mutated as an object property.
1073 * @type {Object}
1074 */
1075 mustUseAttribute: {},
1076
1077 /**
1078 * Whether the property must be accessed and mutated using `*Attribute()`.
1079 * (This includes anything that fails `<propName> in <element>`.)
1080 * @type {Object}
1081 */
1082 mustUseProperty: {},
1083
1084 /**
1085 * Whether the property should be removed when set to a falsey value.
1086 * @type {Object}
1087 */
1088 hasBooleanValue: {},
1089
1090 /**
1091 * Whether or not setting a value causes side effects such as triggering
1092 * resources to be loaded or text selection changes. We must ensure that
1093 * the value is only set if it has changed.
1094 * @type {Object}
1095 */
1096 hasSideEffects: {},
1097
1098 /**
1099 * All of the isCustomAttribute() functions that have been injected.
1100 */
1101 _isCustomAttributeFunctions: [],
1102
1103 /**
1104 * Checks whether a property name is a custom attribute.
1105 * @method
1106 */
1107 isCustomAttribute: function(attributeName) {
1108 return DOMProperty._isCustomAttributeFunctions.some(
1109 function(isCustomAttributeFn) {
1110 return isCustomAttributeFn.call(null, attributeName);
1111 }
1112 );
1113 },
1114
1115 /**
1116 * Returns the default property value for a DOM property (i.e., not an
1117 * attribute). Most default values are '' or false, but not all. Worse yet,
1118 * some (in particular, `type`) vary depending on the type of element.
1119 *
1120 * TODO: Is it better to grab all the possible properties when creating an
1121 * element to avoid having to create the same element twice?
1122 */
1123 getDefaultValueForProperty: function(nodeName, prop) {
1124 var nodeDefaults = defaultValueCache[nodeName];
1125 var testElement;
1126 if (!nodeDefaults) {
1127 defaultValueCache[nodeName] = nodeDefaults = {};
1128 }
1129 if (!(prop in nodeDefaults)) {
1130 testElement = document.createElement(nodeName);
1131 nodeDefaults[prop] = testElement[prop];
1132 }
1133 return nodeDefaults[prop];
1134 },
1135
1136 injection: DOMPropertyInjection
1137};
1138
1139module.exports = DOMProperty;
1140
1141},{"./invariant":89}],8:[function(require,module,exports){
1142/**
1143 * Copyright 2013 Facebook, Inc.
1144 *
1145 * Licensed under the Apache License, Version 2.0 (the "License");
1146 * you may not use this file except in compliance with the License.
1147 * You may obtain a copy of the License at
1148 *
1149 * http://www.apache.org/licenses/LICENSE-2.0
1150 *
1151 * Unless required by applicable law or agreed to in writing, software
1152 * distributed under the License is distributed on an "AS IS" BASIS,
1153 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1154 * See the License for the specific language governing permissions and
1155 * limitations under the License.
1156 *
1157 * @providesModule DOMPropertyOperations
1158 * @typechecks static-only
1159 */
1160
1161"use strict";
1162
1163var DOMProperty = require("./DOMProperty");
1164
1165var escapeTextForBrowser = require("./escapeTextForBrowser");
1166var memoizeStringOnly = require("./memoizeStringOnly");
1167
1168var processAttributeNameAndPrefix = memoizeStringOnly(function(name) {
1169 return escapeTextForBrowser(name) + '="';
1170});
1171
1172if (true) {
1173 var reactProps = {
1174 '{owner}': true,
1175 children: true,
1176 dangerouslySetInnerHTML: true,
1177 key: true,
1178 ref: true
1179 };
1180 var warnedProperties = {};
1181
1182 var warnUnknownProperty = function(name) {
1183 if (reactProps[name] || warnedProperties[name]) {
1184 return;
1185 }
1186
1187 warnedProperties[name] = true;
1188 var lowerCasedName = name.toLowerCase();
1189
1190 // data-* attributes should be lowercase; suggest the lowercase version
1191 var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ?
1192 lowerCasedName : DOMProperty.getPossibleStandardName[lowerCasedName];
1193
1194 // For now, only warn when we have a suggested correction. This prevents
1195 // logging too much when using transferPropsTo.
1196 if (standardName != null) {
1197 console.warn(
1198 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?'
1199 );
1200 }
1201
1202 };
1203}
1204
1205/**
1206 * Operations for dealing with DOM properties.
1207 */
1208var DOMPropertyOperations = {
1209
1210 /**
1211 * Creates markup for a property.
1212 *
1213 * @param {string} name
1214 * @param {*} value
1215 * @return {?string} Markup string, or null if the property was invalid.
1216 */
1217 createMarkupForProperty: function(name, value) {
1218 if (DOMProperty.isStandardName[name]) {
1219 if (value == null || DOMProperty.hasBooleanValue[name] && !value) {
1220 return '';
1221 }
1222 var attributeName = DOMProperty.getAttributeName[name];
1223 return processAttributeNameAndPrefix(attributeName) +
1224 escapeTextForBrowser(value) + '"';
1225 } else if (DOMProperty.isCustomAttribute(name)) {
1226 if (value == null) {
1227 return '';
1228 }
1229 return processAttributeNameAndPrefix(name) +
1230 escapeTextForBrowser(value) + '"';
1231 } else {
1232 if (true) {
1233 warnUnknownProperty(name);
1234 }
1235 return null;
1236 }
1237 },
1238
1239 /**
1240 * Sets the value for a property on a node.
1241 *
1242 * @param {DOMElement} node
1243 * @param {string} name
1244 * @param {*} value
1245 */
1246 setValueForProperty: function(node, name, value) {
1247 if (DOMProperty.isStandardName[name]) {
1248 var mutationMethod = DOMProperty.getMutationMethod[name];
1249 if (mutationMethod) {
1250 mutationMethod(node, value);
1251 } else if (DOMProperty.mustUseAttribute[name]) {
1252 if (DOMProperty.hasBooleanValue[name] && !value) {
1253 node.removeAttribute(DOMProperty.getAttributeName[name]);
1254 } else {
1255 node.setAttribute(DOMProperty.getAttributeName[name], value);
1256 }
1257 } else {
1258 var propName = DOMProperty.getPropertyName[name];
1259 if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) {
1260 node[propName] = value;
1261 }
1262 }
1263 } else if (DOMProperty.isCustomAttribute(name)) {
1264 node.setAttribute(name, value);
1265 } else {
1266 if (true) {
1267 warnUnknownProperty(name);
1268 }
1269 }
1270 },
1271
1272 /**
1273 * Deletes the value for a property on a node.
1274 *
1275 * @param {DOMElement} node
1276 * @param {string} name
1277 */
1278 deleteValueForProperty: function(node, name) {
1279 if (DOMProperty.isStandardName[name]) {
1280 var mutationMethod = DOMProperty.getMutationMethod[name];
1281 if (mutationMethod) {
1282 mutationMethod(node, undefined);
1283 } else if (DOMProperty.mustUseAttribute[name]) {
1284 node.removeAttribute(DOMProperty.getAttributeName[name]);
1285 } else {
1286 var propName = DOMProperty.getPropertyName[name];
1287 node[propName] = DOMProperty.getDefaultValueForProperty(
1288 node.nodeName,
1289 name
1290 );
1291 }
1292 } else if (DOMProperty.isCustomAttribute(name)) {
1293 node.removeAttribute(name);
1294 } else {
1295 if (true) {
1296 warnUnknownProperty(name);
1297 }
1298 }
1299 }
1300
1301};
1302
1303module.exports = DOMPropertyOperations;
1304
1305},{"./DOMProperty":7,"./escapeTextForBrowser":78,"./memoizeStringOnly":94}],9:[function(require,module,exports){
1306/**
1307 * Copyright 2013 Facebook, Inc.
1308 *
1309 * Licensed under the Apache License, Version 2.0 (the "License");
1310 * you may not use this file except in compliance with the License.
1311 * You may obtain a copy of the License at
1312 *
1313 * http://www.apache.org/licenses/LICENSE-2.0
1314 *
1315 * Unless required by applicable law or agreed to in writing, software
1316 * distributed under the License is distributed on an "AS IS" BASIS,
1317 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1318 * See the License for the specific language governing permissions and
1319 * limitations under the License.
1320 *
1321 * @providesModule Danger
1322 * @typechecks static-only
1323 */
1324
1325/*jslint evil: true, sub: true */
1326
1327"use strict";
1328
1329var ExecutionEnvironment = require("./ExecutionEnvironment");
1330
1331var createNodesFromMarkup = require("./createNodesFromMarkup");
1332var emptyFunction = require("./emptyFunction");
1333var getMarkupWrap = require("./getMarkupWrap");
1334var invariant = require("./invariant");
1335var mutateHTMLNodeWithMarkup = require("./mutateHTMLNodeWithMarkup");
1336
1337var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/;
1338var RESULT_INDEX_ATTR = 'data-danger-index';
1339
1340/**
1341 * Extracts the `nodeName` from a string of markup.
1342 *
1343 * NOTE: Extracting the `nodeName` does not require a regular expression match
1344 * because we make assumptions about React-generated markup (i.e. there are no
1345 * spaces surrounding the opening tag and there is at least one attribute).
1346 *
1347 * @param {string} markup String of markup.
1348 * @return {string} Node name of the supplied markup.
1349 * @see http://jsperf.com/extract-nodename
1350 */
1351function getNodeName(markup) {
1352 return markup.substring(1, markup.indexOf(' '));
1353}
1354
1355var Danger = {
1356
1357 /**
1358 * Renders markup into an array of nodes. The markup is expected to render
1359 * into a list of root nodes. Also, the length of `resultList` and
1360 * `markupList` should be the same.
1361 *
1362 * @param {array<string>} markupList List of markup strings to render.
1363 * @return {array<DOMElement>} List of rendered nodes.
1364 * @internal
1365 */
1366 dangerouslyRenderMarkup: function(markupList) {
1367 invariant(
1368 ExecutionEnvironment.canUseDOM,
1369 'dangerouslyRenderMarkup(...): Cannot render markup in a Worker ' +
1370 'thread. This is likely a bug in the framework. Please report ' +
1371 'immediately.'
1372 );
1373 var nodeName;
1374 var markupByNodeName = {};
1375 // Group markup by `nodeName` if a wrap is necessary, else by '*'.
1376 for (var i = 0; i < markupList.length; i++) {
1377 invariant(
1378 markupList[i],
1379 'dangerouslyRenderMarkup(...): Missing markup.'
1380 );
1381 nodeName = getNodeName(markupList[i]);
1382 nodeName = getMarkupWrap(nodeName) ? nodeName : '*';
1383 markupByNodeName[nodeName] = markupByNodeName[nodeName] || [];
1384 markupByNodeName[nodeName][i] = markupList[i];
1385 }
1386 var resultList = [];
1387 var resultListAssignmentCount = 0;
1388 for (nodeName in markupByNodeName) {
1389 if (!markupByNodeName.hasOwnProperty(nodeName)) {
1390 continue;
1391 }
1392 var markupListByNodeName = markupByNodeName[nodeName];
1393
1394 // This for-in loop skips the holes of the sparse array. The order of
1395 // iteration should follow the order of assignment, which happens to match
1396 // numerical index order, but we don't rely on that.
1397 for (var resultIndex in markupListByNodeName) {
1398 if (markupListByNodeName.hasOwnProperty(resultIndex)) {
1399 var markup = markupListByNodeName[resultIndex];
1400
1401 // Push the requested markup with an additional RESULT_INDEX_ATTR
1402 // attribute. If the markup does not start with a < character, it
1403 // will be discarded below (with an appropriate console.error).
1404 markupListByNodeName[resultIndex] = markup.replace(
1405 OPEN_TAG_NAME_EXP,
1406 // This index will be parsed back out below.
1407 '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" '
1408 );
1409 }
1410 }
1411
1412 // Render each group of markup with similar wrapping `nodeName`.
1413 var renderNodes = createNodesFromMarkup(
1414 markupListByNodeName.join(''),
1415 emptyFunction // Do nothing special with <script> tags.
1416 );
1417
1418 for (i = 0; i < renderNodes.length; ++i) {
1419 var renderNode = renderNodes[i];
1420 if (renderNode.hasAttribute &&
1421 renderNode.hasAttribute(RESULT_INDEX_ATTR)) {
1422
1423 resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR);
1424 renderNode.removeAttribute(RESULT_INDEX_ATTR);
1425
1426 invariant(
1427 !resultList.hasOwnProperty(resultIndex),
1428 'Danger: Assigning to an already-occupied result index.'
1429 );
1430
1431 resultList[resultIndex] = renderNode;
1432
1433 // This should match resultList.length and markupList.length when
1434 // we're done.
1435 resultListAssignmentCount += 1;
1436
1437 } else if (true) {
1438 console.error(
1439 "Danger: Discarding unexpected node:",
1440 renderNode
1441 );
1442 }
1443 }
1444 }
1445
1446 // Although resultList was populated out of order, it should now be a dense
1447 // array.
1448 invariant(
1449 resultListAssignmentCount === resultList.length,
1450 'Danger: Did not assign to every index of resultList.'
1451 );
1452
1453 invariant(
1454 resultList.length === markupList.length,
1455 'Danger: Expected markup to render %d nodes, but rendered %d.',
1456 markupList.length,
1457 resultList.length
1458 );
1459
1460 return resultList;
1461 },
1462
1463 /**
1464 * Replaces a node with a string of markup at its current position within its
1465 * parent. The markup must render into a single root node.
1466 *
1467 * @param {DOMElement} oldChild Child node to replace.
1468 * @param {string} markup Markup to render in place of the child node.
1469 * @internal
1470 */
1471 dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) {
1472 invariant(
1473 ExecutionEnvironment.canUseDOM,
1474 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' +
1475 'worker thread. This is likely a bug in the framework. Please report ' +
1476 'immediately.'
1477 );
1478 invariant(markup, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.');
1479 // createNodesFromMarkup() won't work if the markup is rooted by <html>
1480 // since it has special semantic meaning. So we use an alternatie strategy.
1481 if (oldChild.tagName.toLowerCase() === 'html') {
1482 mutateHTMLNodeWithMarkup(oldChild, markup);
1483 return;
1484 }
1485 var newChild = createNodesFromMarkup(markup, emptyFunction)[0];
1486 oldChild.parentNode.replaceChild(newChild, oldChild);
1487 }
1488
1489};
1490
1491module.exports = Danger;
1492
1493},{"./ExecutionEnvironment":19,"./createNodesFromMarkup":74,"./emptyFunction":77,"./getMarkupWrap":85,"./invariant":89,"./mutateHTMLNodeWithMarkup":99}],10:[function(require,module,exports){
1494/**
1495 * Copyright 2013 Facebook, Inc.
1496 *
1497 * Licensed under the Apache License, Version 2.0 (the "License");
1498 * you may not use this file except in compliance with the License.
1499 * You may obtain a copy of the License at
1500 *
1501 * http://www.apache.org/licenses/LICENSE-2.0
1502 *
1503 * Unless required by applicable law or agreed to in writing, software
1504 * distributed under the License is distributed on an "AS IS" BASIS,
1505 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1506 * See the License for the specific language governing permissions and
1507 * limitations under the License.
1508 *
1509 * @providesModule DefaultDOMPropertyConfig
1510 */
1511
1512"use strict";
1513
1514var DOMProperty = require("./DOMProperty");
1515
1516var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;
1517var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY;
1518var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE;
1519var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS;
1520
1521var DefaultDOMPropertyConfig = {
1522 isCustomAttribute: RegExp.prototype.test.bind(
1523 /^(data|aria)-[a-z_][a-z\d_.\-]*$/
1524 ),
1525 Properties: {
1526 /**
1527 * Standard Properties
1528 */
1529 accessKey: null,
1530 accept: null,
1531 action: null,
1532 ajaxify: MUST_USE_ATTRIBUTE,
1533 allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
1534 allowTransparency: MUST_USE_ATTRIBUTE,
1535 alt: null,
1536 autoComplete: null,
1537 autoFocus: HAS_BOOLEAN_VALUE,
1538 autoPlay: HAS_BOOLEAN_VALUE,
1539 cellPadding: null,
1540 cellSpacing: null,
1541 charSet: MUST_USE_ATTRIBUTE,
1542 checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
1543 className: MUST_USE_PROPERTY,
1544 colSpan: null,
1545 content: null,
1546 contentEditable: null,
1547 contextMenu: MUST_USE_ATTRIBUTE,
1548 controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
1549 data: null, // For `<object />` acts as `src`.
1550 dateTime: MUST_USE_ATTRIBUTE,
1551 dir: null,
1552 disabled: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
1553 draggable: null,
1554 encType: null,
1555 form: MUST_USE_ATTRIBUTE,
1556 frameBorder: MUST_USE_ATTRIBUTE,
1557 height: MUST_USE_ATTRIBUTE,
1558 hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
1559 href: null,
1560 htmlFor: null,
1561 httpEquiv: null,
1562 icon: null,
1563 id: MUST_USE_PROPERTY,
1564 label: null,
1565 lang: null,
1566 list: null,
1567 max: null,
1568 maxLength: MUST_USE_ATTRIBUTE,
1569 method: null,
1570 min: null,
1571 multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
1572 name: null,
1573 pattern: null,
1574 poster: null,
1575 preload: null,
1576 placeholder: null,
1577 radioGroup: null,
1578 rel: null,
1579 readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
1580 required: HAS_BOOLEAN_VALUE,
1581 role: MUST_USE_ATTRIBUTE,
1582 rowSpan: null,
1583 scrollLeft: MUST_USE_PROPERTY,
1584 scrollTop: MUST_USE_PROPERTY,
1585 selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
1586 size: null,
1587 spellCheck: null,
1588 src: null,
1589 step: null,
1590 style: null,
1591 tabIndex: null,
1592 target: null,
1593 title: null,
1594 type: null,
1595 value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS,
1596 width: MUST_USE_ATTRIBUTE,
1597 wmode: MUST_USE_ATTRIBUTE,
1598
1599 /**
1600 * Non-standard Properties
1601 */
1602 autoCapitalize: null, // Supported in Mobile Safari for keyboard hints
1603
1604 /**
1605 * SVG Properties
1606 */
1607 cx: MUST_USE_PROPERTY,
1608 cy: MUST_USE_PROPERTY,
1609 d: MUST_USE_PROPERTY,
1610 fill: MUST_USE_PROPERTY,
1611 fx: MUST_USE_PROPERTY,
1612 fy: MUST_USE_PROPERTY,
1613 points: MUST_USE_PROPERTY,
1614 r: MUST_USE_PROPERTY,
1615 stroke: MUST_USE_PROPERTY,
1616 strokeLinecap: MUST_USE_PROPERTY,
1617 strokeWidth: MUST_USE_PROPERTY,
1618 transform: MUST_USE_PROPERTY,
1619 x: MUST_USE_PROPERTY,
1620 x1: MUST_USE_PROPERTY,
1621 x2: MUST_USE_PROPERTY,
1622 version: MUST_USE_PROPERTY,
1623 viewBox: MUST_USE_PROPERTY,
1624 y: MUST_USE_PROPERTY,
1625 y1: MUST_USE_PROPERTY,
1626 y2: MUST_USE_PROPERTY,
1627 spreadMethod: MUST_USE_PROPERTY,
1628 offset: MUST_USE_PROPERTY,
1629 stopColor: MUST_USE_PROPERTY,
1630 stopOpacity: MUST_USE_PROPERTY,
1631 gradientUnits: MUST_USE_PROPERTY,
1632 gradientTransform: MUST_USE_PROPERTY
1633 },
1634 DOMAttributeNames: {
1635 className: 'class',
1636 htmlFor: 'for',
1637 strokeLinecap: 'stroke-linecap',
1638 strokeWidth: 'stroke-width',
1639 stopColor: 'stop-color',
1640 stopOpacity: 'stop-opacity'
1641 },
1642 DOMPropertyNames: {
1643 autoCapitalize: 'autocapitalize',
1644 autoComplete: 'autocomplete',
1645 autoFocus: 'autofocus',
1646 autoPlay: 'autoplay',
1647 encType: 'enctype',
1648 radioGroup: 'radiogroup',
1649 spellCheck: 'spellcheck'
1650 },
1651 DOMMutationMethods: {
1652 /**
1653 * Setting `className` to null may cause it to be set to the string "null".
1654 *
1655 * @param {DOMElement} node
1656 * @param {*} value
1657 */
1658 className: function(node, value) {
1659 node.className = value || '';
1660 }
1661 }
1662};
1663
1664module.exports = DefaultDOMPropertyConfig;
1665
1666},{"./DOMProperty":7}],11:[function(require,module,exports){
1667/**
1668 * Copyright 2013 Facebook, Inc.
1669 *
1670 * Licensed under the Apache License, Version 2.0 (the "License");
1671 * you may not use this file except in compliance with the License.
1672 * You may obtain a copy of the License at
1673 *
1674 * http://www.apache.org/licenses/LICENSE-2.0
1675 *
1676 * Unless required by applicable law or agreed to in writing, software
1677 * distributed under the License is distributed on an "AS IS" BASIS,
1678 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1679 * See the License for the specific language governing permissions and
1680 * limitations under the License.
1681 *
1682 * @providesModule DefaultEventPluginOrder
1683 */
1684
1685"use strict";
1686
1687 var keyOf = require("./keyOf");
1688
1689/**
1690 * Module that is injectable into `EventPluginHub`, that specifies a
1691 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
1692 * plugins, without having to package every one of them. This is better than
1693 * having plugins be ordered in the same order that they are injected because
1694 * that ordering would be influenced by the packaging order.
1695 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
1696 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
1697 */
1698var DefaultEventPluginOrder = [
1699 keyOf({ResponderEventPlugin: null}),
1700 keyOf({SimpleEventPlugin: null}),
1701 keyOf({TapEventPlugin: null}),
1702 keyOf({EnterLeaveEventPlugin: null}),
1703 keyOf({ChangeEventPlugin: null}),
1704 keyOf({AnalyticsEventPlugin: null}),
1705 keyOf({MobileSafariClickEventPlugin: null})
1706];
1707
1708module.exports = DefaultEventPluginOrder;
1709
1710},{"./keyOf":93}],12:[function(require,module,exports){
1711/**
1712 * Copyright 2013 Facebook, Inc.
1713 *
1714 * Licensed under the Apache License, Version 2.0 (the "License");
1715 * you may not use this file except in compliance with the License.
1716 * You may obtain a copy of the License at
1717 *
1718 * http://www.apache.org/licenses/LICENSE-2.0
1719 *
1720 * Unless required by applicable law or agreed to in writing, software
1721 * distributed under the License is distributed on an "AS IS" BASIS,
1722 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1723 * See the License for the specific language governing permissions and
1724 * limitations under the License.
1725 *
1726 * @providesModule EnterLeaveEventPlugin
1727 * @typechecks static-only
1728 */
1729
1730"use strict";
1731
1732var EventConstants = require("./EventConstants");
1733var EventPropagators = require("./EventPropagators");
1734var SyntheticMouseEvent = require("./SyntheticMouseEvent");
1735
1736var ReactMount = require("./ReactMount");
1737var keyOf = require("./keyOf");
1738
1739var topLevelTypes = EventConstants.topLevelTypes;
1740var getFirstReactDOM = ReactMount.getFirstReactDOM;
1741
1742var eventTypes = {
1743 mouseEnter: {registrationName: keyOf({onMouseEnter: null})},
1744 mouseLeave: {registrationName: keyOf({onMouseLeave: null})}
1745};
1746
1747var extractedEvents = [null, null];
1748
1749var EnterLeaveEventPlugin = {
1750
1751 eventTypes: eventTypes,
1752
1753 /**
1754 * For almost every interaction we care about, there will be both a top-level
1755 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
1756 * we do not extract duplicate events. However, moving the mouse into the
1757 * browser from outside will not fire a `mouseout` event. In this case, we use
1758 * the `mouseover` top-level event.
1759 *
1760 * @param {string} topLevelType Record from `EventConstants`.
1761 * @param {DOMEventTarget} topLevelTarget The listening component root node.
1762 * @param {string} topLevelTargetID ID of `topLevelTarget`.
1763 * @param {object} nativeEvent Native browser event.
1764 * @return {*} An accumulation of synthetic events.
1765 * @see {EventPluginHub.extractEvents}
1766 */
1767 extractEvents: function(
1768 topLevelType,
1769 topLevelTarget,
1770 topLevelTargetID,
1771 nativeEvent) {
1772 if (topLevelType === topLevelTypes.topMouseOver &&
1773 (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
1774 return null;
1775 }
1776 if (topLevelType !== topLevelTypes.topMouseOut &&
1777 topLevelType !== topLevelTypes.topMouseOver) {
1778 // Must not be a mouse in or mouse out - ignoring.
1779 return null;
1780 }
1781
1782 var from, to;
1783 if (topLevelType === topLevelTypes.topMouseOut) {
1784 from = topLevelTarget;
1785 to =
1786 getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) ||
1787 window;
1788 } else {
1789 from = window;
1790 to = topLevelTarget;
1791 }
1792
1793 if (from === to) {
1794 // Nothing pertains to our managed components.
1795 return null;
1796 }
1797
1798 var fromID = from ? ReactMount.getID(from) : '';
1799 var toID = to ? ReactMount.getID(to) : '';
1800
1801 var leave = SyntheticMouseEvent.getPooled(
1802 eventTypes.mouseLeave,
1803 fromID,
1804 nativeEvent
1805 );
1806 var enter = SyntheticMouseEvent.getPooled(
1807 eventTypes.mouseEnter,
1808 toID,
1809 nativeEvent
1810 );
1811
1812 EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID);
1813
1814 extractedEvents[0] = leave;
1815 extractedEvents[1] = enter;
1816
1817 return extractedEvents;
1818 }
1819
1820};
1821
1822module.exports = EnterLeaveEventPlugin;
1823
1824},{"./EventConstants":13,"./EventPropagators":18,"./ReactMount":45,"./SyntheticMouseEvent":63,"./keyOf":93}],13:[function(require,module,exports){
1825/**
1826 * Copyright 2013 Facebook, Inc.
1827 *
1828 * Licensed under the Apache License, Version 2.0 (the "License");
1829 * you may not use this file except in compliance with the License.
1830 * You may obtain a copy of the License at
1831 *
1832 * http://www.apache.org/licenses/LICENSE-2.0
1833 *
1834 * Unless required by applicable law or agreed to in writing, software
1835 * distributed under the License is distributed on an "AS IS" BASIS,
1836 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1837 * See the License for the specific language governing permissions and
1838 * limitations under the License.
1839 *
1840 * @providesModule EventConstants
1841 */
1842
1843"use strict";
1844
1845var keyMirror = require("./keyMirror");
1846
1847var PropagationPhases = keyMirror({bubbled: null, captured: null});
1848
1849/**
1850 * Types of raw signals from the browser caught at the top level.
1851 */
1852var topLevelTypes = keyMirror({
1853 topBlur: null,
1854 topChange: null,
1855 topClick: null,
1856 topCopy: null,
1857 topCut: null,
1858 topDOMCharacterDataModified: null,
1859 topDoubleClick: null,
1860 topDrag: null,
1861 topDragEnd: null,
1862 topDragEnter: null,
1863 topDragExit: null,
1864 topDragLeave: null,
1865 topDragOver: null,
1866 topDragStart: null,
1867 topDrop: null,
1868 topFocus: null,
1869 topInput: null,
1870 topKeyDown: null,
1871 topKeyPress: null,
1872 topKeyUp: null,
1873 topMouseDown: null,
1874 topMouseMove: null,
1875 topMouseOut: null,
1876 topMouseOver: null,
1877 topMouseUp: null,
1878 topPaste: null,
1879 topScroll: null,
1880 topSelectionChange: null,
1881 topSubmit: null,
1882 topTouchCancel: null,
1883 topTouchEnd: null,
1884 topTouchMove: null,
1885 topTouchStart: null,
1886 topWheel: null
1887});
1888
1889var EventConstants = {
1890 topLevelTypes: topLevelTypes,
1891 PropagationPhases: PropagationPhases
1892};
1893
1894module.exports = EventConstants;
1895
1896},{"./keyMirror":92}],14:[function(require,module,exports){
1897/**
1898 * Copyright 2013 Facebook, Inc.
1899 *
1900 * Licensed under the Apache License, Version 2.0 (the "License");
1901 * you may not use this file except in compliance with the License.
1902 * You may obtain a copy of the License at
1903 *
1904 * http://www.apache.org/licenses/LICENSE-2.0
1905 *
1906 * Unless required by applicable law or agreed to in writing, software
1907 * distributed under the License is distributed on an "AS IS" BASIS,
1908 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1909 * See the License for the specific language governing permissions and
1910 * limitations under the License.
1911 *
1912 * @providesModule EventListener
1913 */
1914
1915/**
1916 * Upstream version of event listener. Does not take into account specific
1917 * nature of platform.
1918 */
1919var EventListener = {
1920 /**
1921 * Listens to bubbled events on a DOM node.
1922 *
1923 * @param {Element} el DOM element to register listener on.
1924 * @param {string} handlerBaseName 'click'/'mouseover'
1925 * @param {Function!} cb Callback function
1926 */
1927 listen: function(el, handlerBaseName, cb) {
1928 if (el.addEventListener) {
1929 el.addEventListener(handlerBaseName, cb, false);
1930 } else if (el.attachEvent) {
1931 el.attachEvent('on' + handlerBaseName, cb);
1932 }
1933 },
1934
1935 /**
1936 * Listens to captured events on a DOM node.
1937 *
1938 * @see `EventListener.listen` for params.
1939 * @throws Exception if addEventListener is not supported.
1940 */
1941 capture: function(el, handlerBaseName, cb) {
1942 if (!el.addEventListener) {
1943 if (true) {
1944 console.error(
1945 'You are attempting to use addEventlistener ' +
1946 'in a browser that does not support it support it.' +
1947 'This likely means that you will not receive events that ' +
1948 'your application relies on (such as scroll).');
1949 }
1950 return;
1951 } else {
1952 el.addEventListener(handlerBaseName, cb, true);
1953 }
1954 }
1955};
1956
1957module.exports = EventListener;
1958
1959},{}],15:[function(require,module,exports){
1960/**
1961 * Copyright 2013 Facebook, Inc.
1962 *
1963 * Licensed under the Apache License, Version 2.0 (the "License");
1964 * you may not use this file except in compliance with the License.
1965 * You may obtain a copy of the License at
1966 *
1967 * http://www.apache.org/licenses/LICENSE-2.0
1968 *
1969 * Unless required by applicable law or agreed to in writing, software
1970 * distributed under the License is distributed on an "AS IS" BASIS,
1971 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1972 * See the License for the specific language governing permissions and
1973 * limitations under the License.
1974 *
1975 * @providesModule EventPluginHub
1976 */
1977
1978"use strict";
1979
1980var CallbackRegistry = require("./CallbackRegistry");
1981var EventPluginRegistry = require("./EventPluginRegistry");
1982var EventPluginUtils = require("./EventPluginUtils");
1983var EventPropagators = require("./EventPropagators");
1984var ExecutionEnvironment = require("./ExecutionEnvironment");
1985
1986var accumulate = require("./accumulate");
1987var forEachAccumulated = require("./forEachAccumulated");
1988var invariant = require("./invariant");
1989
1990/**
1991 * Internal queue of events that have accumulated their dispatches and are
1992 * waiting to have their dispatches executed.
1993 */
1994var eventQueue = null;
1995
1996/**
1997 * Dispatches an event and releases it back into the pool, unless persistent.
1998 *
1999 * @param {?object} event Synthetic event to be dispatched.
2000 * @private
2001 */
2002var executeDispatchesAndRelease = function(event) {
2003 if (event) {
2004 var executeDispatch = EventPluginUtils.executeDispatch;
2005 // Plugins can provide custom behavior when dispatching events.
2006 var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event);
2007 if (PluginModule && PluginModule.executeDispatch) {
2008 executeDispatch = PluginModule.executeDispatch;
2009 }
2010 EventPluginUtils.executeDispatchesInOrder(event, executeDispatch);
2011
2012 if (!event.isPersistent()) {
2013 event.constructor.release(event);
2014 }
2015 }
2016};
2017
2018/**
2019 * This is a unified interface for event plugins to be installed and configured.
2020 *
2021 * Event plugins can implement the following properties:
2022 *
2023 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
2024 * Required. When a top-level event is fired, this method is expected to
2025 * extract synthetic events that will in turn be queued and dispatched.
2026 *
2027 * `eventTypes` {object}
2028 * Optional, plugins that fire events must publish a mapping of registration
2029 * names that are used to register listeners. Values of this mapping must
2030 * be objects that contain `registrationName` or `phasedRegistrationNames`.
2031 *
2032 * `executeDispatch` {function(object, function, string)}
2033 * Optional, allows plugins to override how an event gets dispatched. By
2034 * default, the listener is simply invoked.
2035 *
2036 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
2037 *
2038 * @public
2039 */
2040var EventPluginHub = {
2041
2042 /**
2043 * Methods for injecting dependencies.
2044 */
2045 injection: {
2046
2047 /**
2048 * @param {object} InjectedInstanceHandle
2049 * @public
2050 */
2051 injectInstanceHandle: EventPropagators.injection.injectInstanceHandle,
2052
2053 /**
2054 * @param {array} InjectedEventPluginOrder
2055 * @public
2056 */
2057 injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,
2058
2059 /**
2060 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
2061 */
2062 injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName
2063
2064 },
2065
2066 registrationNames: EventPluginRegistry.registrationNames,
2067
2068 putListener: CallbackRegistry.putListener,
2069
2070 getListener: CallbackRegistry.getListener,
2071
2072 deleteListener: CallbackRegistry.deleteListener,
2073
2074 deleteAllListeners: CallbackRegistry.deleteAllListeners,
2075
2076 /**
2077 * Allows registered plugins an opportunity to extract events from top-level
2078 * native browser events.
2079 *
2080 * @param {string} topLevelType Record from `EventConstants`.
2081 * @param {DOMEventTarget} topLevelTarget The listening component root node.
2082 * @param {string} topLevelTargetID ID of `topLevelTarget`.
2083 * @param {object} nativeEvent Native browser event.
2084 * @return {*} An accumulation of synthetic events.
2085 * @internal
2086 */
2087 extractEvents: function(
2088 topLevelType,
2089 topLevelTarget,
2090 topLevelTargetID,
2091 nativeEvent) {
2092 var events;
2093 var plugins = EventPluginRegistry.plugins;
2094 for (var i = 0, l = plugins.length; i < l; i++) {
2095 // Not every plugin in the ordering may be loaded at runtime.
2096 var possiblePlugin = plugins[i];
2097 if (possiblePlugin) {
2098 var extractedEvents = possiblePlugin.extractEvents(
2099 topLevelType,
2100 topLevelTarget,
2101 topLevelTargetID,
2102 nativeEvent
2103 );
2104 if (extractedEvents) {
2105 events = accumulate(events, extractedEvents);
2106 }
2107 }
2108 }
2109 return events;
2110 },
2111
2112 /**
2113 * Enqueues a synthetic event that should be dispatched when
2114 * `processEventQueue` is invoked.
2115 *
2116 * @param {*} events An accumulation of synthetic events.
2117 * @internal
2118 */
2119 enqueueEvents: function(events) {
2120 if (events) {
2121 eventQueue = accumulate(eventQueue, events);
2122 }
2123 },
2124
2125 /**
2126 * Dispatches all synthetic events on the event queue.
2127 *
2128 * @internal
2129 */
2130 processEventQueue: function() {
2131 // Set `eventQueue` to null before processing it so that we can tell if more
2132 // events get enqueued while processing.
2133 var processingEventQueue = eventQueue;
2134 eventQueue = null;
2135 forEachAccumulated(processingEventQueue, executeDispatchesAndRelease);
2136 invariant(
2137 !eventQueue,
2138 'processEventQueue(): Additional events were enqueued while processing ' +
2139 'an event queue. Support for this has not yet been implemented.'
2140 );
2141 }
2142
2143};
2144
2145if (ExecutionEnvironment.canUseDOM) {
2146 window.EventPluginHub = EventPluginHub;
2147}
2148
2149module.exports = EventPluginHub;
2150
2151},{"./CallbackRegistry":4,"./EventPluginRegistry":16,"./EventPluginUtils":17,"./EventPropagators":18,"./ExecutionEnvironment":19,"./accumulate":70,"./forEachAccumulated":82,"./invariant":89}],16:[function(require,module,exports){
2152/**
2153 * Copyright 2013 Facebook, Inc.
2154 *
2155 * Licensed under the Apache License, Version 2.0 (the "License");
2156 * you may not use this file except in compliance with the License.
2157 * You may obtain a copy of the License at
2158 *
2159 * http://www.apache.org/licenses/LICENSE-2.0
2160 *
2161 * Unless required by applicable law or agreed to in writing, software
2162 * distributed under the License is distributed on an "AS IS" BASIS,
2163 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2164 * See the License for the specific language governing permissions and
2165 * limitations under the License.
2166 *
2167 * @providesModule EventPluginRegistry
2168 * @typechecks static-only
2169 */
2170
2171"use strict";
2172
2173var invariant = require("./invariant");
2174
2175/**
2176 * Injectable ordering of event plugins.
2177 */
2178var EventPluginOrder = null;
2179
2180/**
2181 * Injectable mapping from names to event plugin modules.
2182 */
2183var namesToPlugins = {};
2184
2185/**
2186 * Recomputes the plugin list using the injected plugins and plugin ordering.
2187 *
2188 * @private
2189 */
2190function recomputePluginOrdering() {
2191 if (!EventPluginOrder) {
2192 // Wait until an `EventPluginOrder` is injected.
2193 return;
2194 }
2195 for (var pluginName in namesToPlugins) {
2196 var PluginModule = namesToPlugins[pluginName];
2197 var pluginIndex = EventPluginOrder.indexOf(pluginName);
2198 invariant(
2199 pluginIndex > -1,
2200 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' +
2201 'the plugin ordering, `%s`.',
2202 pluginName
2203 );
2204 if (EventPluginRegistry.plugins[pluginIndex]) {
2205 continue;
2206 }
2207 invariant(
2208 PluginModule.extractEvents,
2209 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +
2210 'method, but `%s` does not.',
2211 pluginName
2212 );
2213 EventPluginRegistry.plugins[pluginIndex] = PluginModule;
2214 var publishedEvents = PluginModule.eventTypes;
2215 for (var eventName in publishedEvents) {
2216 invariant(
2217 publishEventForPlugin(publishedEvents[eventName], PluginModule),
2218 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.',
2219 eventName,
2220 pluginName
2221 );
2222 }
2223 }
2224}
2225
2226/**
2227 * Publishes an event so that it can be dispatched by the supplied plugin.
2228 *
2229 * @param {object} dispatchConfig Dispatch configuration for the event.
2230 * @param {object} PluginModule Plugin publishing the event.
2231 * @return {boolean} True if the event was successfully published.
2232 * @private
2233 */
2234function publishEventForPlugin(dispatchConfig, PluginModule) {
2235 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
2236 if (phasedRegistrationNames) {
2237 for (var phaseName in phasedRegistrationNames) {
2238 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
2239 var phasedRegistrationName = phasedRegistrationNames[phaseName];
2240 publishRegistrationName(phasedRegistrationName, PluginModule);
2241 }
2242 }
2243 return true;
2244 } else if (dispatchConfig.registrationName) {
2245 publishRegistrationName(dispatchConfig.registrationName, PluginModule);
2246 return true;
2247 }
2248 return false;
2249}
2250
2251/**
2252 * Publishes a registration name that is used to identify dispatched events and
2253 * can be used with `EventPluginHub.putListener` to register listeners.
2254 *
2255 * @param {string} registrationName Registration name to add.
2256 * @param {object} PluginModule Plugin publishing the event.
2257 * @private
2258 */
2259function publishRegistrationName(registrationName, PluginModule) {
2260 invariant(
2261 !EventPluginRegistry.registrationNames[registrationName],
2262 'EventPluginHub: More than one plugin attempted to publish the same ' +
2263 'registration name, `%s`.',
2264 registrationName
2265 );
2266 EventPluginRegistry.registrationNames[registrationName] = PluginModule;
2267 EventPluginRegistry.registrationNamesKeys.push(registrationName);
2268}
2269
2270/**
2271 * Registers plugins so that they can extract and dispatch events.
2272 *
2273 * @see {EventPluginHub}
2274 */
2275var EventPluginRegistry = {
2276
2277 /**
2278 * Ordered list of injected plugins.
2279 */
2280 plugins: [],
2281
2282 /**
2283 * Mapping from registration names to plugin modules.
2284 */
2285 registrationNames: {},
2286
2287 /**
2288 * The keys of `registrationNames`.
2289 */
2290 registrationNamesKeys: [],
2291
2292 /**
2293 * Injects an ordering of plugins (by plugin name). This allows the ordering
2294 * to be decoupled from injection of the actual plugins so that ordering is
2295 * always deterministic regardless of packaging, on-the-fly injection, etc.
2296 *
2297 * @param {array} InjectedEventPluginOrder
2298 * @internal
2299 * @see {EventPluginHub.injection.injectEventPluginOrder}
2300 */
2301 injectEventPluginOrder: function(InjectedEventPluginOrder) {
2302 invariant(
2303 !EventPluginOrder,
2304 'EventPluginRegistry: Cannot inject event plugin ordering more than once.'
2305 );
2306 // Clone the ordering so it cannot be dynamically mutated.
2307 EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);
2308 recomputePluginOrdering();
2309 },
2310
2311 /**
2312 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
2313 * in the ordering injected by `injectEventPluginOrder`.
2314 *
2315 * Plugins can be injected as part of page initialization or on-the-fly.
2316 *
2317 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
2318 * @internal
2319 * @see {EventPluginHub.injection.injectEventPluginsByName}
2320 */
2321 injectEventPluginsByName: function(injectedNamesToPlugins) {
2322 var isOrderingDirty = false;
2323 for (var pluginName in injectedNamesToPlugins) {
2324 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
2325 continue;
2326 }
2327 var PluginModule = injectedNamesToPlugins[pluginName];
2328 if (namesToPlugins[pluginName] !== PluginModule) {
2329 invariant(
2330 !namesToPlugins[pluginName],
2331 'EventPluginRegistry: Cannot inject two different event plugins ' +
2332 'using the same name, `%s`.',
2333 pluginName
2334 );
2335 namesToPlugins[pluginName] = PluginModule;
2336 isOrderingDirty = true;
2337 }
2338 }
2339 if (isOrderingDirty) {
2340 recomputePluginOrdering();
2341 }
2342 },
2343
2344 /**
2345 * Looks up the plugin for the supplied event.
2346 *
2347 * @param {object} event A synthetic event.
2348 * @return {?object} The plugin that created the supplied event.
2349 * @internal
2350 */
2351 getPluginModuleForEvent: function(event) {
2352 var dispatchConfig = event.dispatchConfig;
2353 if (dispatchConfig.registrationName) {
2354 return EventPluginRegistry.registrationNames[
2355 dispatchConfig.registrationName
2356 ] || null;
2357 }
2358 for (var phase in dispatchConfig.phasedRegistrationNames) {
2359 if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) {
2360 continue;
2361 }
2362 var PluginModule = EventPluginRegistry.registrationNames[
2363 dispatchConfig.phasedRegistrationNames[phase]
2364 ];
2365 if (PluginModule) {
2366 return PluginModule;
2367 }
2368 }
2369 return null;
2370 },
2371
2372 /**
2373 * Exposed for unit testing.
2374 * @private
2375 */
2376 _resetEventPlugins: function() {
2377 EventPluginOrder = null;
2378 for (var pluginName in namesToPlugins) {
2379 if (namesToPlugins.hasOwnProperty(pluginName)) {
2380 delete namesToPlugins[pluginName];
2381 }
2382 }
2383 EventPluginRegistry.plugins.length = 0;
2384 var registrationNames = EventPluginRegistry.registrationNames;
2385 for (var registrationName in registrationNames) {
2386 if (registrationNames.hasOwnProperty(registrationName)) {
2387 delete registrationNames[registrationName];
2388 }
2389 }
2390 EventPluginRegistry.registrationNamesKeys.length = 0;
2391 }
2392
2393};
2394
2395module.exports = EventPluginRegistry;
2396
2397},{"./invariant":89}],17:[function(require,module,exports){
2398/**
2399 * Copyright 2013 Facebook, Inc.
2400 *
2401 * Licensed under the Apache License, Version 2.0 (the "License");
2402 * you may not use this file except in compliance with the License.
2403 * You may obtain a copy of the License at
2404 *
2405 * http://www.apache.org/licenses/LICENSE-2.0
2406 *
2407 * Unless required by applicable law or agreed to in writing, software
2408 * distributed under the License is distributed on an "AS IS" BASIS,
2409 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2410 * See the License for the specific language governing permissions and
2411 * limitations under the License.
2412 *
2413 * @providesModule EventPluginUtils
2414 */
2415
2416"use strict";
2417
2418var EventConstants = require("./EventConstants");
2419
2420var invariant = require("./invariant");
2421
2422var topLevelTypes = EventConstants.topLevelTypes;
2423
2424function isEndish(topLevelType) {
2425 return topLevelType === topLevelTypes.topMouseUp ||
2426 topLevelType === topLevelTypes.topTouchEnd ||
2427 topLevelType === topLevelTypes.topTouchCancel;
2428}
2429
2430function isMoveish(topLevelType) {
2431 return topLevelType === topLevelTypes.topMouseMove ||
2432 topLevelType === topLevelTypes.topTouchMove;
2433}
2434function isStartish(topLevelType) {
2435 return topLevelType === topLevelTypes.topMouseDown ||
2436 topLevelType === topLevelTypes.topTouchStart;
2437}
2438
2439var validateEventDispatches;
2440if (true) {
2441 validateEventDispatches = function(event) {
2442 var dispatchListeners = event._dispatchListeners;
2443 var dispatchIDs = event._dispatchIDs;
2444
2445 var listenersIsArr = Array.isArray(dispatchListeners);
2446 var idsIsArr = Array.isArray(dispatchIDs);
2447 var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0;
2448 var listenersLen = listenersIsArr ?
2449 dispatchListeners.length :
2450 dispatchListeners ? 1 : 0;
2451
2452 invariant(
2453 idsIsArr === listenersIsArr && IDsLen === listenersLen,
2454 'EventPluginUtils: Invalid `event`.'
2455 );
2456 };
2457}
2458
2459/**
2460 * Invokes `cb(event, listener, id)`. Avoids using call if no scope is
2461 * provided. The `(listener,id)` pair effectively forms the "dispatch" but are
2462 * kept separate to conserve memory.
2463 */
2464function forEachEventDispatch(event, cb) {
2465 var dispatchListeners = event._dispatchListeners;
2466 var dispatchIDs = event._dispatchIDs;
2467 if (true) {
2468 validateEventDispatches(event);
2469 }
2470 if (Array.isArray(dispatchListeners)) {
2471 for (var i = 0; i < dispatchListeners.length; i++) {
2472 if (event.isPropagationStopped()) {
2473 break;
2474 }
2475 // Listeners and IDs are two parallel arrays that are always in sync.
2476 cb(event, dispatchListeners[i], dispatchIDs[i]);
2477 }
2478 } else if (dispatchListeners) {
2479 cb(event, dispatchListeners, dispatchIDs);
2480 }
2481}
2482
2483/**
2484 * Default implementation of PluginModule.executeDispatch().
2485 * @param {SyntheticEvent} SyntheticEvent to handle
2486 * @param {function} Application-level callback
2487 * @param {string} domID DOM id to pass to the callback.
2488 */
2489function executeDispatch(event, listener, domID) {
2490 listener(event, domID);
2491}
2492
2493/**
2494 * Standard/simple iteration through an event's collected dispatches.
2495 */
2496function executeDispatchesInOrder(event, executeDispatch) {
2497 forEachEventDispatch(event, executeDispatch);
2498 event._dispatchListeners = null;
2499 event._dispatchIDs = null;
2500}
2501
2502/**
2503 * Standard/simple iteration through an event's collected dispatches, but stops
2504 * at the first dispatch execution returning true, and returns that id.
2505 *
2506 * @return id of the first dispatch execution who's listener returns true, or
2507 * null if no listener returned true.
2508 */
2509function executeDispatchesInOrderStopAtTrue(event) {
2510 var dispatchListeners = event._dispatchListeners;
2511 var dispatchIDs = event._dispatchIDs;
2512 if (true) {
2513 validateEventDispatches(event);
2514 }
2515 if (Array.isArray(dispatchListeners)) {
2516 for (var i = 0; i < dispatchListeners.length; i++) {
2517 if (event.isPropagationStopped()) {
2518 break;
2519 }
2520 // Listeners and IDs are two parallel arrays that are always in sync.
2521 if (dispatchListeners[i](event, dispatchIDs[i])) {
2522 return dispatchIDs[i];
2523 }
2524 }
2525 } else if (dispatchListeners) {
2526 if (dispatchListeners(event, dispatchIDs)) {
2527 return dispatchIDs;
2528 }
2529 }
2530 return null;
2531}
2532
2533/**
2534 * Execution of a "direct" dispatch - there must be at most one dispatch
2535 * accumulated on the event or it is considered an error. It doesn't really make
2536 * sense for an event with multiple dispatches (bubbled) to keep track of the
2537 * return values at each dispatch execution, but it does tend to make sense when
2538 * dealing with "direct" dispatches.
2539 *
2540 * @return The return value of executing the single dispatch.
2541 */
2542function executeDirectDispatch(event) {
2543 if (true) {
2544 validateEventDispatches(event);
2545 }
2546 var dispatchListener = event._dispatchListeners;
2547 var dispatchID = event._dispatchIDs;
2548 invariant(
2549 !Array.isArray(dispatchListener),
2550 'executeDirectDispatch(...): Invalid `event`.'
2551 );
2552 var res = dispatchListener ?
2553 dispatchListener(event, dispatchID) :
2554 null;
2555 event._dispatchListeners = null;
2556 event._dispatchIDs = null;
2557 return res;
2558}
2559
2560/**
2561 * @param {SyntheticEvent} event
2562 * @return {bool} True iff number of dispatches accumulated is greater than 0.
2563 */
2564function hasDispatches(event) {
2565 return !!event._dispatchListeners;
2566}
2567
2568/**
2569 * General utilities that are useful in creating custom Event Plugins.
2570 */
2571var EventPluginUtils = {
2572 isEndish: isEndish,
2573 isMoveish: isMoveish,
2574 isStartish: isStartish,
2575 executeDispatchesInOrder: executeDispatchesInOrder,
2576 executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,
2577 executeDirectDispatch: executeDirectDispatch,
2578 hasDispatches: hasDispatches,
2579 executeDispatch: executeDispatch
2580};
2581
2582module.exports = EventPluginUtils;
2583
2584},{"./EventConstants":13,"./invariant":89}],18:[function(require,module,exports){
2585/**
2586 * Copyright 2013 Facebook, Inc.
2587 *
2588 * Licensed under the Apache License, Version 2.0 (the "License");
2589 * you may not use this file except in compliance with the License.
2590 * You may obtain a copy of the License at
2591 *
2592 * http://www.apache.org/licenses/LICENSE-2.0
2593 *
2594 * Unless required by applicable law or agreed to in writing, software
2595 * distributed under the License is distributed on an "AS IS" BASIS,
2596 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2597 * See the License for the specific language governing permissions and
2598 * limitations under the License.
2599 *
2600 * @providesModule EventPropagators
2601 */
2602
2603"use strict";
2604
2605var CallbackRegistry = require("./CallbackRegistry");
2606var EventConstants = require("./EventConstants");
2607
2608var accumulate = require("./accumulate");
2609var forEachAccumulated = require("./forEachAccumulated");
2610var getListener = CallbackRegistry.getListener;
2611var PropagationPhases = EventConstants.PropagationPhases;
2612
2613/**
2614 * Injected dependencies:
2615 */
2616
2617/**
2618 * - `InstanceHandle`: [required] Module that performs logical traversals of DOM
2619 * hierarchy given ids of the logical DOM elements involved.
2620 */
2621var injection = {
2622 InstanceHandle: null,
2623 injectInstanceHandle: function(InjectedInstanceHandle) {
2624 injection.InstanceHandle = InjectedInstanceHandle;
2625 if (true) {
2626 injection.validate();
2627 }
2628 },
2629 validate: function() {
2630 var invalid = !injection.InstanceHandle||
2631 !injection.InstanceHandle.traverseTwoPhase ||
2632 !injection.InstanceHandle.traverseEnterLeave;
2633 if (invalid) {
2634 throw new Error('InstanceHandle not injected before use!');
2635 }
2636 }
2637};
2638
2639/**
2640 * Some event types have a notion of different registration names for different
2641 * "phases" of propagation. This finds listeners by a given phase.
2642 */
2643function listenerAtPhase(id, event, propagationPhase) {
2644 var registrationName =
2645 event.dispatchConfig.phasedRegistrationNames[propagationPhase];
2646 return getListener(id, registrationName);
2647}
2648
2649/**
2650 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
2651 * here, allows us to not have to bind or create functions for each event.
2652 * Mutating the event's members allows us to not have to create a wrapping
2653 * "dispatch" object that pairs the event with the listener.
2654 */
2655function accumulateDirectionalDispatches(domID, upwards, event) {
2656 if (true) {
2657 if (!domID) {
2658 throw new Error('Dispatching id must not be null');
2659 }
2660 injection.validate();
2661 }
2662 var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured;
2663 var listener = listenerAtPhase(domID, event, phase);
2664 if (listener) {
2665 event._dispatchListeners = accumulate(event._dispatchListeners, listener);
2666 event._dispatchIDs = accumulate(event._dispatchIDs, domID);
2667 }
2668}
2669
2670/**
2671 * Collect dispatches (must be entirely collected before dispatching - see unit
2672 * tests). Lazily allocate the array to conserve memory. We must loop through
2673 * each event and perform the traversal for each one. We can not perform a
2674 * single traversal for the entire collection of events because each event may
2675 * have a different target.
2676 */
2677function accumulateTwoPhaseDispatchesSingle(event) {
2678 if (event && event.dispatchConfig.phasedRegistrationNames) {
2679 injection.InstanceHandle.traverseTwoPhase(
2680 event.dispatchMarker,
2681 accumulateDirectionalDispatches,
2682 event
2683 );
2684 }
2685}
2686
2687
2688/**
2689 * Accumulates without regard to direction, does not look for phased
2690 * registration names. Same as `accumulateDirectDispatchesSingle` but without
2691 * requiring that the `dispatchMarker` be the same as the dispatched ID.
2692 */
2693function accumulateDispatches(id, ignoredDirection, event) {
2694 if (event && event.dispatchConfig.registrationName) {
2695 var registrationName = event.dispatchConfig.registrationName;
2696 var listener = getListener(id, registrationName);
2697 if (listener) {
2698 event._dispatchListeners = accumulate(event._dispatchListeners, listener);
2699 event._dispatchIDs = accumulate(event._dispatchIDs, id);
2700 }
2701 }
2702}
2703
2704/**
2705 * Accumulates dispatches on an `SyntheticEvent`, but only for the
2706 * `dispatchMarker`.
2707 * @param {SyntheticEvent} event
2708 */
2709function accumulateDirectDispatchesSingle(event) {
2710 if (event && event.dispatchConfig.registrationName) {
2711 accumulateDispatches(event.dispatchMarker, null, event);
2712 }
2713}
2714
2715function accumulateTwoPhaseDispatches(events) {
2716 if (true) {
2717 injection.validate();
2718 }
2719 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
2720}
2721
2722function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) {
2723 if (true) {
2724 injection.validate();
2725 }
2726 injection.InstanceHandle.traverseEnterLeave(
2727 fromID,
2728 toID,
2729 accumulateDispatches,
2730 leave,
2731 enter
2732 );
2733}
2734
2735
2736function accumulateDirectDispatches(events) {
2737 if (true) {
2738 injection.validate();
2739 }
2740 forEachAccumulated(events, accumulateDirectDispatchesSingle);
2741}
2742
2743
2744
2745/**
2746 * A small set of propagation patterns, each of which will accept a small amount
2747 * of information, and generate a set of "dispatch ready event objects" - which
2748 * are sets of events that have already been annotated with a set of dispatched
2749 * listener functions/ids. The API is designed this way to discourage these
2750 * propagation strategies from actually executing the dispatches, since we
2751 * always want to collect the entire set of dispatches before executing event a
2752 * single one.
2753 *
2754 * @constructor EventPropagators
2755 */
2756var EventPropagators = {
2757 accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
2758 accumulateDirectDispatches: accumulateDirectDispatches,
2759 accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches,
2760 injection: injection
2761};
2762
2763module.exports = EventPropagators;
2764
2765},{"./CallbackRegistry":4,"./EventConstants":13,"./accumulate":70,"./forEachAccumulated":82}],19:[function(require,module,exports){
2766/**
2767 * Copyright 2013 Facebook, Inc.
2768 *
2769 * Licensed under the Apache License, Version 2.0 (the "License");
2770 * you may not use this file except in compliance with the License.
2771 * You may obtain a copy of the License at
2772 *
2773 * http://www.apache.org/licenses/LICENSE-2.0
2774 *
2775 * Unless required by applicable law or agreed to in writing, software
2776 * distributed under the License is distributed on an "AS IS" BASIS,
2777 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2778 * See the License for the specific language governing permissions and
2779 * limitations under the License.
2780 *
2781 * @providesModule ExecutionEnvironment
2782 */
2783
2784/*jslint evil: true */
2785
2786"use strict";
2787
2788var canUseDOM = typeof window !== 'undefined';
2789
2790/**
2791 * Simple, lightweight module assisting with the detection and context of
2792 * Worker. Helps avoid circular dependencies and allows code to reason about
2793 * whether or not they are in a Worker, even if they never include the main
2794 * `ReactWorker` dependency.
2795 */
2796var ExecutionEnvironment = {
2797
2798 canUseDOM: canUseDOM,
2799
2800 canUseWorkers: typeof Worker !== 'undefined',
2801
2802 isInWorker: !canUseDOM // For now, this is true - might change in the future.
2803
2804};
2805
2806module.exports = ExecutionEnvironment;
2807
2808},{}],20:[function(require,module,exports){
2809/**
2810 * Copyright 2013 Facebook, Inc.
2811 *
2812 * Licensed under the Apache License, Version 2.0 (the "License");
2813 * you may not use this file except in compliance with the License.
2814 * You may obtain a copy of the License at
2815 *
2816 * http://www.apache.org/licenses/LICENSE-2.0
2817 *
2818 * Unless required by applicable law or agreed to in writing, software
2819 * distributed under the License is distributed on an "AS IS" BASIS,
2820 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2821 * See the License for the specific language governing permissions and
2822 * limitations under the License.
2823 *
2824 * @providesModule MobileSafariClickEventPlugin
2825 * @typechecks static-only
2826 */
2827
2828"use strict";
2829
2830var EventConstants = require("./EventConstants");
2831
2832var emptyFunction = require("./emptyFunction");
2833
2834var topLevelTypes = EventConstants.topLevelTypes;
2835
2836/**
2837 * Mobile Safari does not fire properly bubble click events on non-interactive
2838 * elements, which means delegated click listeners do not fire. The workaround
2839 * for this bug involves attaching an empty click listener on the target node.
2840 *
2841 * This particular plugin works around the bug by attaching an empty click
2842 * listener on `touchstart` (which does fire on every element).
2843 */
2844var MobileSafariClickEventPlugin = {
2845
2846 eventTypes: null,
2847
2848 /**
2849 * @param {string} topLevelType Record from `EventConstants`.
2850 * @param {DOMEventTarget} topLevelTarget The listening component root node.
2851 * @param {string} topLevelTargetID ID of `topLevelTarget`.
2852 * @param {object} nativeEvent Native browser event.
2853 * @return {*} An accumulation of synthetic events.
2854 * @see {EventPluginHub.extractEvents}
2855 */
2856 extractEvents: function(
2857 topLevelType,
2858 topLevelTarget,
2859 topLevelTargetID,
2860 nativeEvent) {
2861 if (topLevelType === topLevelTypes.topTouchStart) {
2862 var target = nativeEvent.target;
2863 if (target && !target.onclick) {
2864 target.onclick = emptyFunction;
2865 }
2866 }
2867 }
2868
2869};
2870
2871module.exports = MobileSafariClickEventPlugin;
2872
2873},{"./EventConstants":13,"./emptyFunction":77}],21:[function(require,module,exports){
2874/**
2875 * Copyright 2013 Facebook, Inc.
2876 *
2877 * Licensed under the Apache License, Version 2.0 (the "License");
2878 * you may not use this file except in compliance with the License.
2879 * You may obtain a copy of the License at
2880 *
2881 * http://www.apache.org/licenses/LICENSE-2.0
2882 *
2883 * Unless required by applicable law or agreed to in writing, software
2884 * distributed under the License is distributed on an "AS IS" BASIS,
2885 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2886 * See the License for the specific language governing permissions and
2887 * limitations under the License.
2888 *
2889 * @providesModule PooledClass
2890 */
2891
2892"use strict";
2893
2894/**
2895 * Static poolers. Several custom versions for each potential number of
2896 * arguments. A completely generic pooler is easy to implement, but would
2897 * require accessing the `arguments` object. In each of these, `this` refers to
2898 * the Class itself, not an instance. If any others are needed, simply add them
2899 * here, or in their own files.
2900 */
2901var oneArgumentPooler = function(copyFieldsFrom) {
2902 var Klass = this;
2903 if (Klass.instancePool.length) {
2904 var instance = Klass.instancePool.pop();
2905 Klass.call(instance, copyFieldsFrom);
2906 return instance;
2907 } else {
2908 return new Klass(copyFieldsFrom);
2909 }
2910};
2911
2912var twoArgumentPooler = function(a1, a2) {
2913 var Klass = this;
2914 if (Klass.instancePool.length) {
2915 var instance = Klass.instancePool.pop();
2916 Klass.call(instance, a1, a2);
2917 return instance;
2918 } else {
2919 return new Klass(a1, a2);
2920 }
2921};
2922
2923var threeArgumentPooler = function(a1, a2, a3) {
2924 var Klass = this;
2925 if (Klass.instancePool.length) {
2926 var instance = Klass.instancePool.pop();
2927 Klass.call(instance, a1, a2, a3);
2928 return instance;
2929 } else {
2930 return new Klass(a1, a2, a3);
2931 }
2932};
2933
2934var fiveArgumentPooler = function(a1, a2, a3, a4, a5) {
2935 var Klass = this;
2936 if (Klass.instancePool.length) {
2937 var instance = Klass.instancePool.pop();
2938 Klass.call(instance, a1, a2, a3, a4, a5);
2939 return instance;
2940 } else {
2941 return new Klass(a1, a2, a3, a4, a5);
2942 }
2943};
2944
2945var standardReleaser = function(instance) {
2946 var Klass = this;
2947 if (instance.destructor) {
2948 instance.destructor();
2949 }
2950 if (Klass.instancePool.length < Klass.poolSize) {
2951 Klass.instancePool.push(instance);
2952 }
2953};
2954
2955var DEFAULT_POOL_SIZE = 10;
2956var DEFAULT_POOLER = oneArgumentPooler;
2957
2958/**
2959 * Augments `CopyConstructor` to be a poolable class, augmenting only the class
2960 * itself (statically) not adding any prototypical fields. Any CopyConstructor
2961 * you give this may have a `poolSize` property, and will look for a
2962 * prototypical `destructor` on instances (optional).
2963 *
2964 * @param {Function} CopyConstructor Constructor that can be used to reset.
2965 * @param {Function} pooler Customizable pooler.
2966 */
2967var addPoolingTo = function(CopyConstructor, pooler) {
2968 var NewKlass = CopyConstructor;
2969 NewKlass.instancePool = [];
2970 NewKlass.getPooled = pooler || DEFAULT_POOLER;
2971 if (!NewKlass.poolSize) {
2972 NewKlass.poolSize = DEFAULT_POOL_SIZE;
2973 }
2974 NewKlass.release = standardReleaser;
2975 return NewKlass;
2976};
2977
2978var PooledClass = {
2979 addPoolingTo: addPoolingTo,
2980 oneArgumentPooler: oneArgumentPooler,
2981 twoArgumentPooler: twoArgumentPooler,
2982 threeArgumentPooler: threeArgumentPooler,
2983 fiveArgumentPooler: fiveArgumentPooler
2984};
2985
2986module.exports = PooledClass;
2987
2988},{}],22:[function(require,module,exports){
2989/**
2990 * Copyright 2013 Facebook, Inc.
2991 *
2992 * Licensed under the Apache License, Version 2.0 (the "License");
2993 * you may not use this file except in compliance with the License.
2994 * You may obtain a copy of the License at
2995 *
2996 * http://www.apache.org/licenses/LICENSE-2.0
2997 *
2998 * Unless required by applicable law or agreed to in writing, software
2999 * distributed under the License is distributed on an "AS IS" BASIS,
3000 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3001 * See the License for the specific language governing permissions and
3002 * limitations under the License.
3003 *
3004 * @providesModule React
3005 */
3006
3007"use strict";
3008
3009var ReactCompositeComponent = require("./ReactCompositeComponent");
3010var ReactComponent = require("./ReactComponent");
3011var ReactDOM = require("./ReactDOM");
3012var ReactMount = require("./ReactMount");
3013var ReactPerf = require("./ReactPerf");
3014var ReactPropTypes = require("./ReactPropTypes");
3015var ReactServerRendering = require("./ReactServerRendering");
3016
3017var ReactDefaultInjection = require("./ReactDefaultInjection");
3018
3019ReactDefaultInjection.inject();
3020
3021var React = {
3022 DOM: ReactDOM,
3023 PropTypes: ReactPropTypes,
3024 initializeTouchEvents: function(shouldUseTouch) {
3025 ReactMount.useTouchEvents = shouldUseTouch;
3026 },
3027 createClass: ReactCompositeComponent.createClass,
3028 constructAndRenderComponent: ReactMount.constructAndRenderComponent,
3029 constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID,
3030 renderComponent: ReactPerf.measure(
3031 'React',
3032 'renderComponent',
3033 ReactMount.renderComponent
3034 ),
3035 renderComponentToString: ReactServerRendering.renderComponentToString,
3036 unmountAndReleaseReactRootNode: ReactMount.unmountAndReleaseReactRootNode,
3037 isValidClass: ReactCompositeComponent.isValidClass,
3038 isValidComponent: ReactComponent.isValidComponent
3039};
3040
3041// Version exists only in the open-source version of React, not in Facebook's
3042// internal version.
3043React.version = '0.5.0-alpha';
3044
3045module.exports = React;
3046
3047},{"./ReactComponent":23,"./ReactCompositeComponent":26,"./ReactDOM":28,"./ReactDefaultInjection":37,"./ReactMount":45,"./ReactPerf":51,"./ReactPropTypes":53,"./ReactServerRendering":55}],23:[function(require,module,exports){
3048/**
3049 * Copyright 2013 Facebook, Inc.
3050 *
3051 * Licensed under the Apache License, Version 2.0 (the "License");
3052 * you may not use this file except in compliance with the License.
3053 * You may obtain a copy of the License at
3054 *
3055 * http://www.apache.org/licenses/LICENSE-2.0
3056 *
3057 * Unless required by applicable law or agreed to in writing, software
3058 * distributed under the License is distributed on an "AS IS" BASIS,
3059 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3060 * See the License for the specific language governing permissions and
3061 * limitations under the License.
3062 *
3063 * @providesModule ReactComponent
3064 */
3065
3066"use strict";
3067
3068var ReactComponentEnvironment = require("./ReactComponentEnvironment");
3069var ReactCurrentOwner = require("./ReactCurrentOwner");
3070var ReactOwner = require("./ReactOwner");
3071var ReactUpdates = require("./ReactUpdates");
3072
3073var invariant = require("./invariant");
3074var keyMirror = require("./keyMirror");
3075var merge = require("./merge");
3076
3077/**
3078 * Prop key that references a component's owner.
3079 * @private
3080 */
3081var OWNER = '{owner}';
3082
3083/**
3084 * Props key that determines if a component's key was already validated.
3085 * @private
3086 */
3087var IS_KEY_VALIDATED = '{is.key.validated}';
3088
3089/**
3090 * Every React component is in one of these life cycles.
3091 */
3092var ComponentLifeCycle = keyMirror({
3093 /**
3094 * Mounted components have a DOM node representation and are capable of
3095 * receiving new props.
3096 */
3097 MOUNTED: null,
3098 /**
3099 * Unmounted components are inactive and cannot receive new props.
3100 */
3101 UNMOUNTED: null
3102});
3103
3104/**
3105 * Warn if there's no key explicitly set on dynamic arrays of children.
3106 * This allows us to keep track of children between updates.
3107 */
3108
3109var ownerHasWarned = {};
3110
3111/**
3112 * Warn if the component doesn't have an explicit key assigned to it.
3113 * This component is in an array. The array could grow and shrink or be
3114 * reordered. All children, that hasn't already been validated, are required to
3115 * have a "key" property assigned to it.
3116 *
3117 * @internal
3118 * @param {ReactComponent} component Component that requires a key.
3119 */
3120function validateExplicitKey(component) {
3121 if (component[IS_KEY_VALIDATED] || component.props.key != null) {
3122 return;
3123 }
3124 component[IS_KEY_VALIDATED] = true;
3125
3126 // We can't provide friendly warnings for top level components.
3127 if (!ReactCurrentOwner.current) {
3128 return;
3129 }
3130
3131 // Name of the component whose render method tried to pass children.
3132 var currentName = ReactCurrentOwner.current.constructor.displayName;
3133 if (ownerHasWarned.hasOwnProperty(currentName)) {
3134 return;
3135 }
3136 ownerHasWarned[currentName] = true;
3137
3138 var message = 'Each child in an array should have a unique "key" prop. ' +
3139 'Check the render method of ' + currentName + '.';
3140 if (!component.isOwnedBy(ReactCurrentOwner.current)) {
3141 // Name of the component that originally created this child.
3142 var childOwnerName =
3143 component.props[OWNER] && component.props[OWNER].constructor.displayName;
3144
3145 // Usually the current owner is the offender, but if it accepts
3146 // children as a property, it may be the creator of the child that's
3147 // responsible for assigning it a key.
3148 message += ' It was passed a child from ' + childOwnerName + '.';
3149 }
3150
3151 console.warn(message);
3152}
3153
3154/**
3155 * Ensure that every component either is passed in a static location or, if
3156 * if it's passed in an array, has an explicit key property defined.
3157 *
3158 * @internal
3159 * @param {*} component Statically passed child of any type.
3160 * @return {boolean}
3161 */
3162function validateChildKeys(component) {
3163 if (Array.isArray(component)) {
3164 for (var i = 0; i < component.length; i++) {
3165 var child = component[i];
3166 if (ReactComponent.isValidComponent(child)) {
3167 validateExplicitKey(child);
3168 }
3169 }
3170 } else if (ReactComponent.isValidComponent(component)) {
3171 // This component was passed in a valid location.
3172 component[IS_KEY_VALIDATED] = true;
3173 }
3174}
3175
3176/**
3177 * Components are the basic units of composition in React.
3178 *
3179 * Every component accepts a set of keyed input parameters known as "props" that
3180 * are initialized by the constructor. Once a component is mounted, the props
3181 * can be mutated using `setProps` or `replaceProps`.
3182 *
3183 * Every component is capable of the following operations:
3184 *
3185 * `mountComponent`
3186 * Initializes the component, renders markup, and registers event listeners.
3187 *
3188 * `receiveProps`
3189 * Updates the rendered DOM nodes given a new set of props.
3190 *
3191 * `unmountComponent`
3192 * Releases any resources allocated by this component.
3193 *
3194 * Components can also be "owned" by other components. Being owned by another
3195 * component means being constructed by that component. This is different from
3196 * being the child of a component, which means having a DOM representation that
3197 * is a child of the DOM representation of that component.
3198 *
3199 * @class ReactComponent
3200 */
3201var ReactComponent = {
3202
3203 /**
3204 * @param {?object} object
3205 * @return {boolean} True if `object` is a valid component.
3206 * @final
3207 */
3208 isValidComponent: function(object) {
3209 return !!(
3210 object &&
3211 typeof object.mountComponentIntoNode === 'function' &&
3212 typeof object.receiveProps === 'function'
3213 );
3214 },
3215
3216 /**
3217 * Generate a key string that identifies a component within a set.
3218 *
3219 * @param {*} component A component that could contain a manual key.
3220 * @param {number} index Index that is used if a manual key is not provided.
3221 * @return {string}
3222 * @internal
3223 */
3224 getKey: function(component, index) {
3225 if (component && component.props && component.props.key != null) {
3226 // Explicit key
3227 return '{' + component.props.key + '}';
3228 }
3229 // Implicit key determined by the index in the set
3230 return '[' + index + ']';
3231 },
3232
3233 /**
3234 * @internal
3235 */
3236 LifeCycle: ComponentLifeCycle,
3237
3238 /**
3239 * Injected module that provides ability to mutate individual properties.
3240 * Injected into the base class because many different subclasses need access
3241 * to this.
3242 *
3243 * @internal
3244 */
3245 DOMIDOperations: ReactComponentEnvironment.DOMIDOperations,
3246
3247 /**
3248 * Optionally injectable environment dependent cleanup hook. (server vs.
3249 * browser etc). Example: A browser system caches DOM nodes based on component
3250 * ID and must remove that cache entry when this instance is unmounted.
3251 *
3252 * @private
3253 */
3254 unmountIDFromEnvironment: ReactComponentEnvironment.unmountIDFromEnvironment,
3255
3256 /**
3257 * The "image" of a component tree, is the platform specific (typically
3258 * serialized) data that represents a tree of lower level UI building blocks.
3259 * On the web, this "image" is HTML markup which describes a construction of
3260 * low level `div` and `span` nodes. Other platforms may have different
3261 * encoding of this "image". This must be injected.
3262 *
3263 * @private
3264 */
3265 mountImageIntoNode: ReactComponentEnvironment.mountImageIntoNode,
3266
3267 /**
3268 * React references `ReactReconcileTransaction` using this property in order
3269 * to allow dependency injection.
3270 *
3271 * @internal
3272 */
3273 ReactReconcileTransaction:
3274 ReactComponentEnvironment.ReactReconcileTransaction,
3275
3276 /**
3277 * Base functionality for every ReactComponent constructor. Mixed into the
3278 * `ReactComponent` prototype, but exposed statically for easy access.
3279 *
3280 * @lends {ReactComponent.prototype}
3281 */
3282 Mixin: merge(ReactComponentEnvironment.Mixin, {
3283
3284 /**
3285 * Checks whether or not this component is mounted.
3286 *
3287 * @return {boolean} True if mounted, false otherwise.
3288 * @final
3289 * @protected
3290 */
3291 isMounted: function() {
3292 return this._lifeCycleState === ComponentLifeCycle.MOUNTED;
3293 },
3294
3295 /**
3296 * Sets a subset of the props.
3297 *
3298 * @param {object} partialProps Subset of the next props.
3299 * @param {?function} callback Called after props are updated.
3300 * @final
3301 * @public
3302 */
3303 setProps: function(partialProps, callback) {
3304 // Merge with `_pendingProps` if it exists, otherwise with existing props.
3305 this.replaceProps(
3306 merge(this._pendingProps || this.props, partialProps),
3307 callback
3308 );
3309 },
3310
3311 /**
3312 * Replaces all of the props.
3313 *
3314 * @param {object} props New props.
3315 * @param {?function} callback Called after props are updated.
3316 * @final
3317 * @public
3318 */
3319 replaceProps: function(props, callback) {
3320 invariant(
3321 !this.props[OWNER],
3322 'replaceProps(...): You called `setProps` or `replaceProps` on a ' +
3323 'component with an owner. This is an anti-pattern since props will ' +
3324 'get reactively updated when rendered. Instead, change the owner\'s ' +
3325 '`render` method to pass the correct value as props to the component ' +
3326 'where it is created.'
3327 );
3328 invariant(
3329 this.isMounted(),
3330 'replaceProps(...): Can only update a mounted component.'
3331 );
3332 this._pendingProps = props;
3333 ReactUpdates.enqueueUpdate(this, callback);
3334 },
3335
3336 /**
3337 * Base constructor for all React component.
3338 *
3339 * Subclasses that override this method should make sure to invoke
3340 * `ReactComponent.Mixin.construct.call(this, ...)`.
3341 *
3342 * @param {?object} initialProps
3343 * @param {*} children
3344 * @internal
3345 */
3346 construct: function(initialProps, children) {
3347 this.props = initialProps || {};
3348 // Record the component responsible for creating this component.
3349 this.props[OWNER] = ReactCurrentOwner.current;
3350 // All components start unmounted.
3351 this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
3352
3353 this._pendingProps = null;
3354 this._pendingCallbacks = null;
3355
3356 // Children can be more than one argument
3357 var childrenLength = arguments.length - 1;
3358 if (childrenLength === 1) {
3359 if (true) {
3360 validateChildKeys(children);
3361 }
3362 this.props.children = children;
3363 } else if (childrenLength > 1) {
3364 var childArray = Array(childrenLength);
3365 for (var i = 0; i < childrenLength; i++) {
3366 if (true) {
3367 validateChildKeys(arguments[i + 1]);
3368 }
3369 childArray[i] = arguments[i + 1];
3370 }
3371 this.props.children = childArray;
3372 }
3373 },
3374
3375 /**
3376 * Initializes the component, renders markup, and registers event listeners.
3377 *
3378 * NOTE: This does not insert any nodes into the DOM.
3379 *
3380 * Subclasses that override this method should make sure to invoke
3381 * `ReactComponent.Mixin.mountComponent.call(this, ...)`.
3382 *
3383 * @param {string} rootID DOM ID of the root node.
3384 * @param {ReactReconcileTransaction} transaction
3385 * @return {?string} Rendered markup to be inserted into the DOM.
3386 * @internal
3387 */
3388 mountComponent: function(rootID, transaction) {
3389 invariant(
3390 !this.isMounted(),
3391 'mountComponent(%s, ...): Can only mount an unmounted component.',
3392 rootID
3393 );
3394 var props = this.props;
3395 if (props.ref != null) {
3396 ReactOwner.addComponentAsRefTo(this, props.ref, props[OWNER]);
3397 }
3398 this._rootNodeID = rootID;
3399 this._lifeCycleState = ComponentLifeCycle.MOUNTED;
3400 // Effectively: return '';
3401 },
3402
3403 /**
3404 * Releases any resources allocated by `mountComponent`.
3405 *
3406 * NOTE: This does not remove any nodes from the DOM.
3407 *
3408 * Subclasses that override this method should make sure to invoke
3409 * `ReactComponent.Mixin.unmountComponent.call(this)`.
3410 *
3411 * @internal
3412 */
3413 unmountComponent: function() {
3414 invariant(
3415 this.isMounted(),
3416 'unmountComponent(): Can only unmount a mounted component.'
3417 );
3418 var props = this.props;
3419 if (props.ref != null) {
3420 ReactOwner.removeComponentAsRefFrom(this, props.ref, props[OWNER]);
3421 }
3422 ReactComponent.unmountIDFromEnvironment(this._rootNodeID);
3423 this._rootNodeID = null;
3424 this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
3425 },
3426
3427 /**
3428 * Updates the rendered DOM nodes given a new set of props.
3429 *
3430 * Subclasses that override this method should make sure to invoke
3431 * `ReactComponent.Mixin.receiveProps.call(this, ...)`.
3432 *
3433 * @param {object} nextProps Next set of properties.
3434 * @param {ReactReconcileTransaction} transaction
3435 * @internal
3436 */
3437 receiveProps: function(nextProps, transaction) {
3438 invariant(
3439 this.isMounted(),
3440 'receiveProps(...): Can only update a mounted component.'
3441 );
3442 this._pendingProps = nextProps;
3443 this._performUpdateIfNecessary(transaction);
3444 },
3445
3446 /**
3447 * Call `_performUpdateIfNecessary` within a new transaction.
3448 *
3449 * @param {ReactReconcileTransaction} transaction
3450 * @internal
3451 */
3452 performUpdateIfNecessary: function() {
3453 var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
3454 transaction.perform(this._performUpdateIfNecessary, this, transaction);
3455 ReactComponent.ReactReconcileTransaction.release(transaction);
3456 },
3457
3458 /**
3459 * If `_pendingProps` is set, update the component.
3460 *
3461 * @param {ReactReconcileTransaction} transaction
3462 * @internal
3463 */
3464 _performUpdateIfNecessary: function(transaction) {
3465 if (this._pendingProps == null) {
3466 return;
3467 }
3468 var prevProps = this.props;
3469 this.props = this._pendingProps;
3470 this._pendingProps = null;
3471 this.updateComponent(transaction, prevProps);
3472 },
3473
3474 /**
3475 * Updates the component's currently mounted representation.
3476 *
3477 * @param {ReactReconcileTransaction} transaction
3478 * @param {object} prevProps
3479 * @internal
3480 */
3481 updateComponent: function(transaction, prevProps) {
3482 var props = this.props;
3483 // If either the owner or a `ref` has changed, make sure the newest owner
3484 // has stored a reference to `this`, and the previous owner (if different)
3485 // has forgotten the reference to `this`.
3486 if (props[OWNER] !== prevProps[OWNER] || props.ref !== prevProps.ref) {
3487 if (prevProps.ref != null) {
3488 ReactOwner.removeComponentAsRefFrom(
3489 this, prevProps.ref, prevProps[OWNER]
3490 );
3491 }
3492 // Correct, even if the owner is the same, and only the ref has changed.
3493 if (props.ref != null) {
3494 ReactOwner.addComponentAsRefTo(this, props.ref, props[OWNER]);
3495 }
3496 }
3497 },
3498
3499 /**
3500 * Mounts this component and inserts it into the DOM.
3501 *
3502 * @param {string} rootID DOM ID of the root node.
3503 * @param {DOMElement} container DOM element to mount into.
3504 * @param {boolean} shouldReuseMarkup If true, do not insert markup
3505 * @final
3506 * @internal
3507 * @see {ReactMount.renderComponent}
3508 */
3509 mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {
3510 var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
3511 transaction.perform(
3512 this._mountComponentIntoNode,
3513 this,
3514 rootID,
3515 container,
3516 transaction,
3517 shouldReuseMarkup
3518 );
3519 ReactComponent.ReactReconcileTransaction.release(transaction);
3520 },
3521
3522 /**
3523 * @param {string} rootID DOM ID of the root node.
3524 * @param {DOMElement} container DOM element to mount into.
3525 * @param {ReactReconcileTransaction} transaction
3526 * @param {boolean} shouldReuseMarkup If true, do not insert markup
3527 * @final
3528 * @private
3529 */
3530 _mountComponentIntoNode: function(
3531 rootID,
3532 container,
3533 transaction,
3534 shouldReuseMarkup) {
3535 var markup = this.mountComponent(rootID, transaction);
3536 ReactComponent.mountImageIntoNode(markup, container, shouldReuseMarkup);
3537 },
3538
3539 /**
3540 * Checks if this component is owned by the supplied `owner` component.
3541 *
3542 * @param {ReactComponent} owner Component to check.
3543 * @return {boolean} True if `owners` owns this component.
3544 * @final
3545 * @internal
3546 */
3547 isOwnedBy: function(owner) {
3548 return this.props[OWNER] === owner;
3549 },
3550
3551 /**
3552 * Gets another component, that shares the same owner as this one, by ref.
3553 *
3554 * @param {string} ref of a sibling Component.
3555 * @return {?ReactComponent} the actual sibling Component.
3556 * @final
3557 * @internal
3558 */
3559 getSiblingByRef: function(ref) {
3560 var owner = this.props[OWNER];
3561 if (!owner || !owner.refs) {
3562 return null;
3563 }
3564 return owner.refs[ref];
3565 }
3566 })
3567};
3568
3569module.exports = ReactComponent;
3570
3571},{"./ReactComponentEnvironment":25,"./ReactCurrentOwner":27,"./ReactOwner":50,"./ReactUpdates":57,"./invariant":89,"./keyMirror":92,"./merge":95}],24:[function(require,module,exports){
3572/**
3573 * Copyright 2013 Facebook, Inc.
3574 *
3575 * Licensed under the Apache License, Version 2.0 (the "License");
3576 * you may not use this file except in compliance with the License.
3577 * You may obtain a copy of the License at
3578 *
3579 * http://www.apache.org/licenses/LICENSE-2.0
3580 *
3581 * Unless required by applicable law or agreed to in writing, software
3582 * distributed under the License is distributed on an "AS IS" BASIS,
3583 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3584 * See the License for the specific language governing permissions and
3585 * limitations under the License.
3586 *
3587 * @providesModule ReactComponentBrowserEnvironment
3588 */
3589
3590/*jslint evil: true */
3591
3592"use strict";
3593
3594var ReactDOMIDOperations = require("./ReactDOMIDOperations");
3595var ReactMarkupChecksum = require("./ReactMarkupChecksum");
3596var ReactMount = require("./ReactMount");
3597var ReactReconcileTransaction = require("./ReactReconcileTransaction");
3598
3599var getReactRootElementInContainer = require("./getReactRootElementInContainer");
3600var invariant = require("./invariant");
3601var mutateHTMLNodeWithMarkup = require("./mutateHTMLNodeWithMarkup");
3602
3603
3604var ELEMENT_NODE_TYPE = 1;
3605var DOC_NODE_TYPE = 9;
3606
3607
3608/**
3609 * Abstracts away all functionality of `ReactComponent` requires knowledge of
3610 * the browser context.
3611 */
3612var ReactComponentBrowserEnvironment = {
3613 /**
3614 * Mixed into every component instance.
3615 */
3616 Mixin: {
3617 /**
3618 * Returns the DOM node rendered by this component.
3619 *
3620 * @return {DOMElement} The root node of this component.
3621 * @final
3622 * @protected
3623 */
3624 getDOMNode: function() {
3625 invariant(
3626 this.isMounted(),
3627 'getDOMNode(): A component must be mounted to have a DOM node.'
3628 );
3629 return ReactMount.getNode(this._rootNodeID);
3630 }
3631 },
3632
3633 ReactReconcileTransaction: ReactReconcileTransaction,
3634
3635 DOMIDOperations: ReactDOMIDOperations,
3636
3637 /**
3638 * If a particular environment requires that some resources be cleaned up,
3639 * specify this in the injected Mixin. In the DOM, we would likely want to
3640 * purge any cached node ID lookups.
3641 *
3642 * @private
3643 */
3644 unmountIDFromEnvironment: function(rootNodeID) {
3645 ReactMount.purgeID(rootNodeID);
3646 },
3647
3648 /**
3649 * @param {string} markup Markup string to place into the DOM Element.
3650 * @param {DOMElement} container DOM Element to insert markup into.
3651 * @param {boolean} shouldReuseMarkup Should reuse the existing markup in the
3652 * container if possible.
3653 */
3654 mountImageIntoNode: function(markup, container, shouldReuseMarkup) {
3655 invariant(
3656 container && (
3657 container.nodeType === ELEMENT_NODE_TYPE ||
3658 container.nodeType === DOC_NODE_TYPE && ReactMount.allowFullPageRender
3659 ),
3660 'mountComponentIntoNode(...): Target container is not valid.'
3661 );
3662 if (shouldReuseMarkup) {
3663 if (ReactMarkupChecksum.canReuseMarkup(
3664 markup,
3665 getReactRootElementInContainer(container))) {
3666 return;
3667 } else {
3668 if (true) {
3669 console.warn(
3670 'React attempted to use reuse markup in a container but the ' +
3671 'checksum was invalid. This generally means that you are using ' +
3672 'server rendering and the markup generated on the server was ' +
3673 'not what the client was expecting. React injected new markup ' +
3674 'to compensate which works but you have lost many of the ' +
3675 'benefits of server rendering. Instead, figure out why the ' +
3676 'markup being generated is different on the client or server.'
3677 );
3678 }
3679 }
3680 }
3681
3682 // You can't naively set the innerHTML of the entire document. You need
3683 // to mutate documentElement which requires doing some crazy tricks. See
3684 // mutateHTMLNodeWithMarkup()
3685 if (container.nodeType === DOC_NODE_TYPE) {
3686 mutateHTMLNodeWithMarkup(container.documentElement, markup);
3687 return;
3688 }
3689
3690 // Asynchronously inject markup by ensuring that the container is not in
3691 // the document when settings its `innerHTML`.
3692 var parent = container.parentNode;
3693 if (parent) {
3694 var next = container.nextSibling;
3695 parent.removeChild(container);
3696 container.innerHTML = markup;
3697 if (next) {
3698 parent.insertBefore(container, next);
3699 } else {
3700 parent.appendChild(container);
3701 }
3702 } else {
3703 container.innerHTML = markup;
3704 }
3705 }
3706};
3707
3708module.exports = ReactComponentBrowserEnvironment;
3709
3710},{"./ReactDOMIDOperations":31,"./ReactMarkupChecksum":44,"./ReactMount":45,"./ReactReconcileTransaction":54,"./getReactRootElementInContainer":86,"./invariant":89,"./mutateHTMLNodeWithMarkup":99}],25:[function(require,module,exports){
3711/**
3712 * Copyright 2013 Facebook, Inc.
3713 *
3714 * Licensed under the Apache License, Version 2.0 (the "License");
3715 * you may not use this file except in compliance with the License.
3716 * You may obtain a copy of the License at
3717 *
3718 * http://www.apache.org/licenses/LICENSE-2.0
3719 *
3720 * Unless required by applicable law or agreed to in writing, software
3721 * distributed under the License is distributed on an "AS IS" BASIS,
3722 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3723 * See the License for the specific language governing permissions and
3724 * limitations under the License.
3725 *
3726 * @providesModule ReactComponentEnvironment
3727 */
3728
3729var ReactComponentBrowserEnvironment =
3730 require("./ReactComponentBrowserEnvironment");
3731
3732var ReactComponentEnvironment = ReactComponentBrowserEnvironment;
3733
3734module.exports = ReactComponentEnvironment;
3735
3736},{"./ReactComponentBrowserEnvironment":24}],26:[function(require,module,exports){
3737/**
3738 * Copyright 2013 Facebook, Inc.
3739 *
3740 * Licensed under the Apache License, Version 2.0 (the "License");
3741 * you may not use this file except in compliance with the License.
3742 * You may obtain a copy of the License at
3743 *
3744 * http://www.apache.org/licenses/LICENSE-2.0
3745 *
3746 * Unless required by applicable law or agreed to in writing, software
3747 * distributed under the License is distributed on an "AS IS" BASIS,
3748 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3749 * See the License for the specific language governing permissions and
3750 * limitations under the License.
3751 *
3752 * @providesModule ReactCompositeComponent
3753 */
3754
3755"use strict";
3756
3757var ReactComponent = require("./ReactComponent");
3758var ReactCurrentOwner = require("./ReactCurrentOwner");
3759var ReactOwner = require("./ReactOwner");
3760var ReactPerf = require("./ReactPerf");
3761var ReactPropTransferer = require("./ReactPropTransferer");
3762var ReactUpdates = require("./ReactUpdates");
3763
3764var invariant = require("./invariant");
3765var keyMirror = require("./keyMirror");
3766var merge = require("./merge");
3767var mixInto = require("./mixInto");
3768var objMap = require("./objMap");
3769
3770/**
3771 * Policies that describe methods in `ReactCompositeComponentInterface`.
3772 */
3773var SpecPolicy = keyMirror({
3774 /**
3775 * These methods may be defined only once by the class specification or mixin.
3776 */
3777 DEFINE_ONCE: null,
3778 /**
3779 * These methods may be defined by both the class specification and mixins.
3780 * Subsequent definitions will be chained. These methods must return void.
3781 */
3782 DEFINE_MANY: null,
3783 /**
3784 * These methods are overriding the base ReactCompositeComponent class.
3785 */
3786 OVERRIDE_BASE: null,
3787 /**
3788 * These methods are similar to DEFINE_MANY, except we assume they return
3789 * objects. We try to merge the keys of the return values of all the mixed in
3790 * functions. If there is a key conflict we throw.
3791 */
3792 DEFINE_MANY_MERGED: null
3793});
3794
3795/**
3796 * Composite components are higher-level components that compose other composite
3797 * or native components.
3798 *
3799 * To create a new type of `ReactCompositeComponent`, pass a specification of
3800 * your new class to `React.createClass`. The only requirement of your class
3801 * specification is that you implement a `render` method.
3802 *
3803 * var MyComponent = React.createClass({
3804 * render: function() {
3805 * return <div>Hello World</div>;
3806 * }
3807 * });
3808 *
3809 * The class specification supports a specific protocol of methods that have
3810 * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for
3811 * more the comprehensive protocol. Any other properties and methods in the
3812 * class specification will available on the prototype.
3813 *
3814 * @interface ReactCompositeComponentInterface
3815 * @internal
3816 */
3817var ReactCompositeComponentInterface = {
3818
3819 /**
3820 * An array of Mixin objects to include when defining your component.
3821 *
3822 * @type {array}
3823 * @optional
3824 */
3825 mixins: SpecPolicy.DEFINE_MANY,
3826
3827 /**
3828 * Definition of prop types for this component.
3829 *
3830 * @type {object}
3831 * @optional
3832 */
3833 propTypes: SpecPolicy.DEFINE_ONCE,
3834
3835
3836
3837 // ==== Definition methods ====
3838
3839 /**
3840 * Invoked when the component is mounted. Values in the mapping will be set on
3841 * `this.props` if that prop is not specified (i.e. using an `in` check).
3842 *
3843 * This method is invoked before `getInitialState` and therefore cannot rely
3844 * on `this.state` or use `this.setState`.
3845 *
3846 * @return {object}
3847 * @optional
3848 */
3849 getDefaultProps: SpecPolicy.DEFINE_ONCE,
3850
3851 /**
3852 * Invoked once before the component is mounted. The return value will be used
3853 * as the initial value of `this.state`.
3854 *
3855 * getInitialState: function() {
3856 * return {
3857 * isOn: false,
3858 * fooBaz: new BazFoo()
3859 * }
3860 * }
3861 *
3862 * @return {object}
3863 * @optional
3864 */
3865 getInitialState: SpecPolicy.DEFINE_MANY_MERGED,
3866
3867 /**
3868 * Uses props from `this.props` and state from `this.state` to render the
3869 * structure of the component.
3870 *
3871 * No guarantees are made about when or how often this method is invoked, so
3872 * it must not have side effects.
3873 *
3874 * render: function() {
3875 * var name = this.props.name;
3876 * return <div>Hello, {name}!</div>;
3877 * }
3878 *
3879 * @return {ReactComponent}
3880 * @nosideeffects
3881 * @required
3882 */
3883 render: SpecPolicy.DEFINE_ONCE,
3884
3885
3886
3887 // ==== Delegate methods ====
3888
3889 /**
3890 * Invoked when the component is initially created and about to be mounted.
3891 * This may have side effects, but any external subscriptions or data created
3892 * by this method must be cleaned up in `componentWillUnmount`.
3893 *
3894 * @optional
3895 */
3896 componentWillMount: SpecPolicy.DEFINE_MANY,
3897
3898 /**
3899 * Invoked when the component has been mounted and has a DOM representation.
3900 * However, there is no guarantee that the DOM node is in the document.
3901 *
3902 * Use this as an opportunity to operate on the DOM when the component has
3903 * been mounted (initialized and rendered) for the first time.
3904 *
3905 * @param {DOMElement} rootNode DOM element representing the component.
3906 * @optional
3907 */
3908 componentDidMount: SpecPolicy.DEFINE_MANY,
3909
3910 /**
3911 * Invoked before the component receives new props.
3912 *
3913 * Use this as an opportunity to react to a prop transition by updating the
3914 * state using `this.setState`. Current props are accessed via `this.props`.
3915 *
3916 * componentWillReceiveProps: function(nextProps) {
3917 * this.setState({
3918 * likesIncreasing: nextProps.likeCount > this.props.likeCount
3919 * });
3920 * }
3921 *
3922 * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
3923 * transition may cause a state change, but the opposite is not true. If you
3924 * need it, you are probably looking for `componentWillUpdate`.
3925 *
3926 * @param {object} nextProps
3927 * @optional
3928 */
3929 componentWillReceiveProps: SpecPolicy.DEFINE_MANY,
3930
3931 /**
3932 * Invoked while deciding if the component should be updated as a result of
3933 * receiving new props and state.
3934 *
3935 * Use this as an opportunity to `return false` when you're certain that the
3936 * transition to the new props and state will not require a component update.
3937 *
3938 * shouldComponentUpdate: function(nextProps, nextState) {
3939 * return !equal(nextProps, this.props) || !equal(nextState, this.state);
3940 * }
3941 *
3942 * @param {object} nextProps
3943 * @param {?object} nextState
3944 * @return {boolean} True if the component should update.
3945 * @optional
3946 */
3947 shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,
3948
3949 /**
3950 * Invoked when the component is about to update due to a transition from
3951 * `this.props` and `this.state` to `nextProps` and `nextState`.
3952 *
3953 * Use this as an opportunity to perform preparation before an update occurs.
3954 *
3955 * NOTE: You **cannot** use `this.setState()` in this method.
3956 *
3957 * @param {object} nextProps
3958 * @param {?object} nextState
3959 * @param {ReactReconcileTransaction} transaction
3960 * @optional
3961 */
3962 componentWillUpdate: SpecPolicy.DEFINE_MANY,
3963
3964 /**
3965 * Invoked when the component's DOM representation has been updated.
3966 *
3967 * Use this as an opportunity to operate on the DOM when the component has
3968 * been updated.
3969 *
3970 * @param {object} prevProps
3971 * @param {?object} prevState
3972 * @param {DOMElement} rootNode DOM element representing the component.
3973 * @optional
3974 */
3975 componentDidUpdate: SpecPolicy.DEFINE_MANY,
3976
3977 /**
3978 * Invoked when the component is about to be removed from its parent and have
3979 * its DOM representation destroyed.
3980 *
3981 * Use this as an opportunity to deallocate any external resources.
3982 *
3983 * NOTE: There is no `componentDidUnmount` since your component will have been
3984 * destroyed by that point.
3985 *
3986 * @optional
3987 */
3988 componentWillUnmount: SpecPolicy.DEFINE_MANY,
3989
3990
3991
3992 // ==== Advanced methods ====
3993
3994 /**
3995 * Updates the component's currently mounted DOM representation.
3996 *
3997 * By default, this implements React's rendering and reconciliation algorithm.
3998 * Sophisticated clients may wish to override this.
3999 *
4000 * @param {ReactReconcileTransaction} transaction
4001 * @internal
4002 * @overridable
4003 */
4004 updateComponent: SpecPolicy.OVERRIDE_BASE
4005
4006};
4007
4008/**
4009 * Mapping from class specification keys to special processing functions.
4010 *
4011 * Although these are declared in the specification when defining classes
4012 * using `React.createClass`, they will not be on the component's prototype.
4013 */
4014var RESERVED_SPEC_KEYS = {
4015 displayName: function(Constructor, displayName) {
4016 Constructor.displayName = displayName;
4017 },
4018 mixins: function(Constructor, mixins) {
4019 if (mixins) {
4020 for (var i = 0; i < mixins.length; i++) {
4021 mixSpecIntoComponent(Constructor, mixins[i]);
4022 }
4023 }
4024 },
4025 propTypes: function(Constructor, propTypes) {
4026 Constructor.propTypes = propTypes;
4027 }
4028};
4029
4030function validateMethodOverride(proto, name) {
4031 var specPolicy = ReactCompositeComponentInterface[name];
4032
4033 // Disallow overriding of base class methods unless explicitly allowed.
4034 if (ReactCompositeComponentMixin.hasOwnProperty(name)) {
4035 invariant(
4036 specPolicy === SpecPolicy.OVERRIDE_BASE,
4037 'ReactCompositeComponentInterface: You are attempting to override ' +
4038 '`%s` from your class specification. Ensure that your method names ' +
4039 'do not overlap with React methods.',
4040 name
4041 );
4042 }
4043
4044 // Disallow defining methods more than once unless explicitly allowed.
4045 if (proto.hasOwnProperty(name)) {
4046 invariant(
4047 specPolicy === SpecPolicy.DEFINE_MANY ||
4048 specPolicy === SpecPolicy.DEFINE_MANY_MERGED,
4049 'ReactCompositeComponentInterface: You are attempting to define ' +
4050 '`%s` on your component more than once. This conflict may be due ' +
4051 'to a mixin.',
4052 name
4053 );
4054 }
4055}
4056
4057
4058function validateLifeCycleOnReplaceState(instance) {
4059 var compositeLifeCycleState = instance._compositeLifeCycleState;
4060 invariant(
4061 instance.isMounted() ||
4062 compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
4063 'replaceState(...): Can only update a mounted or mounting component.'
4064 );
4065 invariant(
4066 compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
4067 compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
4068 'replaceState(...): Cannot update while unmounting component or during ' +
4069 'an existing state transition (such as within `render`).'
4070 );
4071}
4072
4073/**
4074 * Custom version of `mixInto` which handles policy validation and reserved
4075 * specification keys when building `ReactCompositeComponent` classses.
4076 */
4077function mixSpecIntoComponent(Constructor, spec) {
4078 var proto = Constructor.prototype;
4079 for (var name in spec) {
4080 var property = spec[name];
4081 if (!spec.hasOwnProperty(name) || !property) {
4082 continue;
4083 }
4084 validateMethodOverride(proto, name);
4085
4086 if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
4087 RESERVED_SPEC_KEYS[name](Constructor, property);
4088 } else {
4089 // Setup methods on prototype:
4090 // The following member methods should not be automatically bound:
4091 // 1. Expected ReactCompositeComponent methods (in the "interface").
4092 // 2. Overridden methods (that were mixed in).
4093 var isCompositeComponentMethod = name in ReactCompositeComponentInterface;
4094 var isInherited = name in proto;
4095 var markedDontBind = property.__reactDontBind;
4096 var isFunction = typeof property === 'function';
4097 var shouldAutoBind =
4098 isFunction &&
4099 !isCompositeComponentMethod &&
4100 !isInherited &&
4101 !markedDontBind;
4102
4103 if (shouldAutoBind) {
4104 if (!proto.__reactAutoBindMap) {
4105 proto.__reactAutoBindMap = {};
4106 }
4107 proto.__reactAutoBindMap[name] = property;
4108 proto[name] = property;
4109 } else {
4110 if (isInherited) {
4111 // For methods which are defined more than once, call the existing
4112 // methods before calling the new property.
4113 if (ReactCompositeComponentInterface[name] ===
4114 SpecPolicy.DEFINE_MANY_MERGED) {
4115 proto[name] = createMergedResultFunction(proto[name], property);
4116 } else {
4117 proto[name] = createChainedFunction(proto[name], property);
4118 }
4119 } else {
4120 proto[name] = property;
4121 }
4122 }
4123 }
4124 }
4125}
4126
4127/**
4128 * Merge two objects, but throw if both contain the same key.
4129 *
4130 * @param {object} one The first object, which is mutated.
4131 * @param {object} two The second object
4132 * @return {object} one after it has been mutated to contain everything in two.
4133 */
4134function mergeObjectsWithNoDuplicateKeys(one, two) {
4135 invariant(
4136 one && two && typeof one === 'object' && typeof two === 'object',
4137 'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects'
4138 );
4139
4140 objMap(two, function(value, key) {
4141 invariant(
4142 one[key] === undefined,
4143 'mergeObjectsWithNoDuplicateKeys(): ' +
4144 'Tried to merge two objects with the same key: %s',
4145 key
4146 );
4147 one[key] = value;
4148 });
4149 return one;
4150}
4151
4152/**
4153 * Creates a function that invokes two functions and merges their return values.
4154 *
4155 * @param {function} one Function to invoke first.
4156 * @param {function} two Function to invoke second.
4157 * @return {function} Function that invokes the two argument functions.
4158 * @private
4159 */
4160function createMergedResultFunction(one, two) {
4161 return function mergedResult() {
4162 return mergeObjectsWithNoDuplicateKeys(
4163 one.apply(this, arguments),
4164 two.apply(this, arguments)
4165 );
4166 };
4167}
4168
4169/**
4170 * Creates a function that invokes two functions and ignores their return vales.
4171 *
4172 * @param {function} one Function to invoke first.
4173 * @param {function} two Function to invoke second.
4174 * @return {function} Function that invokes the two argument functions.
4175 * @private
4176 */
4177function createChainedFunction(one, two) {
4178 return function chainedFunction() {
4179 one.apply(this, arguments);
4180 two.apply(this, arguments);
4181 };
4182}
4183
4184/**
4185 * `ReactCompositeComponent` maintains an auxiliary life cycle state in
4186 * `this._compositeLifeCycleState` (which can be null).
4187 *
4188 * This is different from the life cycle state maintained by `ReactComponent` in
4189 * `this._lifeCycleState`. The following diagram shows how the states overlap in
4190 * time. There are times when the CompositeLifeCycle is null - at those times it
4191 * is only meaningful to look at ComponentLifeCycle alone.
4192 *
4193 * Top Row: ReactComponent.ComponentLifeCycle
4194 * Low Row: ReactComponent.CompositeLifeCycle
4195 *
4196 * +-------+------------------------------------------------------+--------+
4197 * | UN | MOUNTED | UN |
4198 * |MOUNTED| | MOUNTED|
4199 * +-------+------------------------------------------------------+--------+
4200 * | ^--------+ +------+ +------+ +------+ +--------^ |
4201 * | | | | | | | | | | | |
4202 * | 0--|MOUNTING|-0-|RECEIV|-0-|RECEIV|-0-|RECEIV|-0-| UN |--->0 |
4203 * | | | |PROPS | | PROPS| | STATE| |MOUNTING| |
4204 * | | | | | | | | | | | |
4205 * | | | | | | | | | | | |
4206 * | +--------+ +------+ +------+ +------+ +--------+ |
4207 * | | | |
4208 * +-------+------------------------------------------------------+--------+
4209 */
4210var CompositeLifeCycle = keyMirror({
4211 /**
4212 * Components in the process of being mounted respond to state changes
4213 * differently.
4214 */
4215 MOUNTING: null,
4216 /**
4217 * Components in the process of being unmounted are guarded against state
4218 * changes.
4219 */
4220 UNMOUNTING: null,
4221 /**
4222 * Components that are mounted and receiving new props respond to state
4223 * changes differently.
4224 */
4225 RECEIVING_PROPS: null,
4226 /**
4227 * Components that are mounted and receiving new state are guarded against
4228 * additional state changes.
4229 */
4230 RECEIVING_STATE: null
4231});
4232
4233/**
4234 * @lends {ReactCompositeComponent.prototype}
4235 */
4236var ReactCompositeComponentMixin = {
4237
4238 /**
4239 * Base constructor for all composite component.
4240 *
4241 * @param {?object} initialProps
4242 * @param {*} children
4243 * @final
4244 * @internal
4245 */
4246 construct: function(initialProps, children) {
4247 // Children can be either an array or more than one argument
4248 ReactComponent.Mixin.construct.apply(this, arguments);
4249 this.state = null;
4250 this._pendingState = null;
4251 this._compositeLifeCycleState = null;
4252 },
4253
4254 /**
4255 * Checks whether or not this composite component is mounted.
4256 * @return {boolean} True if mounted, false otherwise.
4257 * @protected
4258 * @final
4259 */
4260 isMounted: function() {
4261 return ReactComponent.Mixin.isMounted.call(this) &&
4262 this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING;
4263 },
4264
4265 /**
4266 * Initializes the component, renders markup, and registers event listeners.
4267 *
4268 * @param {string} rootID DOM ID of the root node.
4269 * @param {ReactReconcileTransaction} transaction
4270 * @return {?string} Rendered markup to be inserted into the DOM.
4271 * @final
4272 * @internal
4273 */
4274 mountComponent: ReactPerf.measure(
4275 'ReactCompositeComponent',
4276 'mountComponent',
4277 function(rootID, transaction) {
4278 ReactComponent.Mixin.mountComponent.call(this, rootID, transaction);
4279 this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
4280
4281 this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null;
4282 this._processProps(this.props);
4283
4284 if (this.__reactAutoBindMap) {
4285 this._bindAutoBindMethods();
4286 }
4287
4288 this.state = this.getInitialState ? this.getInitialState() : null;
4289 this._pendingState = null;
4290 this._pendingForceUpdate = false;
4291
4292 if (this.componentWillMount) {
4293 this.componentWillMount();
4294 // When mounting, calls to `setState` by `componentWillMount` will set
4295 // `this._pendingState` without triggering a re-render.
4296 if (this._pendingState) {
4297 this.state = this._pendingState;
4298 this._pendingState = null;
4299 }
4300 }
4301
4302 this._renderedComponent = this._renderValidatedComponent();
4303
4304 // Done with mounting, `setState` will now trigger UI changes.
4305 this._compositeLifeCycleState = null;
4306 var markup = this._renderedComponent.mountComponent(rootID, transaction);
4307 if (this.componentDidMount) {
4308 transaction.getReactOnDOMReady().enqueue(this, this.componentDidMount);
4309 }
4310 return markup;
4311 }
4312 ),
4313
4314 /**
4315 * Releases any resources allocated by `mountComponent`.
4316 *
4317 * @final
4318 * @internal
4319 */
4320 unmountComponent: function() {
4321 this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING;
4322 if (this.componentWillUnmount) {
4323 this.componentWillUnmount();
4324 }
4325 this._compositeLifeCycleState = null;
4326
4327 this._defaultProps = null;
4328
4329 ReactComponent.Mixin.unmountComponent.call(this);
4330 this._renderedComponent.unmountComponent();
4331 this._renderedComponent = null;
4332
4333 if (this.refs) {
4334 this.refs = null;
4335 }
4336
4337 // Some existing components rely on this.props even after they've been
4338 // destroyed (in event handlers).
4339 // TODO: this.props = null;
4340 // TODO: this.state = null;
4341 },
4342
4343 /**
4344 * Sets a subset of the state. Always use this or `replaceState` to mutate
4345 * state. You should treat `this.state` as immutable.
4346 *
4347 * There is no guarantee that `this.state` will be immediately updated, so
4348 * accessing `this.state` after calling this method may return the old value.
4349 *
4350 * There is no guarantee that calls to `setState` will run synchronously,
4351 * as they may eventually be batched together. You can provide an optional
4352 * callback that will be executed when the call to setState is actually
4353 * completed.
4354 *
4355 * @param {object} partialState Next partial state to be merged with state.
4356 * @param {?function} callback Called after state is updated.
4357 * @final
4358 * @protected
4359 */
4360 setState: function(partialState, callback) {
4361 // Merge with `_pendingState` if it exists, otherwise with existing state.
4362 this.replaceState(
4363 merge(this._pendingState || this.state, partialState),
4364 callback
4365 );
4366 },
4367
4368 /**
4369 * Replaces all of the state. Always use this or `setState` to mutate state.
4370 * You should treat `this.state` as immutable.
4371 *
4372 * There is no guarantee that `this.state` will be immediately updated, so
4373 * accessing `this.state` after calling this method may return the old value.
4374 *
4375 * @param {object} completeState Next state.
4376 * @param {?function} callback Called after state is updated.
4377 * @final
4378 * @protected
4379 */
4380 replaceState: function(completeState, callback) {
4381 validateLifeCycleOnReplaceState(this);
4382 this._pendingState = completeState;
4383 ReactUpdates.enqueueUpdate(this, callback);
4384 },
4385
4386 /**
4387 * Processes props by setting default values for unspecified props and
4388 * asserting that the props are valid.
4389 *
4390 * @param {object} props
4391 * @private
4392 */
4393 _processProps: function(props) {
4394 var propName;
4395 var defaultProps = this._defaultProps;
4396 for (propName in defaultProps) {
4397 if (!(propName in props)) {
4398 props[propName] = defaultProps[propName];
4399 }
4400 }
4401 var propTypes = this.constructor.propTypes;
4402 if (propTypes) {
4403 var componentName = this.constructor.displayName;
4404 for (propName in propTypes) {
4405 var checkProp = propTypes[propName];
4406 if (checkProp) {
4407 checkProp(props, propName, componentName);
4408 }
4409 }
4410 }
4411 },
4412
4413 performUpdateIfNecessary: function() {
4414 var compositeLifeCycleState = this._compositeLifeCycleState;
4415 // Do not trigger a state transition if we are in the middle of mounting or
4416 // receiving props because both of those will already be doing this.
4417 if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING ||
4418 compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) {
4419 return;
4420 }
4421 ReactComponent.Mixin.performUpdateIfNecessary.call(this);
4422 },
4423
4424 /**
4425 * If any of `_pendingProps`, `_pendingState`, or `_pendingForceUpdate` is
4426 * set, update the component.
4427 *
4428 * @param {ReactReconcileTransaction} transaction
4429 * @internal
4430 */
4431 _performUpdateIfNecessary: function(transaction) {
4432 if (this._pendingProps == null &&
4433 this._pendingState == null &&
4434 !this._pendingForceUpdate) {
4435 return;
4436 }
4437
4438 var nextProps = this.props;
4439 if (this._pendingProps != null) {
4440 nextProps = this._pendingProps;
4441 this._processProps(nextProps);
4442 this._pendingProps = null;
4443
4444 this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;
4445 if (this.componentWillReceiveProps) {
4446 this.componentWillReceiveProps(nextProps, transaction);
4447 }
4448 }
4449
4450 this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE;
4451
4452 var nextState = this._pendingState || this.state;
4453 this._pendingState = null;
4454
4455 if (this._pendingForceUpdate ||
4456 !this.shouldComponentUpdate ||
4457 this.shouldComponentUpdate(nextProps, nextState)) {
4458 this._pendingForceUpdate = false;
4459 // Will set `this.props` and `this.state`.
4460 this._performComponentUpdate(nextProps, nextState, transaction);
4461 } else {
4462 // If it's determined that a component should not update, we still want
4463 // to set props and state.
4464 this.props = nextProps;
4465 this.state = nextState;
4466 }
4467
4468 this._compositeLifeCycleState = null;
4469 },
4470
4471 /**
4472 * Merges new props and state, notifies delegate methods of update and
4473 * performs update.
4474 *
4475 * @param {object} nextProps Next object to set as properties.
4476 * @param {?object} nextState Next object to set as state.
4477 * @param {ReactReconcileTransaction} transaction
4478 * @private
4479 */
4480 _performComponentUpdate: function(nextProps, nextState, transaction) {
4481 var prevProps = this.props;
4482 var prevState = this.state;
4483
4484 if (this.componentWillUpdate) {
4485 this.componentWillUpdate(nextProps, nextState, transaction);
4486 }
4487
4488 this.props = nextProps;
4489 this.state = nextState;
4490
4491 this.updateComponent(transaction, prevProps, prevState);
4492
4493 if (this.componentDidUpdate) {
4494 transaction.getReactOnDOMReady().enqueue(
4495 this,
4496 this.componentDidUpdate.bind(this, prevProps, prevState)
4497 );
4498 }
4499 },
4500
4501 /**
4502 * Updates the component's currently mounted DOM representation.
4503 *
4504 * By default, this implements React's rendering and reconciliation algorithm.
4505 * Sophisticated clients may wish to override this.
4506 *
4507 * @param {ReactReconcileTransaction} transaction
4508 * @param {object} prevProps
4509 * @param {?object} prevState
4510 * @internal
4511 * @overridable
4512 */
4513 updateComponent: ReactPerf.measure(
4514 'ReactCompositeComponent',
4515 'updateComponent',
4516 function(transaction, prevProps, prevState) {
4517 ReactComponent.Mixin.updateComponent.call(this, transaction, prevProps);
4518 var currentComponent = this._renderedComponent;
4519 var nextComponent = this._renderValidatedComponent();
4520 if (currentComponent.constructor === nextComponent.constructor) {
4521 currentComponent.receiveProps(nextComponent.props, transaction);
4522 } else {
4523 // These two IDs are actually the same! But nothing should rely on that.
4524 var thisID = this._rootNodeID;
4525 var currentComponentID = currentComponent._rootNodeID;
4526 currentComponent.unmountComponent();
4527 var nextMarkup = nextComponent.mountComponent(thisID, transaction);
4528 ReactComponent.DOMIDOperations.dangerouslyReplaceNodeWithMarkupByID(
4529 currentComponentID,
4530 nextMarkup
4531 );
4532 this._renderedComponent = nextComponent;
4533 }
4534 }
4535 ),
4536
4537 /**
4538 * Forces an update. This should only be invoked when it is known with
4539 * certainty that we are **not** in a DOM transaction.
4540 *
4541 * You may want to call this when you know that some deeper aspect of the
4542 * component's state has changed but `setState` was not called.
4543 *
4544 * This will not invoke `shouldUpdateComponent`, but it will invoke
4545 * `componentWillUpdate` and `componentDidUpdate`.
4546 *
4547 * @param {?function} callback Called after update is complete.
4548 * @final
4549 * @protected
4550 */
4551 forceUpdate: function(callback) {
4552 var compositeLifeCycleState = this._compositeLifeCycleState;
4553 invariant(
4554 this.isMounted() ||
4555 compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
4556 'forceUpdate(...): Can only force an update on mounted or mounting ' +
4557 'components.'
4558 );
4559 invariant(
4560 compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
4561 compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
4562 'forceUpdate(...): Cannot force an update while unmounting component ' +
4563 'or during an existing state transition (such as within `render`).'
4564 );
4565 this._pendingForceUpdate = true;
4566 ReactUpdates.enqueueUpdate(this, callback);
4567 },
4568
4569 /**
4570 * @private
4571 */
4572 _renderValidatedComponent: function() {
4573 var renderedComponent;
4574 ReactCurrentOwner.current = this;
4575 try {
4576 renderedComponent = this.render();
4577 } catch (error) {
4578 // IE8 requires `catch` in order to use `finally`.
4579 throw error;
4580 } finally {
4581 ReactCurrentOwner.current = null;
4582 }
4583 invariant(
4584 ReactComponent.isValidComponent(renderedComponent),
4585 '%s.render(): A valid ReactComponent must be returned.',
4586 this.constructor.displayName || 'ReactCompositeComponent'
4587 );
4588 return renderedComponent;
4589 },
4590
4591 /**
4592 * @private
4593 */
4594 _bindAutoBindMethods: function() {
4595 for (var autoBindKey in this.__reactAutoBindMap) {
4596 if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
4597 continue;
4598 }
4599 var method = this.__reactAutoBindMap[autoBindKey];
4600 this[autoBindKey] = this._bindAutoBindMethod(method);
4601 }
4602 },
4603
4604 /**
4605 * Binds a method to the component.
4606 *
4607 * @param {function} method Method to be bound.
4608 * @private
4609 */
4610 _bindAutoBindMethod: function(method) {
4611 var component = this;
4612 var boundMethod = function() {
4613 return method.apply(component, arguments);
4614 };
4615 if (true) {
4616 var componentName = component.constructor.displayName;
4617 var _bind = boundMethod.bind;
4618 boundMethod.bind = function(newThis) {
4619 // User is trying to bind() an autobound method; we effectively will
4620 // ignore the value of "this" that the user is trying to use, so
4621 // let's warn.
4622 if (newThis !== component && newThis !== null) {
4623 console.warn(
4624 'bind(): React component methods may only be bound to the ' +
4625 'component instance. See ' + componentName
4626 );
4627 } else if (arguments.length === 1) {
4628 console.warn(
4629 'bind(): You are binding a component method to the component. ' +
4630 'React does this for you automatically in a high-performance ' +
4631 'way, so you can safely remove this call. See ' + componentName
4632 );
4633 return boundMethod;
4634 }
4635 return _bind.apply(boundMethod, arguments);
4636 };
4637 }
4638 return boundMethod;
4639 }
4640};
4641
4642var ReactCompositeComponentBase = function() {};
4643mixInto(ReactCompositeComponentBase, ReactComponent.Mixin);
4644mixInto(ReactCompositeComponentBase, ReactOwner.Mixin);
4645mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);
4646mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);
4647
4648/**
4649 * Module for creating composite components.
4650 *
4651 * @class ReactCompositeComponent
4652 * @extends ReactComponent
4653 * @extends ReactOwner
4654 * @extends ReactPropTransferer
4655 */
4656var ReactCompositeComponent = {
4657
4658 LifeCycle: CompositeLifeCycle,
4659
4660 Base: ReactCompositeComponentBase,
4661
4662 /**
4663 * Creates a composite component class given a class specification.
4664 *
4665 * @param {object} spec Class specification (which must define `render`).
4666 * @return {function} Component constructor function.
4667 * @public
4668 */
4669 createClass: function(spec) {
4670 var Constructor = function() {};
4671 Constructor.prototype = new ReactCompositeComponentBase();
4672 Constructor.prototype.constructor = Constructor;
4673 mixSpecIntoComponent(Constructor, spec);
4674 invariant(
4675 Constructor.prototype.render,
4676 'createClass(...): Class specification must implement a `render` method.'
4677 );
4678 // Reduce time spent doing lookups by setting these on the prototype.
4679 for (var methodName in ReactCompositeComponentInterface) {
4680 if (!Constructor.prototype[methodName]) {
4681 Constructor.prototype[methodName] = null;
4682 }
4683 }
4684
4685 var ConvenienceConstructor = function(props, children) {
4686 var instance = new Constructor();
4687 instance.construct.apply(instance, arguments);
4688 return instance;
4689 };
4690 ConvenienceConstructor.componentConstructor = Constructor;
4691 ConvenienceConstructor.originalSpec = spec;
4692 return ConvenienceConstructor;
4693 },
4694
4695 /**
4696 * Checks if a value is a valid component constructor.
4697 *
4698 * @param {*}
4699 * @return {boolean}
4700 * @public
4701 */
4702 isValidClass: function(componentClass) {
4703 return componentClass instanceof Function &&
4704 'componentConstructor' in componentClass &&
4705 componentClass.componentConstructor instanceof Function;
4706 }
4707};
4708
4709module.exports = ReactCompositeComponent;
4710
4711},{"./ReactComponent":23,"./ReactCurrentOwner":27,"./ReactOwner":50,"./ReactPerf":51,"./ReactPropTransferer":52,"./ReactUpdates":57,"./invariant":89,"./keyMirror":92,"./merge":95,"./mixInto":98,"./objMap":100}],27:[function(require,module,exports){
4712/**
4713 * Copyright 2013 Facebook, Inc.
4714 *
4715 * Licensed under the Apache License, Version 2.0 (the "License");
4716 * you may not use this file except in compliance with the License.
4717 * You may obtain a copy of the License at
4718 *
4719 * http://www.apache.org/licenses/LICENSE-2.0
4720 *
4721 * Unless required by applicable law or agreed to in writing, software
4722 * distributed under the License is distributed on an "AS IS" BASIS,
4723 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4724 * See the License for the specific language governing permissions and
4725 * limitations under the License.
4726 *
4727 * @providesModule ReactCurrentOwner
4728 */
4729
4730"use strict";
4731
4732/**
4733 * Keeps track of the current owner.
4734 *
4735 * The current owner is the component who should own any components that are
4736 * currently being constructed.
4737 *
4738 * The depth indicate how many composite components are above this render level.
4739 */
4740var ReactCurrentOwner = {
4741
4742 /**
4743 * @internal
4744 * @type {ReactComponent}
4745 */
4746 current: null
4747
4748};
4749
4750module.exports = ReactCurrentOwner;
4751
4752},{}],28:[function(require,module,exports){
4753/**
4754 * Copyright 2013 Facebook, Inc.
4755 *
4756 * Licensed under the Apache License, Version 2.0 (the "License");
4757 * you may not use this file except in compliance with the License.
4758 * You may obtain a copy of the License at
4759 *
4760 * http://www.apache.org/licenses/LICENSE-2.0
4761 *
4762 * Unless required by applicable law or agreed to in writing, software
4763 * distributed under the License is distributed on an "AS IS" BASIS,
4764 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4765 * See the License for the specific language governing permissions and
4766 * limitations under the License.
4767 *
4768 * @providesModule ReactDOM
4769 * @typechecks static-only
4770 */
4771
4772"use strict";
4773
4774var ReactNativeComponent = require("./ReactNativeComponent");
4775
4776var mergeInto = require("./mergeInto");
4777var objMapKeyVal = require("./objMapKeyVal");
4778
4779/**
4780 * Creates a new React class that is idempotent and capable of containing other
4781 * React components. It accepts event listeners and DOM properties that are
4782 * valid according to `DOMProperty`.
4783 *
4784 * - Event listeners: `onClick`, `onMouseDown`, etc.
4785 * - DOM properties: `className`, `name`, `title`, etc.
4786 *
4787 * The `style` property functions differently from the DOM API. It accepts an
4788 * object mapping of style properties to values.
4789 *
4790 * @param {string} tag Tag name (e.g. `div`).
4791 * @param {boolean} omitClose True if the close tag should be omitted.
4792 * @private
4793 */
4794function createDOMComponentClass(tag, omitClose) {
4795 var Constructor = function() {};
4796 Constructor.prototype = new ReactNativeComponent(tag, omitClose);
4797 Constructor.prototype.constructor = Constructor;
4798
4799 var ConvenienceConstructor = function(props, children) {
4800 var instance = new Constructor();
4801 instance.construct.apply(instance, arguments);
4802 return instance;
4803 };
4804 ConvenienceConstructor.componentConstructor = Constructor;
4805 return ConvenienceConstructor;
4806}
4807
4808/**
4809 * Creates a mapping from supported HTML tags to `ReactNativeComponent` classes.
4810 * This is also accessible via `React.DOM`.
4811 *
4812 * @public
4813 */
4814var ReactDOM = objMapKeyVal({
4815 a: false,
4816 abbr: false,
4817 address: false,
4818 area: false,
4819 article: false,
4820 aside: false,
4821 audio: false,
4822 b: false,
4823 base: false,
4824 bdi: false,
4825 bdo: false,
4826 big: false,
4827 blockquote: false,
4828 body: false,
4829 br: true,
4830 button: false,
4831 canvas: false,
4832 caption: false,
4833 cite: false,
4834 code: false,
4835 col: true,
4836 colgroup: false,
4837 data: false,
4838 datalist: false,
4839 dd: false,
4840 del: false,
4841 details: false,
4842 dfn: false,
4843 div: false,
4844 dl: false,
4845 dt: false,
4846 em: false,
4847 embed: true,
4848 fieldset: false,
4849 figcaption: false,
4850 figure: false,
4851 footer: false,
4852 form: false, // NOTE: Injected, see `ReactDOMForm`.
4853 h1: false,
4854 h2: false,
4855 h3: false,
4856 h4: false,
4857 h5: false,
4858 h6: false,
4859 head: false,
4860 header: false,
4861 hr: true,
4862 html: false,
4863 i: false,
4864 iframe: false,
4865 img: true,
4866 input: true,
4867 ins: false,
4868 kbd: false,
4869 keygen: true,
4870 label: false,
4871 legend: false,
4872 li: false,
4873 link: false,
4874 main: false,
4875 map: false,
4876 mark: false,
4877 menu: false,
4878 menuitem: false, // NOTE: Close tag should be omitted, but causes problems.
4879 meta: true,
4880 meter: false,
4881 nav: false,
4882 noscript: false,
4883 object: false,
4884 ol: false,
4885 optgroup: false,
4886 option: false,
4887 output: false,
4888 p: false,
4889 param: true,
4890 pre: false,
4891 progress: false,
4892 q: false,
4893 rp: false,
4894 rt: false,
4895 ruby: false,
4896 s: false,
4897 samp: false,
4898 script: false,
4899 section: false,
4900 select: false,
4901 small: false,
4902 source: false,
4903 span: false,
4904 strong: false,
4905 style: false,
4906 sub: false,
4907 summary: false,
4908 sup: false,
4909 table: false,
4910 tbody: false,
4911 td: false,
4912 textarea: false, // NOTE: Injected, see `ReactDOMTextarea`.
4913 tfoot: false,
4914 th: false,
4915 thead: false,
4916 time: false,
4917 title: false,
4918 tr: false,
4919 track: true,
4920 u: false,
4921 ul: false,
4922 'var': false,
4923 video: false,
4924 wbr: false,
4925
4926 // SVG
4927 circle: false,
4928 g: false,
4929 line: false,
4930 path: false,
4931 polyline: false,
4932 rect: false,
4933 svg: false,
4934 text: false
4935}, createDOMComponentClass);
4936
4937var injection = {
4938 injectComponentClasses: function(componentClasses) {
4939 mergeInto(ReactDOM, componentClasses);
4940 }
4941};
4942
4943ReactDOM.injection = injection;
4944
4945module.exports = ReactDOM;
4946
4947},{"./ReactNativeComponent":48,"./mergeInto":97,"./objMapKeyVal":101}],29:[function(require,module,exports){
4948/**
4949 * Copyright 2013 Facebook, Inc.
4950 *
4951 * Licensed under the Apache License, Version 2.0 (the "License");
4952 * you may not use this file except in compliance with the License.
4953 * You may obtain a copy of the License at
4954 *
4955 * http://www.apache.org/licenses/LICENSE-2.0
4956 *
4957 * Unless required by applicable law or agreed to in writing, software
4958 * distributed under the License is distributed on an "AS IS" BASIS,
4959 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4960 * See the License for the specific language governing permissions and
4961 * limitations under the License.
4962 *
4963 * @providesModule ReactDOMButton
4964 */
4965
4966"use strict";
4967
4968var ReactCompositeComponent = require("./ReactCompositeComponent");
4969var ReactDOM = require("./ReactDOM");
4970
4971var keyMirror = require("./keyMirror");
4972
4973// Store a reference to the <button> `ReactNativeComponent`.
4974var button = ReactDOM.button;
4975
4976var mouseListenerNames = keyMirror({
4977 onClick: true,
4978 onDoubleClick: true,
4979 onMouseDown: true,
4980 onMouseMove: true,
4981 onMouseUp: true,
4982 onClickCapture: true,
4983 onDoubleClickCapture: true,
4984 onMouseDownCapture: true,
4985 onMouseMoveCapture: true,
4986 onMouseUpCapture: true
4987});
4988
4989/**
4990 * Implements a <button> native component that does not receive mouse events
4991 * when `disabled` is set.
4992 */
4993var ReactDOMButton = ReactCompositeComponent.createClass({
4994
4995 render: function() {
4996 var props = {};
4997
4998 // Copy the props; except the mouse listeners if we're disabled
4999 for (var key in this.props) {
5000 if (this.props.hasOwnProperty(key) &&
5001 (!this.props.disabled || !mouseListenerNames[key])) {
5002 props[key] = this.props[key];
5003 }
5004 }
5005
5006 return button(props, this.props.children);
5007 }
5008
5009});
5010
5011module.exports = ReactDOMButton;
5012
5013},{"./ReactCompositeComponent":26,"./ReactDOM":28,"./keyMirror":92}],30:[function(require,module,exports){
5014/**
5015 * Copyright 2013 Facebook, Inc.
5016 *
5017 * Licensed under the Apache License, Version 2.0 (the "License");
5018 * you may not use this file except in compliance with the License.
5019 * You may obtain a copy of the License at
5020 *
5021 * http://www.apache.org/licenses/LICENSE-2.0
5022 *
5023 * Unless required by applicable law or agreed to in writing, software
5024 * distributed under the License is distributed on an "AS IS" BASIS,
5025 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5026 * See the License for the specific language governing permissions and
5027 * limitations under the License.
5028 *
5029 * @providesModule ReactDOMForm
5030 */
5031
5032"use strict";
5033
5034var ReactCompositeComponent = require("./ReactCompositeComponent");
5035var ReactDOM = require("./ReactDOM");
5036var ReactEventEmitter = require("./ReactEventEmitter");
5037var EventConstants = require("./EventConstants");
5038
5039// Store a reference to the <form> `ReactNativeComponent`.
5040var form = ReactDOM.form;
5041
5042/**
5043 * Since onSubmit doesn't bubble OR capture on the top level in IE8, we need
5044 * to capture it on the <form> element itself. There are lots of hacks we could
5045 * do to accomplish this, but the most reliable is to make <form> a
5046 * composite component and use `componentDidMount` to attach the event handlers.
5047 */
5048var ReactDOMForm = ReactCompositeComponent.createClass({
5049 render: function() {
5050 // TODO: Instead of using `ReactDOM` directly, we should use JSX. However,
5051 // `jshint` fails to parse JSX so in order for linting to work in the open
5052 // source repo, we need to just use `ReactDOM.form`.
5053 return this.transferPropsTo(form(null, this.props.children));
5054 },
5055
5056 componentDidMount: function(node) {
5057 ReactEventEmitter.trapBubbledEvent(
5058 EventConstants.topLevelTypes.topSubmit,
5059 'submit',
5060 node
5061 );
5062 }
5063});
5064
5065module.exports = ReactDOMForm;
5066
5067},{"./EventConstants":13,"./ReactCompositeComponent":26,"./ReactDOM":28,"./ReactEventEmitter":39}],31:[function(require,module,exports){
5068/**
5069 * Copyright 2013 Facebook, Inc.
5070 *
5071 * Licensed under the Apache License, Version 2.0 (the "License");
5072 * you may not use this file except in compliance with the License.
5073 * You may obtain a copy of the License at
5074 *
5075 * http://www.apache.org/licenses/LICENSE-2.0
5076 *
5077 * Unless required by applicable law or agreed to in writing, software
5078 * distributed under the License is distributed on an "AS IS" BASIS,
5079 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5080 * See the License for the specific language governing permissions and
5081 * limitations under the License.
5082 *
5083 * @providesModule ReactDOMIDOperations
5084 * @typechecks static-only
5085 */
5086
5087/*jslint evil: true */
5088
5089"use strict";
5090
5091var CSSPropertyOperations = require("./CSSPropertyOperations");
5092var DOMChildrenOperations = require("./DOMChildrenOperations");
5093var DOMPropertyOperations = require("./DOMPropertyOperations");
5094var ReactMount = require("./ReactMount");
5095
5096var getTextContentAccessor = require("./getTextContentAccessor");
5097var invariant = require("./invariant");
5098
5099/**
5100 * Errors for properties that should not be updated with `updatePropertyById()`.
5101 *
5102 * @type {object}
5103 * @private
5104 */
5105var INVALID_PROPERTY_ERRORS = {
5106 dangerouslySetInnerHTML:
5107 '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',
5108 style: '`style` must be set using `updateStylesByID()`.'
5109};
5110
5111/**
5112 * The DOM property to use when setting text content.
5113 *
5114 * @type {string}
5115 * @private
5116 */
5117var textContentAccessor = getTextContentAccessor() || 'NA';
5118
5119/**
5120 * Operations used to process updates to DOM nodes. This is made injectable via
5121 * `ReactComponent.DOMIDOperations`.
5122 */
5123var ReactDOMIDOperations = {
5124
5125 /**
5126 * Updates a DOM node with new property values. This should only be used to
5127 * update DOM properties in `DOMProperty`.
5128 *
5129 * @param {string} id ID of the node to update.
5130 * @param {string} name A valid property name, see `DOMProperty`.
5131 * @param {*} value New value of the property.
5132 * @internal
5133 */
5134 updatePropertyByID: function(id, name, value) {
5135 var node = ReactMount.getNode(id);
5136 invariant(
5137 !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
5138 'updatePropertyByID(...): %s',
5139 INVALID_PROPERTY_ERRORS[name]
5140 );
5141
5142 // If we're updating to null or undefined, we should remove the property
5143 // from the DOM node instead of inadvertantly setting to a string. This
5144 // brings us in line with the same behavior we have on initial render.
5145 if (value != null) {
5146 DOMPropertyOperations.setValueForProperty(node, name, value);
5147 } else {
5148 DOMPropertyOperations.deleteValueForProperty(node, name);
5149 }
5150 },
5151
5152 /**
5153 * Updates a DOM node to remove a property. This should only be used to remove
5154 * DOM properties in `DOMProperty`.
5155 *
5156 * @param {string} id ID of the node to update.
5157 * @param {string} name A property name to remove, see `DOMProperty`.
5158 * @internal
5159 */
5160 deletePropertyByID: function(id, name, value) {
5161 var node = ReactMount.getNode(id);
5162 invariant(
5163 !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
5164 'updatePropertyByID(...): %s',
5165 INVALID_PROPERTY_ERRORS[name]
5166 );
5167 DOMPropertyOperations.deleteValueForProperty(node, name, value);
5168 },
5169
5170 /**
5171 * This should almost never be used instead of `updatePropertyByID()` due to
5172 * the extra object allocation required by the API. That said, this is useful
5173 * for batching up several operations across worker thread boundaries.
5174 *
5175 * @param {string} id ID of the node to update.
5176 * @param {object} properties A mapping of valid property names.
5177 * @internal
5178 * @see {ReactDOMIDOperations.updatePropertyByID}
5179 */
5180 updatePropertiesByID: function(id, properties) {
5181 for (var name in properties) {
5182 if (!properties.hasOwnProperty(name)) {
5183 continue;
5184 }
5185 ReactDOMIDOperations.updatePropertiesByID(id, name, properties[name]);
5186 }
5187 },
5188
5189 /**
5190 * Updates a DOM node with new style values. If a value is specified as '',
5191 * the corresponding style property will be unset.
5192 *
5193 * @param {string} id ID of the node to update.
5194 * @param {object} styles Mapping from styles to values.
5195 * @internal
5196 */
5197 updateStylesByID: function(id, styles) {
5198 var node = ReactMount.getNode(id);
5199 CSSPropertyOperations.setValueForStyles(node, styles);
5200 },
5201
5202 /**
5203 * Updates a DOM node's innerHTML set by `props.dangerouslySetInnerHTML`.
5204 *
5205 * @param {string} id ID of the node to update.
5206 * @param {object} html An HTML object with the `__html` property.
5207 * @internal
5208 */
5209 updateInnerHTMLByID: function(id, html) {
5210 var node = ReactMount.getNode(id);
5211 // HACK: IE8- normalize whitespace in innerHTML, removing leading spaces.
5212 // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
5213 node.innerHTML = (html && html.__html || '').replace(/^ /g, '&nbsp;');
5214 },
5215
5216 /**
5217 * Updates a DOM node's text content set by `props.content`.
5218 *
5219 * @param {string} id ID of the node to update.
5220 * @param {string} content Text content.
5221 * @internal
5222 */
5223 updateTextContentByID: function(id, content) {
5224 var node = ReactMount.getNode(id);
5225 node[textContentAccessor] = content;
5226 },
5227
5228 /**
5229 * Replaces a DOM node that exists in the document with markup.
5230 *
5231 * @param {string} id ID of child to be replaced.
5232 * @param {string} markup Dangerous markup to inject in place of child.
5233 * @internal
5234 * @see {Danger.dangerouslyReplaceNodeWithMarkup}
5235 */
5236 dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {
5237 var node = ReactMount.getNode(id);
5238 DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
5239 },
5240
5241 /**
5242 * Updates a component's children by processing a series of updates.
5243 *
5244 * @param {array<object>} updates List of update configurations.
5245 * @param {array<string>} markup List of markup strings.
5246 * @internal
5247 */
5248 dangerouslyProcessChildrenUpdates: function(updates, markup) {
5249 for (var i = 0; i < updates.length; i++) {
5250 updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
5251 }
5252 DOMChildrenOperations.processUpdates(updates, markup);
5253 }
5254
5255};
5256
5257module.exports = ReactDOMIDOperations;
5258
5259},{"./CSSPropertyOperations":3,"./DOMChildrenOperations":6,"./DOMPropertyOperations":8,"./ReactMount":45,"./getTextContentAccessor":87,"./invariant":89}],32:[function(require,module,exports){
5260/**
5261 * Copyright 2013 Facebook, Inc.
5262 *
5263 * Licensed under the Apache License, Version 2.0 (the "License");
5264 * you may not use this file except in compliance with the License.
5265 * You may obtain a copy of the License at
5266 *
5267 * http://www.apache.org/licenses/LICENSE-2.0
5268 *
5269 * Unless required by applicable law or agreed to in writing, software
5270 * distributed under the License is distributed on an "AS IS" BASIS,
5271 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5272 * See the License for the specific language governing permissions and
5273 * limitations under the License.
5274 *
5275 * @providesModule ReactDOMInput
5276 */
5277
5278"use strict";
5279
5280var DOMPropertyOperations = require("./DOMPropertyOperations");
5281var ReactCompositeComponent = require("./ReactCompositeComponent");
5282var ReactDOM = require("./ReactDOM");
5283var ReactMount = require("./ReactMount");
5284
5285var invariant = require("./invariant");
5286var merge = require("./merge");
5287
5288// Store a reference to the <input> `ReactNativeComponent`.
5289var input = ReactDOM.input;
5290
5291var instancesByReactID = {};
5292
5293/**
5294 * Implements an <input> native component that allows setting these optional
5295 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
5296 *
5297 * If `checked` or `value` are not supplied (or null/undefined), user actions
5298 * that affect the checked state or value will trigger updates to the element.
5299 *
5300 * If they are supplied (and not null/undefined), the rendered element will not
5301 * trigger updates to the element. Instead, the props must change in order for
5302 * the rendered element to be updated.
5303 *
5304 * The rendered element will be initialized as unchecked (or `defaultChecked`)
5305 * with an empty value (or `defaultValue`).
5306 *
5307 * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
5308 */
5309var ReactDOMInput = ReactCompositeComponent.createClass({
5310
5311 getInitialState: function() {
5312 var defaultValue = this.props.defaultValue;
5313 return {
5314 checked: this.props.defaultChecked || false,
5315 value: defaultValue != null && defaultValue !== false ? defaultValue : ''
5316 };
5317 },
5318
5319 shouldComponentUpdate: function() {
5320 // Defer any updates to this component during the `onChange` handler.
5321 return !this._isChanging;
5322 },
5323
5324 render: function() {
5325 // Clone `this.props` so we don't mutate the input.
5326 var props = merge(this.props);
5327
5328 props.defaultChecked = null;
5329 props.defaultValue = null;
5330 props.checked =
5331 this.props.checked != null ? this.props.checked : this.state.checked;
5332
5333 props.value = this.props.value != null && this.props.value !== false
5334 ? '' + this.props.value
5335 : this.state.value;
5336
5337 props.onChange = this._handleChange;
5338
5339 return input(props, this.props.children);
5340 },
5341
5342 componentDidMount: function(rootNode) {
5343 var id = ReactMount.getID(rootNode);
5344 instancesByReactID[id] = this;
5345 },
5346
5347 componentWillUnmount: function() {
5348 var rootNode = this.getDOMNode();
5349 var id = ReactMount.getID(rootNode);
5350 delete instancesByReactID[id];
5351 },
5352
5353 componentDidUpdate: function(prevProps, prevState, rootNode) {
5354 if (this.props.checked != null) {
5355 DOMPropertyOperations.setValueForProperty(
5356 rootNode,
5357 'checked',
5358 this.props.checked || false
5359 );
5360 }
5361 if (this.props.value != null) {
5362 // Cast `this.props.value` to a string so falsey values that cast to
5363 // truthy strings are not ignored.
5364 DOMPropertyOperations.setValueForProperty(
5365 rootNode,
5366 'value',
5367 this.props.value !== false ? '' + this.props.value : ''
5368 );
5369 }
5370 },
5371
5372 _handleChange: function(event) {
5373 var returnValue;
5374 if (this.props.onChange) {
5375 this._isChanging = true;
5376 returnValue = this.props.onChange(event);
5377 this._isChanging = false;
5378 }
5379 this.setState({
5380 checked: event.target.checked,
5381 value: event.target.value
5382 });
5383
5384 var name = this.props.name;
5385 if (this.props.type === 'radio' && name != null) {
5386 var rootNode = this.getDOMNode();
5387 // If `rootNode.form` was non-null, then we could try `form.elements`,
5388 // but that sometimes behaves strangely in IE8. We could also try using
5389 // `form.getElementsByName`, but that will only return direct children
5390 // and won't include inputs that use the HTML5 `form=` attribute. Since
5391 // the input might not even be in a form, let's just use the global
5392 // `getElementsByName` to ensure we don't miss anything.
5393 var group = document.getElementsByName(name);
5394 for (var i = 0, groupLen = group.length; i < groupLen; i++) {
5395 var otherNode = group[i];
5396 if (otherNode === rootNode ||
5397 otherNode.nodeName !== 'INPUT' || otherNode.type !== 'radio' ||
5398 otherNode.form !== rootNode.form) {
5399 continue;
5400 }
5401 var otherID = ReactMount.getID(otherNode);
5402 invariant(
5403 otherID,
5404 'ReactDOMInput: Mixing React and non-React radio inputs with the ' +
5405 'same `name` is not supported.'
5406 );
5407 var otherInstance = instancesByReactID[otherID];
5408 invariant(
5409 otherInstance,
5410 'ReactDOMInput: Unknown radio button ID %s.',
5411 otherID
5412 );
5413 // In some cases, this will actually change the `checked` state value.
5414 // In other cases, there's no change but this forces a reconcile upon
5415 // which componentDidUpdate will reset the DOM property to whatever it
5416 // should be.
5417 otherInstance.setState({
5418 checked: false
5419 });
5420 }
5421 }
5422
5423 return returnValue;
5424 }
5425
5426});
5427
5428module.exports = ReactDOMInput;
5429
5430},{"./DOMPropertyOperations":8,"./ReactCompositeComponent":26,"./ReactDOM":28,"./ReactMount":45,"./invariant":89,"./merge":95}],33:[function(require,module,exports){
5431/**
5432 * Copyright 2013 Facebook, Inc.
5433 *
5434 * Licensed under the Apache License, Version 2.0 (the "License");
5435 * you may not use this file except in compliance with the License.
5436 * You may obtain a copy of the License at
5437 *
5438 * http://www.apache.org/licenses/LICENSE-2.0
5439 *
5440 * Unless required by applicable law or agreed to in writing, software
5441 * distributed under the License is distributed on an "AS IS" BASIS,
5442 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5443 * See the License for the specific language governing permissions and
5444 * limitations under the License.
5445 *
5446 * @providesModule ReactDOMOption
5447 */
5448
5449"use strict";
5450
5451var ReactCompositeComponent = require("./ReactCompositeComponent");
5452var ReactDOM = require("./ReactDOM");
5453
5454// Store a reference to the <option> `ReactNativeComponent`.
5455var option = ReactDOM.option;
5456
5457/**
5458 * Implements an <option> native component that warns when `selected` is set.
5459 */
5460var ReactDOMOption = ReactCompositeComponent.createClass({
5461
5462 componentWillMount: function() {
5463 // TODO (yungsters): Remove support for `selected` in <option>.
5464 if (this.props.selected != null) {
5465 if (true) {
5466 console.warn(
5467 'Use the `defaultValue` or `value` props on <select> instead of ' +
5468 'setting `selected` on <option>.'
5469 );
5470 }
5471 }
5472 },
5473
5474 render: function() {
5475 return option(this.props, this.props.children);
5476 }
5477
5478});
5479
5480module.exports = ReactDOMOption;
5481
5482},{"./ReactCompositeComponent":26,"./ReactDOM":28}],34:[function(require,module,exports){
5483/**
5484 * Copyright 2013 Facebook, Inc.
5485 *
5486 * Licensed under the Apache License, Version 2.0 (the "License");
5487 * you may not use this file except in compliance with the License.
5488 * You may obtain a copy of the License at
5489 *
5490 * http://www.apache.org/licenses/LICENSE-2.0
5491 *
5492 * Unless required by applicable law or agreed to in writing, software
5493 * distributed under the License is distributed on an "AS IS" BASIS,
5494 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5495 * See the License for the specific language governing permissions and
5496 * limitations under the License.
5497 *
5498 * @providesModule ReactDOMSelect
5499 */
5500
5501"use strict";
5502
5503var ReactCompositeComponent = require("./ReactCompositeComponent");
5504var ReactDOM = require("./ReactDOM");
5505
5506var invariant = require("./invariant");
5507var merge = require("./merge");
5508
5509// Store a reference to the <select> `ReactNativeComponent`.
5510var select = ReactDOM.select;
5511
5512/**
5513 * Validation function for `value` and `defaultValue`.
5514 * @private
5515 */
5516function selectValueType(props, propName, componentName) {
5517 if (props[propName] == null) {
5518 return;
5519 }
5520 if (props.multiple) {
5521 invariant(
5522 Array.isArray(props[propName]),
5523 'The `%s` prop supplied to <select> must be an array if `multiple` is ' +
5524 'true.',
5525 propName
5526 );
5527 } else {
5528 invariant(
5529 !Array.isArray(props[propName]),
5530 'The `%s` prop supplied to <select> must be a scalar value if ' +
5531 '`multiple` is false.',
5532 propName
5533 );
5534 }
5535}
5536
5537/**
5538 * If `value` is supplied, updates <option> elements on mount and update.
5539 * @private
5540 */
5541function updateOptions() {
5542 /*jshint validthis:true */
5543 var value = this.props.value != null ? this.props.value : this.state.value;
5544 var options = this.getDOMNode().options;
5545 var selectedValue = '' + value;
5546
5547 for (var i = 0, l = options.length; i < l; i++) {
5548 var selected = this.props.multiple ?
5549 selectedValue.indexOf(options[i].value) >= 0 :
5550 selected = options[i].value === selectedValue;
5551
5552 if (selected !== options[i].selected) {
5553 options[i].selected = selected;
5554 }
5555 }
5556}
5557
5558/**
5559 * Implements a <select> native component that allows optionally setting the
5560 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
5561 * string. If `multiple` is true, the prop must be an array of strings.
5562 *
5563 * If `value` is not supplied (or null/undefined), user actions that change the
5564 * selected option will trigger updates to the rendered options.
5565 *
5566 * If it is supplied (and not null/undefined), the rendered options will not
5567 * update in response to user actions. Instead, the `value` prop must change in
5568 * order for the rendered options to update.
5569 *
5570 * If `defaultValue` is provided, any options with the supplied values will be
5571 * selected.
5572 */
5573var ReactDOMSelect = ReactCompositeComponent.createClass({
5574
5575 propTypes: {
5576 defaultValue: selectValueType,
5577 value: selectValueType
5578 },
5579
5580 getInitialState: function() {
5581 return {value: this.props.defaultValue || (this.props.multiple ? [] : '')};
5582 },
5583
5584 componentWillReceiveProps: function(nextProps) {
5585 if (!this.props.multiple && nextProps.multiple) {
5586 this.setState({value: [this.state.value]});
5587 } else if (this.props.multiple && !nextProps.multiple) {
5588 this.setState({value: this.state.value[0]});
5589 }
5590 },
5591
5592 shouldComponentUpdate: function() {
5593 // Defer any updates to this component during the `onChange` handler.
5594 return !this._isChanging;
5595 },
5596
5597 render: function() {
5598 // Clone `this.props` so we don't mutate the input.
5599 var props = merge(this.props);
5600
5601 props.onChange = this._handleChange;
5602 props.value = null;
5603
5604 return select(props, this.props.children);
5605 },
5606
5607 componentDidMount: updateOptions,
5608
5609 componentDidUpdate: updateOptions,
5610
5611 _handleChange: function(event) {
5612 var returnValue;
5613 if (this.props.onChange) {
5614 this._isChanging = true;
5615 returnValue = this.props.onChange(event);
5616 this._isChanging = false;
5617 }
5618
5619 var selectedValue;
5620 if (this.props.multiple) {
5621 selectedValue = [];
5622 var options = event.target.options;
5623 for (var i = 0, l = options.length; i < l; i++) {
5624 if (options[i].selected) {
5625 selectedValue.push(options[i].value);
5626 }
5627 }
5628 } else {
5629 selectedValue = event.target.value;
5630 }
5631
5632 this.setState({value: selectedValue});
5633 return returnValue;
5634 }
5635
5636});
5637
5638module.exports = ReactDOMSelect;
5639
5640},{"./ReactCompositeComponent":26,"./ReactDOM":28,"./invariant":89,"./merge":95}],35:[function(require,module,exports){
5641/**
5642 * Copyright 2013 Facebook, Inc.
5643 *
5644 * Licensed under the Apache License, Version 2.0 (the "License");
5645 * you may not use this file except in compliance with the License.
5646 * You may obtain a copy of the License at
5647 *
5648 * http://www.apache.org/licenses/LICENSE-2.0
5649 *
5650 * Unless required by applicable law or agreed to in writing, software
5651 * distributed under the License is distributed on an "AS IS" BASIS,
5652 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5653 * See the License for the specific language governing permissions and
5654 * limitations under the License.
5655 *
5656 * @providesModule ReactDOMTextarea
5657 */
5658
5659"use strict";
5660
5661var DOMPropertyOperations = require("./DOMPropertyOperations");
5662var ReactCompositeComponent = require("./ReactCompositeComponent");
5663var ReactDOM = require("./ReactDOM");
5664
5665var invariant = require("./invariant");
5666var merge = require("./merge");
5667
5668// Store a reference to the <textarea> `ReactNativeComponent`.
5669var textarea = ReactDOM.textarea;
5670
5671// For quickly matching children type, to test if can be treated as content.
5672var CONTENT_TYPES = {'string': true, 'number': true};
5673
5674/**
5675 * Implements a <textarea> native component that allows setting `value`, and
5676 * `defaultValue`. This differs from the traditional DOM API because value is
5677 * usually set as PCDATA children.
5678 *
5679 * If `value` is not supplied (or null/undefined), user actions that affect the
5680 * value will trigger updates to the element.
5681 *
5682 * If `value` is supplied (and not null/undefined), the rendered element will
5683 * not trigger updates to the element. Instead, the `value` prop must change in
5684 * order for the rendered element to be updated.
5685 *
5686 * The rendered element will be initialized with an empty value, the prop
5687 * `defaultValue` if specified, or the children content (deprecated).
5688 */
5689var ReactDOMTextarea = ReactCompositeComponent.createClass({
5690
5691 getInitialState: function() {
5692 var defaultValue = this.props.defaultValue;
5693 // TODO (yungsters): Remove support for children content in <textarea>.
5694 var children = this.props.children;
5695 if (children != null) {
5696 if (true) {
5697 console.warn(
5698 'Use the `defaultValue` or `value` props instead of setting ' +
5699 'children on <textarea>.'
5700 );
5701 }
5702 invariant(
5703 defaultValue == null,
5704 'If you supply `defaultValue` on a <textarea>, do not pass children.'
5705 );
5706 if (Array.isArray(children)) {
5707 invariant(
5708 children.length <= 1,
5709 '<textarea> can only have at most one child.'
5710 );
5711 children = children[0];
5712 }
5713 invariant(
5714 CONTENT_TYPES[typeof children],
5715 'If you specify children to <textarea>, it must be a single string ' +
5716 'or number., not an array or object.'
5717 );
5718 defaultValue = '' + children;
5719 }
5720 if (defaultValue == null) {
5721 defaultValue = '';
5722 }
5723 return {
5724 // We save the initial value so that `ReactNativeComponent` doesn't update
5725 // `textContent` (unnecessary since we update value).
5726 initialValue: this.props.value != null ? this.props.value : defaultValue,
5727 value: defaultValue
5728 };
5729 },
5730
5731 shouldComponentUpdate: function() {
5732 // Defer any updates to this component during the `onChange` handler.
5733 return !this._isChanging;
5734 },
5735
5736 render: function() {
5737 // Clone `this.props` so we don't mutate the input.
5738 var props = merge(this.props);
5739
5740 invariant(
5741 props.dangerouslySetInnerHTML == null,
5742 '`dangerouslySetInnerHTML` does not make sense on <textarea>.'
5743 );
5744
5745 props.defaultValue = null;
5746 props.value =
5747 this.props.value != null ? this.props.value : this.state.value;
5748 props.onChange = this._handleChange;
5749
5750 // Always set children to the same thing. In IE9, the selection range will
5751 // get reset if `textContent` is mutated.
5752 return textarea(props, this.state.initialValue);
5753 },
5754
5755 componentDidUpdate: function(prevProps, prevState, rootNode) {
5756 if (this.props.value != null) {
5757 DOMPropertyOperations.setValueForProperty(
5758 rootNode,
5759 'value',
5760 this.props.value !== false ? '' + this.props.value : ''
5761 );
5762 }
5763 },
5764
5765 _handleChange: function(event) {
5766 var returnValue;
5767 if (this.props.onChange) {
5768 this._isChanging = true;
5769 returnValue = this.props.onChange(event);
5770 this._isChanging = false;
5771 }
5772 this.setState({value: event.target.value});
5773 return returnValue;
5774 }
5775
5776});
5777
5778module.exports = ReactDOMTextarea;
5779
5780},{"./DOMPropertyOperations":8,"./ReactCompositeComponent":26,"./ReactDOM":28,"./invariant":89,"./merge":95}],36:[function(require,module,exports){
5781/**
5782 * Copyright 2013 Facebook, Inc.
5783 *
5784 * Licensed under the Apache License, Version 2.0 (the "License");
5785 * you may not use this file except in compliance with the License.
5786 * You may obtain a copy of the License at
5787 *
5788 * http://www.apache.org/licenses/LICENSE-2.0
5789 *
5790 * Unless required by applicable law or agreed to in writing, software
5791 * distributed under the License is distributed on an "AS IS" BASIS,
5792 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5793 * See the License for the specific language governing permissions and
5794 * limitations under the License.
5795 *
5796 * @providesModule ReactDefaultBatchingStrategy
5797 */
5798
5799"use strict";
5800
5801var ReactUpdates = require("./ReactUpdates");
5802var Transaction = require("./Transaction");
5803
5804var emptyFunction = require("./emptyFunction");
5805var mixInto = require("./mixInto");
5806
5807var RESET_BATCHED_UPDATES = {
5808 initialize: emptyFunction,
5809 close: function() {
5810 ReactDefaultBatchingStrategy.isBatchingUpdates = false;
5811 }
5812};
5813
5814var FLUSH_BATCHED_UPDATES = {
5815 initialize: emptyFunction,
5816 close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates)
5817};
5818
5819var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];
5820
5821function ReactDefaultBatchingStrategyTransaction() {
5822 this.reinitializeTransaction();
5823}
5824
5825mixInto(ReactDefaultBatchingStrategyTransaction, Transaction.Mixin);
5826mixInto(ReactDefaultBatchingStrategyTransaction, {
5827 getTransactionWrappers: function() {
5828 return TRANSACTION_WRAPPERS;
5829 }
5830});
5831
5832var transaction = new ReactDefaultBatchingStrategyTransaction();
5833
5834var ReactDefaultBatchingStrategy = {
5835 isBatchingUpdates: false,
5836
5837 /**
5838 * Call the provided function in a context within which calls to `setState`
5839 * and friends are batched such that components aren't updated unnecessarily.
5840 */
5841 batchedUpdates: function(callback, param) {
5842 var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
5843
5844 ReactDefaultBatchingStrategy.isBatchingUpdates = true;
5845
5846 // The code is written this way to avoid extra allocations
5847 if (alreadyBatchingUpdates) {
5848 callback(param);
5849 } else {
5850 transaction.perform(callback, null, param);
5851 }
5852 }
5853};
5854
5855module.exports = ReactDefaultBatchingStrategy;
5856
5857},{"./ReactUpdates":57,"./Transaction":68,"./emptyFunction":77,"./mixInto":98}],37:[function(require,module,exports){
5858/**
5859 * Copyright 2013 Facebook, Inc.
5860 *
5861 * Licensed under the Apache License, Version 2.0 (the "License");
5862 * you may not use this file except in compliance with the License.
5863 * You may obtain a copy of the License at
5864 *
5865 * http://www.apache.org/licenses/LICENSE-2.0
5866 *
5867 * Unless required by applicable law or agreed to in writing, software
5868 * distributed under the License is distributed on an "AS IS" BASIS,
5869 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5870 * See the License for the specific language governing permissions and
5871 * limitations under the License.
5872 *
5873 * @providesModule ReactDefaultInjection
5874 */
5875
5876"use strict";
5877
5878var ReactDOM = require("./ReactDOM");
5879var ReactDOMButton = require("./ReactDOMButton");
5880var ReactDOMForm = require("./ReactDOMForm");
5881var ReactDOMInput = require("./ReactDOMInput");
5882var ReactDOMOption = require("./ReactDOMOption");
5883var ReactDOMSelect = require("./ReactDOMSelect");
5884var ReactDOMTextarea = require("./ReactDOMTextarea");
5885var ReactEventEmitter = require("./ReactEventEmitter");
5886var ReactEventTopLevelCallback = require("./ReactEventTopLevelCallback");
5887var ReactPerf = require("./ReactPerf");
5888
5889var DefaultDOMPropertyConfig = require("./DefaultDOMPropertyConfig");
5890var DOMProperty = require("./DOMProperty");
5891
5892var DefaultEventPluginOrder = require("./DefaultEventPluginOrder");
5893var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin");
5894var ChangeEventPlugin = require("./ChangeEventPlugin");
5895var EventPluginHub = require("./EventPluginHub");
5896var ReactInstanceHandles = require("./ReactInstanceHandles");
5897var SimpleEventPlugin = require("./SimpleEventPlugin");
5898var MobileSafariClickEventPlugin = require("./MobileSafariClickEventPlugin");
5899
5900var ReactDefaultBatchingStrategy = require("./ReactDefaultBatchingStrategy");
5901var ReactUpdates = require("./ReactUpdates");
5902
5903function inject() {
5904 ReactEventEmitter.TopLevelCallbackCreator = ReactEventTopLevelCallback;
5905 /**
5906 * Inject module for resolving DOM hierarchy and plugin ordering.
5907 */
5908 EventPluginHub.injection.injectEventPluginOrder(DefaultEventPluginOrder);
5909 EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles);
5910
5911 /**
5912 * Some important event plugins included by default (without having to require
5913 * them).
5914 */
5915 EventPluginHub.injection.injectEventPluginsByName({
5916 'SimpleEventPlugin': SimpleEventPlugin,
5917 'EnterLeaveEventPlugin': EnterLeaveEventPlugin,
5918 'ChangeEventPlugin': ChangeEventPlugin,
5919 'MobileSafariClickEventPlugin': MobileSafariClickEventPlugin
5920 });
5921
5922 ReactDOM.injection.injectComponentClasses({
5923 button: ReactDOMButton,
5924 form: ReactDOMForm,
5925 input: ReactDOMInput,
5926 option: ReactDOMOption,
5927 select: ReactDOMSelect,
5928 textarea: ReactDOMTextarea
5929 });
5930
5931 DOMProperty.injection.injectDOMPropertyConfig(DefaultDOMPropertyConfig);
5932
5933 if (true) {
5934 ReactPerf.injection.injectMeasure(require("./ReactDefaultPerf").measure);
5935 }
5936
5937 ReactUpdates.injection.injectBatchingStrategy(
5938 ReactDefaultBatchingStrategy
5939 );
5940}
5941
5942module.exports = {
5943 inject: inject
5944};
5945
5946},{"./ChangeEventPlugin":5,"./DOMProperty":7,"./DefaultDOMPropertyConfig":10,"./DefaultEventPluginOrder":11,"./EnterLeaveEventPlugin":12,"./EventPluginHub":15,"./MobileSafariClickEventPlugin":20,"./ReactDOM":28,"./ReactDOMButton":29,"./ReactDOMForm":30,"./ReactDOMInput":32,"./ReactDOMOption":33,"./ReactDOMSelect":34,"./ReactDOMTextarea":35,"./ReactDefaultBatchingStrategy":36,"./ReactDefaultPerf":38,"./ReactEventEmitter":39,"./ReactEventTopLevelCallback":41,"./ReactInstanceHandles":43,"./ReactPerf":51,"./ReactUpdates":57,"./SimpleEventPlugin":58}],38:[function(require,module,exports){
5947/**
5948 * Copyright 2013 Facebook, Inc.
5949 *
5950 * Licensed under the Apache License, Version 2.0 (the "License");
5951 * you may not use this file except in compliance with the License.
5952 * You may obtain a copy of the License at
5953 *
5954 * http://www.apache.org/licenses/LICENSE-2.0
5955 *
5956 * Unless required by applicable law or agreed to in writing, software
5957 * distributed under the License is distributed on an "AS IS" BASIS,
5958 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5959 * See the License for the specific language governing permissions and
5960 * limitations under the License.
5961 *
5962 * @providesModule ReactDefaultPerf
5963 * @typechecks static-only
5964 */
5965
5966"use strict";
5967
5968var performanceNow = require("./performanceNow");
5969
5970var ReactDefaultPerf = {};
5971
5972if (true) {
5973 ReactDefaultPerf = {
5974 /**
5975 * Gets the stored information for a given object's function.
5976 *
5977 * @param {string} objName
5978 * @param {string} fnName
5979 * @return {?object}
5980 */
5981 getInfo: function(objName, fnName) {
5982 if (!this.info[objName] || !this.info[objName][fnName]) {
5983 return null;
5984 }
5985 return this.info[objName][fnName];
5986 },
5987
5988 /**
5989 * Gets the logs pertaining to a given object's function.
5990 *
5991 * @param {string} objName
5992 * @param {string} fnName
5993 * @return {?array<object>}
5994 */
5995 getLogs: function(objName, fnName) {
5996 if (!this.getInfo(objName, fnName)) {
5997 return null;
5998 }
5999 return this.logs.filter(function(log) {
6000 return log.objName === objName && log.fnName === fnName;
6001 });
6002 },
6003
6004 /**
6005 * Runs through the logs and builds an array of arrays, where each array
6006 * walks through the mounting/updating of each component underneath.
6007 *
6008 * @param {string} rootID The reactID of the root node, e.g. '.r[2cpyq]'
6009 * @return {array<array>}
6010 */
6011 getRawRenderHistory: function(rootID) {
6012 var history = [];
6013 /**
6014 * Since logs are added after the method returns, the logs are in a sense
6015 * upside-down: the inner-most elements from mounting/updating are logged
6016 * first, and the last addition to the log is the top renderComponent.
6017 * Therefore, we flip the logs upside down for ease of processing, and
6018 * reverse the history array at the end so the earliest event has index 0.
6019 */
6020 var logs = this.logs.filter(function(log) {
6021 return log.reactID.indexOf(rootID) === 0;
6022 }).reverse();
6023
6024 var subHistory = [];
6025 logs.forEach(function(log, i) {
6026 if (i && log.reactID === rootID && logs[i - 1].reactID !== rootID) {
6027 subHistory.length && history.push(subHistory);
6028 subHistory = [];
6029 }
6030 subHistory.push(log);
6031 });
6032 if (subHistory.length) {
6033 history.push(subHistory);
6034 }
6035 return history.reverse();
6036 },
6037
6038 /**
6039 * Runs through the logs and builds an array of strings, where each string
6040 * is a multiline formatted way of walking through the mounting/updating
6041 * underneath.
6042 *
6043 * @param {string} rootID The reactID of the root node, e.g. '.r[2cpyq]'
6044 * @return {array<string>}
6045 */
6046 getRenderHistory: function(rootID) {
6047 var history = this.getRawRenderHistory(rootID);
6048
6049 return history.map(function(subHistory) {
6050 var headerString = (
6051 'log# Component (execution time) [bloat from logging]\n' +
6052 '================================================================\n'
6053 );
6054 return headerString + subHistory.map(function(log) {
6055 // Add two spaces for every layer in the reactID.
6056 var indents = '\t' + Array(log.reactID.split('.[').length).join(' ');
6057 var delta = _microTime(log.timing.delta);
6058 var bloat = _microTime(log.timing.timeToLog);
6059
6060 return log.index + indents + log.name + ' (' + delta + 'ms)' +
6061 ' [' + bloat + 'ms]';
6062 }).join('\n');
6063 });
6064 },
6065
6066 /**
6067 * Print the render history from `getRenderHistory` using console.log.
6068 * This is currently the best way to display perf data from
6069 * any React component; working on that.
6070 *
6071 * @param {string} rootID The reactID of the root node, e.g. '.r[2cpyq]'
6072 * @param {number} index
6073 */
6074 printRenderHistory: function(rootID, index) {
6075 var history = this.getRenderHistory(rootID);
6076 if (!history[index]) {
6077 console.warn(
6078 'Index', index, 'isn\'t available! ' +
6079 'The render history is', history.length, 'long.'
6080 );
6081 return;
6082 }
6083 console.log(
6084 'Loading render history #' + (index + 1) +
6085 ' of ' + history.length + ':\n' + history[index]
6086 );
6087 },
6088
6089 /**
6090 * Prints the heatmap legend to console, showing how the colors correspond
6091 * with render times. This relies on console.log styles.
6092 */
6093 printHeatmapLegend: function() {
6094 if (!this.options.heatmap.enabled) {
6095 return;
6096 }
6097 var max = this.info.React
6098 && this.info.React.renderComponent
6099 && this.info.React.renderComponent.max;
6100 if (max) {
6101 var logStr = 'Heatmap: ';
6102 for (var ii = 0; ii <= 10 * max; ii += max) {
6103 logStr += '%c ' + (Math.round(ii) / 10) + 'ms ';
6104 }
6105 console.log(
6106 logStr,
6107 'background-color: hsla(100, 100%, 50%, 0.6);',
6108 'background-color: hsla( 90, 100%, 50%, 0.6);',
6109 'background-color: hsla( 80, 100%, 50%, 0.6);',
6110 'background-color: hsla( 70, 100%, 50%, 0.6);',
6111 'background-color: hsla( 60, 100%, 50%, 0.6);',
6112 'background-color: hsla( 50, 100%, 50%, 0.6);',
6113 'background-color: hsla( 40, 100%, 50%, 0.6);',
6114 'background-color: hsla( 30, 100%, 50%, 0.6);',
6115 'background-color: hsla( 20, 100%, 50%, 0.6);',
6116 'background-color: hsla( 10, 100%, 50%, 0.6);',
6117 'background-color: hsla( 0, 100%, 50%, 0.6);'
6118 );
6119 }
6120 },
6121
6122 /**
6123 * Measure a given function with logging information, and calls a callback
6124 * if there is one.
6125 *
6126 * @param {string} objName
6127 * @param {string} fnName
6128 * @param {function} func
6129 * @return {function}
6130 */
6131 measure: function(objName, fnName, func) {
6132 var info = _getNewInfo(objName, fnName);
6133
6134 var fnArgs = _getFnArguments(func);
6135
6136 return function() {
6137 var timeBeforeFn = performanceNow();
6138 var fnReturn = func.apply(this, arguments);
6139 var timeAfterFn = performanceNow();
6140
6141 /**
6142 * Hold onto arguments in a readable way: args[1] -> args.component.
6143 * args is also passed to the callback, so if you want to save an
6144 * argument in the log, do so in the callback.
6145 */
6146 var args = {};
6147 for (var i = 0; i < arguments.length; i++) {
6148 args[fnArgs[i]] = arguments[i];
6149 }
6150
6151 var log = {
6152 index: ReactDefaultPerf.logs.length,
6153 fnName: fnName,
6154 objName: objName,
6155 timing: {
6156 before: timeBeforeFn,
6157 after: timeAfterFn,
6158 delta: timeAfterFn - timeBeforeFn
6159 }
6160 };
6161
6162 ReactDefaultPerf.logs.push(log);
6163
6164 /**
6165 * The callback gets:
6166 * - this (the component)
6167 * - the original method's arguments
6168 * - what the method returned
6169 * - the log object, and
6170 * - the wrapped method's info object.
6171 */
6172 var callback = _getCallback(objName, fnName);
6173 callback && callback(this, args, fnReturn, log, info);
6174
6175 log.timing.timeToLog = performanceNow() - timeAfterFn;
6176
6177 return fnReturn;
6178 };
6179 },
6180
6181 /**
6182 * Holds information on wrapped objects/methods.
6183 * For instance, ReactDefaultPerf.info.React.renderComponent
6184 */
6185 info: {},
6186
6187 /**
6188 * Holds all of the logs. Filter this to pull desired information.
6189 */
6190 logs: [],
6191
6192 /**
6193 * Toggle settings for ReactDefaultPerf
6194 */
6195 options: {
6196 /**
6197 * The heatmap sets the background color of the React containers
6198 * according to how much total time has been spent rendering them.
6199 * The most temporally expensive component is set as pure red,
6200 * and the others are colored from green to red as a fraction
6201 * of that max component time.
6202 */
6203 heatmap: {
6204 enabled: true
6205 }
6206 }
6207 };
6208
6209 /**
6210 * Gets a info area for a given object's function, adding a new one if
6211 * necessary.
6212 *
6213 * @param {string} objName
6214 * @param {string} fnName
6215 * @return {object}
6216 */
6217 var _getNewInfo = function(objName, fnName) {
6218 var info = ReactDefaultPerf.getInfo(objName, fnName);
6219 if (info) {
6220 return info;
6221 }
6222 ReactDefaultPerf.info[objName] = ReactDefaultPerf.info[objName] || {};
6223
6224 return ReactDefaultPerf.info[objName][fnName] = {
6225 getLogs: function() {
6226 return ReactDefaultPerf.getLogs(objName, fnName);
6227 }
6228 };
6229 };
6230
6231 /**
6232 * Gets a list of the argument names from a function's definition.
6233 * This is useful for storing arguments by their names within wrapFn().
6234 *
6235 * @param {function} fn
6236 * @return {array<string>}
6237 */
6238 var _getFnArguments = function(fn) {
6239 var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
6240 var fnStr = fn.toString().replace(STRIP_COMMENTS, '');
6241 fnStr = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')'));
6242 return fnStr.match(/([^\s,]+)/g);
6243 };
6244
6245 /**
6246 * Store common callbacks within ReactDefaultPerf.
6247 *
6248 * @param {string} objName
6249 * @param {string} fnName
6250 * @return {?function}
6251 */
6252 var _getCallback = function(objName, fnName) {
6253 switch (objName + '.' + fnName) {
6254 case 'React.renderComponent':
6255 return _renderComponentCallback;
6256 case 'ReactNativeComponent.mountComponent':
6257 case 'ReactNativeComponent.updateComponent':
6258 return _nativeComponentCallback;
6259 case 'ReactCompositeComponent.mountComponent':
6260 case 'ReactCompositeComponent.updateComponent':
6261 return _compositeComponentCallback;
6262 default:
6263 return null;
6264 }
6265 };
6266
6267 /**
6268 * Callback function for React.renderComponent
6269 *
6270 * @param {object} component
6271 * @param {object} args
6272 * @param {?object} fnReturn
6273 * @param {object} log
6274 * @param {object} info
6275 */
6276 var _renderComponentCallback =
6277 function(component, args, fnReturn, log, info) {
6278 log.name = args.nextComponent.constructor.displayName || '[unknown]';
6279 log.reactID = fnReturn._rootNodeID || null;
6280
6281 if (ReactDefaultPerf.options.heatmap.enabled) {
6282 var container = args.container;
6283 if (!container.loggedByReactDefaultPerf) {
6284 container.loggedByReactDefaultPerf = true;
6285 info.components = info.components || [];
6286 info.components.push(container);
6287 }
6288
6289 container.count = container.count || 0;
6290 container.count += log.timing.delta;
6291 info.max = info.max || 0;
6292 if (container.count > info.max) {
6293 info.max = container.count;
6294 info.components.forEach(function(component) {
6295 _setHue(component, 100 - 100 * component.count / info.max);
6296 });
6297 } else {
6298 _setHue(container, 100 - 100 * container.count / info.max);
6299 }
6300 }
6301 };
6302
6303 /**
6304 * Callback function for ReactNativeComponent
6305 *
6306 * @param {object} component
6307 * @param {object} args
6308 * @param {?object} fnReturn
6309 * @param {object} log
6310 * @param {object} info
6311 */
6312 var _nativeComponentCallback =
6313 function(component, args, fnReturn, log, info) {
6314 log.name = component.tagName || '[unknown]';
6315 log.reactID = component._rootNodeID;
6316 };
6317
6318 /**
6319 * Callback function for ReactCompositeComponent
6320 *
6321 * @param {object} component
6322 * @param {object} args
6323 * @param {?object} fnReturn
6324 * @param {object} log
6325 * @param {object} info
6326 */
6327 var _compositeComponentCallback =
6328 function(component, args, fnReturn, log, info) {
6329 log.name = component.constructor.displayName || '[unknown]';
6330 log.reactID = component._rootNodeID;
6331 };
6332
6333 /**
6334 * Using the hsl() background-color attribute, colors an element.
6335 *
6336 * @param {DOMElement} el
6337 * @param {number} hue [0 for red, 120 for green, 240 for blue]
6338 */
6339 var _setHue = function(el, hue) {
6340 el.style.backgroundColor = 'hsla(' + hue + ', 100%, 50%, 0.6)';
6341 };
6342
6343 /**
6344 * Round to the thousandth place.
6345 * @param {number} time
6346 * @return {number}
6347 */
6348 var _microTime = function(time) {
6349 return Math.round(time * 1000) / 1000;
6350 };
6351}
6352
6353module.exports = ReactDefaultPerf;
6354
6355},{"./performanceNow":102}],39:[function(require,module,exports){
6356/**
6357 * Copyright 2013 Facebook, Inc.
6358 *
6359 * Licensed under the Apache License, Version 2.0 (the "License");
6360 * you may not use this file except in compliance with the License.
6361 * You may obtain a copy of the License at
6362 *
6363 * http://www.apache.org/licenses/LICENSE-2.0
6364 *
6365 * Unless required by applicable law or agreed to in writing, software
6366 * distributed under the License is distributed on an "AS IS" BASIS,
6367 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6368 * See the License for the specific language governing permissions and
6369 * limitations under the License.
6370 *
6371 * @providesModule ReactEventEmitter
6372 * @typechecks static-only
6373 */
6374
6375"use strict";
6376
6377var EventConstants = require("./EventConstants");
6378var EventListener = require("./EventListener");
6379var EventPluginHub = require("./EventPluginHub");
6380var ExecutionEnvironment = require("./ExecutionEnvironment");
6381var ReactEventEmitterMixin = require("./ReactEventEmitterMixin");
6382var ViewportMetrics = require("./ViewportMetrics");
6383
6384var invariant = require("./invariant");
6385var isEventSupported = require("./isEventSupported");
6386var merge = require("./merge");
6387
6388/**
6389 * Summary of `ReactEventEmitter` event handling:
6390 *
6391 * - Top-level delegation is used to trap native browser events. We normalize
6392 * and de-duplicate events to account for browser quirks.
6393 *
6394 * - Forward these native events (with the associated top-level type used to
6395 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
6396 * to extract any synthetic events.
6397 *
6398 * - The `EventPluginHub` will then process each event by annotating them with
6399 * "dispatches", a sequence of listeners and IDs that care about that event.
6400 *
6401 * - The `EventPluginHub` then dispatches the events.
6402 *
6403 * Overview of React and the event system:
6404 *
6405 * .
6406 * +------------+ .
6407 * | DOM | .
6408 * +------------+ . +-----------+
6409 * + . +--------+|SimpleEvent|
6410 * | . | |Plugin |
6411 * +-----|------+ . v +-----------+
6412 * | | | . +--------------+ +------------+
6413 * | +-----------.--->|EventPluginHub| | Event |
6414 * | | . | | +-----------+ | Propagators|
6415 * | ReactEvent | . | | |TapEvent | |------------|
6416 * | Emitter | . | |<---+|Plugin | |other plugin|
6417 * | | . | | +-----------+ | utilities |
6418 * | +-----------.---------+ | +------------+
6419 * | | | . +----|---------+
6420 * +-----|------+ . | ^ +-----------+
6421 * | . | | |Enter/Leave|
6422 * + . | +-------+|Plugin |
6423 * +-------------+ . v +-----------+
6424 * | application | . +----------+
6425 * |-------------| . | callback |
6426 * | | . | registry |
6427 * | | . +----------+
6428 * +-------------+ .
6429 * .
6430 * React Core . General Purpose Event Plugin System
6431 */
6432
6433/**
6434 * Traps top-level events by using event bubbling.
6435 *
6436 * @param {string} topLevelType Record from `EventConstants`.
6437 * @param {string} handlerBaseName Event name (e.g. "click").
6438 * @param {DOMEventTarget} element Element on which to attach listener.
6439 * @internal
6440 */
6441function trapBubbledEvent(topLevelType, handlerBaseName, element) {
6442 EventListener.listen(
6443 element,
6444 handlerBaseName,
6445 ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(
6446 topLevelType
6447 )
6448 );
6449}
6450
6451/**
6452 * Traps a top-level event by using event capturing.
6453 *
6454 * @param {string} topLevelType Record from `EventConstants`.
6455 * @param {string} handlerBaseName Event name (e.g. "click").
6456 * @param {DOMEventTarget} element Element on which to attach listener.
6457 * @internal
6458 */
6459function trapCapturedEvent(topLevelType, handlerBaseName, element) {
6460 EventListener.capture(
6461 element,
6462 handlerBaseName,
6463 ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback(
6464 topLevelType
6465 )
6466 );
6467}
6468
6469/**
6470 * Listens to window scroll and resize events. We cache scroll values so that
6471 * application code can access them without triggering reflows.
6472 *
6473 * NOTE: Scroll events do not bubble.
6474 *
6475 * @private
6476 * @see http://www.quirksmode.org/dom/events/scroll.html
6477 */
6478function registerScrollValueMonitoring() {
6479 var refresh = ViewportMetrics.refreshScrollValues;
6480 EventListener.listen(window, 'scroll', refresh);
6481 EventListener.listen(window, 'resize', refresh);
6482}
6483
6484/**
6485 * `ReactEventEmitter` is used to attach top-level event listeners. For example:
6486 *
6487 * ReactEventEmitter.putListener('myID', 'onClick', myFunction);
6488 *
6489 * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'.
6490 *
6491 * @internal
6492 */
6493var ReactEventEmitter = merge(ReactEventEmitterMixin, {
6494
6495 /**
6496 * React references `ReactEventTopLevelCallback` using this property in order
6497 * to allow dependency injection.
6498 */
6499 TopLevelCallbackCreator: null,
6500
6501 /**
6502 * Ensures that top-level event delegation listeners are installed.
6503 *
6504 * There are issues with listening to both touch events and mouse events on
6505 * the top-level, so we make the caller choose which one to listen to. (If
6506 * there's a touch top-level listeners, anchors don't receive clicks for some
6507 * reason, and only in some cases).
6508 *
6509 * @param {boolean} touchNotMouse Listen to touch events instead of mouse.
6510 * @param {DOMDocument} contentDocument DOM document to listen on
6511 */
6512 ensureListening: function(touchNotMouse, contentDocument) {
6513 invariant(
6514 ExecutionEnvironment.canUseDOM,
6515 'ensureListening(...): Cannot toggle event listening in a Worker ' +
6516 'thread. This is likely a bug in the framework. Please report ' +
6517 'immediately.'
6518 );
6519 invariant(
6520 ReactEventEmitter.TopLevelCallbackCreator,
6521 'ensureListening(...): Cannot be called without a top level callback ' +
6522 'creator being injected.'
6523 );
6524 // Call out to base implementation.
6525 ReactEventEmitterMixin.ensureListening.call(
6526 ReactEventEmitter,
6527 {
6528 touchNotMouse: touchNotMouse,
6529 contentDocument: contentDocument
6530 }
6531 );
6532 },
6533
6534 /**
6535 * Sets whether or not any created callbacks should be enabled.
6536 *
6537 * @param {boolean} enabled True if callbacks should be enabled.
6538 */
6539 setEnabled: function(enabled) {
6540 invariant(
6541 ExecutionEnvironment.canUseDOM,
6542 'setEnabled(...): Cannot toggle event listening in a Worker thread. ' +
6543 'This is likely a bug in the framework. Please report immediately.'
6544 );
6545 if (ReactEventEmitter.TopLevelCallbackCreator) {
6546 ReactEventEmitter.TopLevelCallbackCreator.setEnabled(enabled);
6547 }
6548 },
6549
6550 /**
6551 * @return {boolean} True if callbacks are enabled.
6552 */
6553 isEnabled: function() {
6554 return !!(
6555 ReactEventEmitter.TopLevelCallbackCreator &&
6556 ReactEventEmitter.TopLevelCallbackCreator.isEnabled()
6557 );
6558 },
6559
6560 /**
6561 * We listen for bubbled touch events on the document object.
6562 *
6563 * Firefox v8.01 (and possibly others) exhibited strange behavior when
6564 * mounting `onmousemove` events at some node that was not the document
6565 * element. The symptoms were that if your mouse is not moving over something
6566 * contained within that mount point (for example on the background) the
6567 * top-level listeners for `onmousemove` won't be called. However, if you
6568 * register the `mousemove` on the document object, then it will of course
6569 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
6570 * top-level listeners to the document object only, at least for these
6571 * movement types of events and possibly all events.
6572 *
6573 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
6574 *
6575 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
6576 * they bubble to document.
6577 *
6578 * @param {boolean} touchNotMouse Listen to touch events instead of mouse.
6579 * @param {DOMDocument} contentDocument Document which owns the container
6580 * @private
6581 * @see http://www.quirksmode.org/dom/events/keys.html.
6582 */
6583 listenAtTopLevel: function(touchNotMouse, contentDocument) {
6584 invariant(
6585 !contentDocument._isListening,
6586 'listenAtTopLevel(...): Cannot setup top-level listener more than once.'
6587 );
6588 var topLevelTypes = EventConstants.topLevelTypes;
6589 var mountAt = contentDocument;
6590
6591 registerScrollValueMonitoring();
6592 trapBubbledEvent(topLevelTypes.topMouseOver, 'mouseover', mountAt);
6593 trapBubbledEvent(topLevelTypes.topMouseDown, 'mousedown', mountAt);
6594 trapBubbledEvent(topLevelTypes.topMouseUp, 'mouseup', mountAt);
6595 trapBubbledEvent(topLevelTypes.topMouseMove, 'mousemove', mountAt);
6596 trapBubbledEvent(topLevelTypes.topMouseOut, 'mouseout', mountAt);
6597 trapBubbledEvent(topLevelTypes.topClick, 'click', mountAt);
6598 trapBubbledEvent(topLevelTypes.topDoubleClick, 'dblclick', mountAt);
6599 if (touchNotMouse) {
6600 trapBubbledEvent(topLevelTypes.topTouchStart, 'touchstart', mountAt);
6601 trapBubbledEvent(topLevelTypes.topTouchEnd, 'touchend', mountAt);
6602 trapBubbledEvent(topLevelTypes.topTouchMove, 'touchmove', mountAt);
6603 trapBubbledEvent(topLevelTypes.topTouchCancel, 'touchcancel', mountAt);
6604 }
6605 trapBubbledEvent(topLevelTypes.topKeyUp, 'keyup', mountAt);
6606 trapBubbledEvent(topLevelTypes.topKeyPress, 'keypress', mountAt);
6607 trapBubbledEvent(topLevelTypes.topKeyDown, 'keydown', mountAt);
6608 trapBubbledEvent(topLevelTypes.topInput, 'input', mountAt);
6609 trapBubbledEvent(topLevelTypes.topChange, 'change', mountAt);
6610 trapBubbledEvent(
6611 topLevelTypes.topSelectionChange,
6612 'selectionchange',
6613 mountAt
6614 );
6615 trapBubbledEvent(
6616 topLevelTypes.topDOMCharacterDataModified,
6617 'DOMCharacterDataModified',
6618 mountAt
6619 );
6620
6621 if (isEventSupported('drag')) {
6622 trapBubbledEvent(topLevelTypes.topDrag, 'drag', mountAt);
6623 trapBubbledEvent(topLevelTypes.topDragEnd, 'dragend', mountAt);
6624 trapBubbledEvent(topLevelTypes.topDragEnter, 'dragenter', mountAt);
6625 trapBubbledEvent(topLevelTypes.topDragExit, 'dragexit', mountAt);
6626 trapBubbledEvent(topLevelTypes.topDragLeave, 'dragleave', mountAt);
6627 trapBubbledEvent(topLevelTypes.topDragOver, 'dragover', mountAt);
6628 trapBubbledEvent(topLevelTypes.topDragStart, 'dragstart', mountAt);
6629 trapBubbledEvent(topLevelTypes.topDrop, 'drop', mountAt);
6630 }
6631
6632 if (isEventSupported('wheel')) {
6633 trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt);
6634 } else if (isEventSupported('mousewheel')) {
6635 trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt);
6636 } else {
6637 // Firefox needs to capture a different mouse scroll event.
6638 // @see http://www.quirksmode.org/dom/events/tests/scroll.html
6639 trapBubbledEvent(topLevelTypes.topWheel, 'DOMMouseScroll', mountAt);
6640 }
6641
6642 // IE<9 does not support capturing so just trap the bubbled event there.
6643 if (isEventSupported('scroll', true)) {
6644 trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt);
6645 } else {
6646 trapBubbledEvent(topLevelTypes.topScroll, 'scroll', window);
6647 }
6648
6649 if (isEventSupported('focus', true)) {
6650 trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt);
6651 trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);
6652 } else if (isEventSupported('focusin')) {
6653 // IE has `focusin` and `focusout` events which bubble.
6654 // @see
6655 // http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
6656 trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);
6657 trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);
6658 }
6659
6660 if (isEventSupported('copy')) {
6661 trapBubbledEvent(topLevelTypes.topCopy, 'copy', mountAt);
6662 trapBubbledEvent(topLevelTypes.topCut, 'cut', mountAt);
6663 trapBubbledEvent(topLevelTypes.topPaste, 'paste', mountAt);
6664 }
6665 },
6666
6667 registrationNames: EventPluginHub.registrationNames,
6668
6669 putListener: EventPluginHub.putListener,
6670
6671 getListener: EventPluginHub.getListener,
6672
6673 deleteListener: EventPluginHub.deleteListener,
6674
6675 deleteAllListeners: EventPluginHub.deleteAllListeners,
6676
6677 trapBubbledEvent: trapBubbledEvent,
6678
6679 trapCapturedEvent: trapCapturedEvent
6680
6681});
6682
6683
6684module.exports = ReactEventEmitter;
6685
6686},{"./EventConstants":13,"./EventListener":14,"./EventPluginHub":15,"./ExecutionEnvironment":19,"./ReactEventEmitterMixin":40,"./ViewportMetrics":69,"./invariant":89,"./isEventSupported":90,"./merge":95}],40:[function(require,module,exports){
6687/**
6688 * Copyright 2013 Facebook, Inc.
6689 *
6690 * Licensed under the Apache License, Version 2.0 (the "License");
6691 * you may not use this file except in compliance with the License.
6692 * You may obtain a copy of the License at
6693 *
6694 * http://www.apache.org/licenses/LICENSE-2.0
6695 *
6696 * Unless required by applicable law or agreed to in writing, software
6697 * distributed under the License is distributed on an "AS IS" BASIS,
6698 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6699 * See the License for the specific language governing permissions and
6700 * limitations under the License.
6701 *
6702 * @providesModule ReactEventEmitterMixin
6703 */
6704
6705"use strict";
6706
6707var EventPluginHub = require("./EventPluginHub");
6708var ReactUpdates = require("./ReactUpdates");
6709
6710function runEventQueueInBatch(events) {
6711 EventPluginHub.enqueueEvents(events);
6712 EventPluginHub.processEventQueue();
6713}
6714
6715var ReactEventEmitterMixin = {
6716 /**
6717 * Whether or not `ensureListening` has been invoked.
6718 * @type {boolean}
6719 * @private
6720 */
6721 _isListening: false,
6722
6723 /**
6724 * Function, must be implemented. Listens to events on the top level of the
6725 * application.
6726 *
6727 * @abstract
6728 *
6729 * listenAtTopLevel: null,
6730 */
6731
6732 /**
6733 * Ensures that top-level event delegation listeners are installed.
6734 *
6735 * There are issues with listening to both touch events and mouse events on
6736 * the top-level, so we make the caller choose which one to listen to. (If
6737 * there's a touch top-level listeners, anchors don't receive clicks for some
6738 * reason, and only in some cases).
6739 *
6740 * @param {*} config Configuration passed through to `listenAtTopLevel`.
6741 */
6742 ensureListening: function(config) {
6743 if (!config.contentDocument._reactIsListening) {
6744 this.listenAtTopLevel(config.touchNotMouse, config.contentDocument);
6745 config.contentDocument._reactIsListening = true;
6746 }
6747 },
6748
6749 /**
6750 * Streams a fired top-level event to `EventPluginHub` where plugins have the
6751 * opportunity to create `ReactEvent`s to be dispatched.
6752 *
6753 * @param {string} topLevelType Record from `EventConstants`.
6754 * @param {object} topLevelTarget The listening component root node.
6755 * @param {string} topLevelTargetID ID of `topLevelTarget`.
6756 * @param {object} nativeEvent Native environment event.
6757 */
6758 handleTopLevel: function(
6759 topLevelType,
6760 topLevelTarget,
6761 topLevelTargetID,
6762 nativeEvent) {
6763 var events = EventPluginHub.extractEvents(
6764 topLevelType,
6765 topLevelTarget,
6766 topLevelTargetID,
6767 nativeEvent
6768 );
6769
6770 // Event queue being processed in the same cycle allows `preventDefault`.
6771 ReactUpdates.batchedUpdates(runEventQueueInBatch, events);
6772 }
6773};
6774
6775module.exports = ReactEventEmitterMixin;
6776
6777},{"./EventPluginHub":15,"./ReactUpdates":57}],41:[function(require,module,exports){
6778/**
6779 * Copyright 2013 Facebook, Inc.
6780 *
6781 * Licensed under the Apache License, Version 2.0 (the "License");
6782 * you may not use this file except in compliance with the License.
6783 * You may obtain a copy of the License at
6784 *
6785 * http://www.apache.org/licenses/LICENSE-2.0
6786 *
6787 * Unless required by applicable law or agreed to in writing, software
6788 * distributed under the License is distributed on an "AS IS" BASIS,
6789 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6790 * See the License for the specific language governing permissions and
6791 * limitations under the License.
6792 *
6793 * @providesModule ReactEventTopLevelCallback
6794 * @typechecks static-only
6795 */
6796
6797"use strict";
6798
6799var ReactEventEmitter = require("./ReactEventEmitter");
6800var ReactMount = require("./ReactMount");
6801
6802var getEventTarget = require("./getEventTarget");
6803
6804/**
6805 * @type {boolean}
6806 * @private
6807 */
6808var _topLevelListenersEnabled = true;
6809
6810/**
6811 * Top-level callback creator used to implement event handling using delegation.
6812 * This is used via dependency injection.
6813 */
6814var ReactEventTopLevelCallback = {
6815
6816 /**
6817 * Sets whether or not any created callbacks should be enabled.
6818 *
6819 * @param {boolean} enabled True if callbacks should be enabled.
6820 */
6821 setEnabled: function(enabled) {
6822 _topLevelListenersEnabled = !!enabled;
6823 },
6824
6825 /**
6826 * @return {boolean} True if callbacks are enabled.
6827 */
6828 isEnabled: function() {
6829 return _topLevelListenersEnabled;
6830 },
6831
6832 /**
6833 * Creates a callback for the supplied `topLevelType` that could be added as
6834 * a listener to the document. The callback computes a `topLevelTarget` which
6835 * should be the root node of a mounted React component where the listener
6836 * is attached.
6837 *
6838 * @param {string} topLevelType Record from `EventConstants`.
6839 * @return {function} Callback for handling top-level events.
6840 */
6841 createTopLevelCallback: function(topLevelType) {
6842 return function(nativeEvent) {
6843 if (!_topLevelListenersEnabled) {
6844 return;
6845 }
6846 // TODO: Remove when synthetic events are ready, this is for IE<9.
6847 if (nativeEvent.srcElement &&
6848 nativeEvent.srcElement !== nativeEvent.target) {
6849 nativeEvent.target = nativeEvent.srcElement;
6850 }
6851 var topLevelTarget = ReactMount.getFirstReactDOM(
6852 getEventTarget(nativeEvent)
6853 ) || window;
6854 var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';
6855 ReactEventEmitter.handleTopLevel(
6856 topLevelType,
6857 topLevelTarget,
6858 topLevelTargetID,
6859 nativeEvent
6860 );
6861 };
6862 }
6863
6864};
6865
6866module.exports = ReactEventTopLevelCallback;
6867
6868},{"./ReactEventEmitter":39,"./ReactMount":45,"./getEventTarget":84}],42:[function(require,module,exports){
6869/**
6870 * Copyright 2013 Facebook, Inc.
6871 *
6872 * Licensed under the Apache License, Version 2.0 (the "License");
6873 * you may not use this file except in compliance with the License.
6874 * You may obtain a copy of the License at
6875 *
6876 * http://www.apache.org/licenses/LICENSE-2.0
6877 *
6878 * Unless required by applicable law or agreed to in writing, software
6879 * distributed under the License is distributed on an "AS IS" BASIS,
6880 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6881 * See the License for the specific language governing permissions and
6882 * limitations under the License.
6883 *
6884 * @providesModule ReactInputSelection
6885 */
6886
6887"use strict";
6888
6889var getTextContentAccessor = require("./getTextContentAccessor");
6890
6891// It is not safe to read the document.activeElement property in IE if there's
6892// nothing focused.
6893function getActiveElement() {
6894 try {
6895 return document.activeElement;
6896 } catch (e) {
6897 }
6898}
6899
6900function isInDocument(node) {
6901 return document.documentElement.contains(node);
6902}
6903
6904/**
6905 * @ReactInputSelection: React input selection module. Based on Selection.js,
6906 * but modified to be suitable for react and has a couple of bug fixes (doesn't
6907 * assume buttons have range selections allowed).
6908 * Input selection module for React.
6909 */
6910var ReactInputSelection = {
6911
6912 hasSelectionCapabilities: function(elem) {
6913 return elem && (
6914 (elem.nodeName === 'INPUT' && elem.type === 'text') ||
6915 elem.nodeName === 'TEXTAREA' ||
6916 elem.contentEditable === 'true'
6917 );
6918 },
6919
6920 getSelectionInformation: function() {
6921 var focusedElem = getActiveElement();
6922 return {
6923 focusedElem: focusedElem,
6924 selectionRange:
6925 ReactInputSelection.hasSelectionCapabilities(focusedElem) ?
6926 ReactInputSelection.getSelection(focusedElem) :
6927 null
6928 };
6929 },
6930
6931 /**
6932 * @restoreSelection: If any selection information was potentially lost,
6933 * restore it. This is useful when performing operations that could remove dom
6934 * nodes and place them back in, resulting in focus being lost.
6935 */
6936 restoreSelection: function(priorSelectionInformation) {
6937 var curFocusedElem = getActiveElement();
6938 var priorFocusedElem = priorSelectionInformation.focusedElem;
6939 var priorSelectionRange = priorSelectionInformation.selectionRange;
6940 if (curFocusedElem !== priorFocusedElem &&
6941 isInDocument(priorFocusedElem)) {
6942 if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) {
6943 ReactInputSelection.setSelection(
6944 priorFocusedElem,
6945 priorSelectionRange
6946 );
6947 }
6948 priorFocusedElem.focus();
6949 }
6950 },
6951
6952 /**
6953 * @getSelection: Gets the selection bounds of a focused textarea, input or
6954 * contentEditable node.
6955 * -@input: Look up selection bounds of this input
6956 * -@return {start: selectionStart, end: selectionEnd}
6957 */
6958 getSelection: function(input) {
6959 var range;
6960 if (input.contentEditable === 'true' && window.getSelection) {
6961 var selection = window.getSelection();
6962 if (selection.rangeCount > 0) {
6963 range = selection.getRangeAt(0);
6964 var commonAncestor = range.commonAncestorContainer;
6965 if (commonAncestor && commonAncestor.nodeType === 3) {
6966 commonAncestor = commonAncestor.parentNode;
6967 }
6968 if (commonAncestor === input) {
6969 return {start: range.startOffset, end: range.endOffset};
6970 }
6971 }
6972 return {start: 0, end: 0};
6973 }
6974
6975 if (!document.selection) {
6976 // Mozilla, Safari, etc.
6977 return {start: input.selectionStart, end: input.selectionEnd};
6978 }
6979
6980 range = document.selection.createRange();
6981 if (range.parentElement() !== input) {
6982 // There can only be one selection per document in IE, so if the
6983 // containing element of the document's selection isn't our text field,
6984 // our text field must have no selection.
6985 return {start: 0, end: 0};
6986 }
6987
6988 var value = input.value || input[getTextContentAccessor()];
6989 var length = value.length;
6990
6991 if (input.nodeName === 'INPUT') {
6992 return {
6993 start: -range.moveStart('character', -length),
6994 end: -range.moveEnd('character', -length)
6995 };
6996 } else {
6997 var range2 = range.duplicate();
6998 range2.moveToElementText(input);
6999 range2.setEndPoint('StartToEnd', range);
7000 var end = length - range2.text.length;
7001 range2.setEndPoint('StartToStart', range);
7002 return {
7003 start: length - range2.text.length,
7004 end: end
7005 };
7006 }
7007 },
7008
7009 /**
7010 * @setSelection: Sets the selection bounds of a textarea or input and focuses
7011 * the input.
7012 * -@input Set selection bounds of this input or textarea
7013 * -@rangeObj Object of same form that is returned from get*
7014 */
7015 setSelection: function(input, rangeObj) {
7016 var range;
7017 var start = rangeObj.start;
7018 var end = rangeObj.end;
7019 if (typeof end === 'undefined') {
7020 end = start;
7021 }
7022 if (document.selection) {
7023 // IE is inconsistent about character offsets when it comes to carriage
7024 // returns, so we need to manually take them into account
7025 if (input.tagName === 'TEXTAREA') {
7026 var cr_before =
7027 (input.value.slice(0, start).match(/\r/g) || []).length;
7028 var cr_inside =
7029 (input.value.slice(start, end).match(/\r/g) || []).length;
7030 start -= cr_before;
7031 end -= cr_before + cr_inside;
7032 }
7033 range = input.createTextRange();
7034 range.collapse(true);
7035 range.moveStart('character', start);
7036 range.moveEnd('character', end - start);
7037 range.select();
7038 } else {
7039 if (input.contentEditable === 'true') {
7040 if (input.childNodes.length === 1) {
7041 range = document.createRange();
7042 range.setStart(input.childNodes[0], start);
7043 range.setEnd(input.childNodes[0], end);
7044 var sel = window.getSelection();
7045 sel.removeAllRanges();
7046 sel.addRange(range);
7047 }
7048 } else {
7049 input.selectionStart = start;
7050 input.selectionEnd = Math.min(end, input.value.length);
7051 input.focus();
7052 }
7053 }
7054 }
7055
7056};
7057
7058module.exports = ReactInputSelection;
7059
7060},{"./getTextContentAccessor":87}],43:[function(require,module,exports){
7061/**
7062 * Copyright 2013 Facebook, Inc.
7063 *
7064 * Licensed under the Apache License, Version 2.0 (the "License");
7065 * you may not use this file except in compliance with the License.
7066 * You may obtain a copy of the License at
7067 *
7068 * http://www.apache.org/licenses/LICENSE-2.0
7069 *
7070 * Unless required by applicable law or agreed to in writing, software
7071 * distributed under the License is distributed on an "AS IS" BASIS,
7072 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7073 * See the License for the specific language governing permissions and
7074 * limitations under the License.
7075 *
7076 * @providesModule ReactInstanceHandles
7077 * @typechecks static-only
7078 */
7079
7080"use strict";
7081
7082var invariant = require("./invariant");
7083
7084var SEPARATOR = '.';
7085var SEPARATOR_LENGTH = SEPARATOR.length;
7086
7087/**
7088 * Maximum depth of traversals before we consider the possibility of a bad ID.
7089 */
7090var MAX_TREE_DEPTH = 100;
7091
7092/**
7093 * Size of the reactRoot ID space. We generate random numbers for React root
7094 * IDs and if there's a collision the events and DOM update system will
7095 * get confused. If we assume 100 React components per page, and a user
7096 * loads 1 page per minute 24/7 for 50 years, with a mount point space of
7097 * 9,999,999 the likelihood of never having a collision is 99.997%.
7098 */
7099var GLOBAL_MOUNT_POINT_MAX = 9999999;
7100
7101/**
7102 * Creates a DOM ID prefix to use when mounting React components.
7103 *
7104 * @param {number} index A unique integer
7105 * @return {string} React root ID.
7106 * @internal
7107 */
7108function getReactRootIDString(index) {
7109 return SEPARATOR + 'r[' + index.toString(36) + ']';
7110}
7111
7112/**
7113 * Checks if a character in the supplied ID is a separator or the end.
7114 *
7115 * @param {string} id A React DOM ID.
7116 * @param {number} index Index of the character to check.
7117 * @return {boolean} True if the character is a separator or end of the ID.
7118 * @private
7119 */
7120function isBoundary(id, index) {
7121 return id.charAt(index) === SEPARATOR || index === id.length;
7122}
7123
7124/**
7125 * Checks if the supplied string is a valid React DOM ID.
7126 *
7127 * @param {string} id A React DOM ID, maybe.
7128 * @return {boolean} True if the string is a valid React DOM ID.
7129 * @private
7130 */
7131function isValidID(id) {
7132 return id === '' || (
7133 id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR
7134 );
7135}
7136
7137/**
7138 * Checks if the first ID is an ancestor of or equal to the second ID.
7139 *
7140 * @param {string} ancestorID
7141 * @param {string} descendantID
7142 * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`.
7143 * @internal
7144 */
7145function isAncestorIDOf(ancestorID, descendantID) {
7146 return (
7147 descendantID.indexOf(ancestorID) === 0 &&
7148 isBoundary(descendantID, ancestorID.length)
7149 );
7150}
7151
7152/**
7153 * Gets the parent ID of the supplied React DOM ID, `id`.
7154 *
7155 * @param {string} id ID of a component.
7156 * @return {string} ID of the parent, or an empty string.
7157 * @private
7158 */
7159function getParentID(id) {
7160 return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';
7161}
7162
7163/**
7164 * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the
7165 * supplied `destinationID`. If they are equal, the ID is returned.
7166 *
7167 * @param {string} ancestorID ID of an ancestor node of `destinationID`.
7168 * @param {string} destinationID ID of the destination node.
7169 * @return {string} Next ID on the path from `ancestorID` to `destinationID`.
7170 * @private
7171 */
7172function getNextDescendantID(ancestorID, destinationID) {
7173 invariant(
7174 isValidID(ancestorID) && isValidID(destinationID),
7175 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.',
7176 ancestorID,
7177 destinationID
7178 );
7179 invariant(
7180 isAncestorIDOf(ancestorID, destinationID),
7181 'getNextDescendantID(...): React has made an invalid assumption about ' +
7182 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.',
7183 ancestorID,
7184 destinationID
7185 );
7186 if (ancestorID === destinationID) {
7187 return ancestorID;
7188 }
7189 // Skip over the ancestor and the immediate separator. Traverse until we hit
7190 // another separator or we reach the end of `destinationID`.
7191 var start = ancestorID.length + SEPARATOR_LENGTH;
7192 for (var i = start; i < destinationID.length; i++) {
7193 if (isBoundary(destinationID, i)) {
7194 break;
7195 }
7196 }
7197 return destinationID.substr(0, i);
7198}
7199
7200/**
7201 * Gets the nearest common ancestor ID of two IDs.
7202 *
7203 * Using this ID scheme, the nearest common ancestor ID is the longest common
7204 * prefix of the two IDs that immediately preceded a "marker" in both strings.
7205 *
7206 * @param {string} oneID
7207 * @param {string} twoID
7208 * @return {string} Nearest common ancestor ID, or the empty string if none.
7209 * @private
7210 */
7211function getFirstCommonAncestorID(oneID, twoID) {
7212 var minLength = Math.min(oneID.length, twoID.length);
7213 if (minLength === 0) {
7214 return '';
7215 }
7216 var lastCommonMarkerIndex = 0;
7217 // Use `<=` to traverse until the "EOL" of the shorter string.
7218 for (var i = 0; i <= minLength; i++) {
7219 if (isBoundary(oneID, i) && isBoundary(twoID, i)) {
7220 lastCommonMarkerIndex = i;
7221 } else if (oneID.charAt(i) !== twoID.charAt(i)) {
7222 break;
7223 }
7224 }
7225 var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);
7226 invariant(
7227 isValidID(longestCommonID),
7228 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s',
7229 oneID,
7230 twoID,
7231 longestCommonID
7232 );
7233 return longestCommonID;
7234}
7235
7236/**
7237 * Traverses the parent path between two IDs (either up or down). The IDs must
7238 * not be the same, and there must exist a parent path between them.
7239 *
7240 * @param {?string} start ID at which to start traversal.
7241 * @param {?string} stop ID at which to end traversal.
7242 * @param {function} cb Callback to invoke each ID with.
7243 * @param {?boolean} skipFirst Whether or not to skip the first node.
7244 * @param {?boolean} skipLast Whether or not to skip the last node.
7245 * @private
7246 */
7247function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {
7248 start = start || '';
7249 stop = stop || '';
7250 invariant(
7251 start !== stop,
7252 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.',
7253 start
7254 );
7255 var traverseUp = isAncestorIDOf(stop, start);
7256 invariant(
7257 traverseUp || isAncestorIDOf(start, stop),
7258 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' +
7259 'not have a parent path.',
7260 start,
7261 stop
7262 );
7263 // Traverse from `start` to `stop` one depth at a time.
7264 var depth = 0;
7265 var traverse = traverseUp ? getParentID : getNextDescendantID;
7266 for (var id = start; /* until break */; id = traverse(id, stop)) {
7267 if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {
7268 cb(id, traverseUp, arg);
7269 }
7270 if (id === stop) {
7271 // Only break //after// visiting `stop`.
7272 break;
7273 }
7274 invariant(
7275 depth++ < MAX_TREE_DEPTH,
7276 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' +
7277 'traversing the React DOM ID tree. This may be due to malformed IDs: %s',
7278 start, stop
7279 );
7280 }
7281}
7282
7283/**
7284 * Manages the IDs assigned to DOM representations of React components. This
7285 * uses a specific scheme in order to traverse the DOM efficiently (e.g. in
7286 * order to simulate events).
7287 *
7288 * @internal
7289 */
7290var ReactInstanceHandles = {
7291
7292 createReactRootID: function() {
7293 return getReactRootIDString(
7294 Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX)
7295 );
7296 },
7297
7298 /**
7299 * Constructs a React ID by joining a root ID with a name.
7300 *
7301 * @param {string} rootID Root ID of a parent component.
7302 * @param {string} name A component's name (as flattened children).
7303 * @return {string} A React ID.
7304 * @internal
7305 */
7306 createReactID: function(rootID, name) {
7307 return rootID + SEPARATOR + name;
7308 },
7309
7310 /**
7311 * Gets the DOM ID of the React component that is the root of the tree that
7312 * contains the React component with the supplied DOM ID.
7313 *
7314 * @param {string} id DOM ID of a React component.
7315 * @return {?string} DOM ID of the React component that is the root.
7316 * @internal
7317 */
7318 getReactRootIDFromNodeID: function(id) {
7319 var regexResult = /\.r\[[^\]]+\]/.exec(id);
7320 return regexResult && regexResult[0];
7321 },
7322
7323 /**
7324 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
7325 * should would receive a `mouseEnter` or `mouseLeave` event.
7326 *
7327 * NOTE: Does not invoke the callback on the nearest common ancestor because
7328 * nothing "entered" or "left" that element.
7329 *
7330 * @param {string} leaveID ID being left.
7331 * @param {string} enterID ID being entered.
7332 * @param {function} cb Callback to invoke on each entered/left ID.
7333 * @param {*} upArg Argument to invoke the callback with on left IDs.
7334 * @param {*} downArg Argument to invoke the callback with on entered IDs.
7335 * @internal
7336 */
7337 traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) {
7338 var ancestorID = getFirstCommonAncestorID(leaveID, enterID);
7339 if (ancestorID !== leaveID) {
7340 traverseParentPath(leaveID, ancestorID, cb, upArg, false, true);
7341 }
7342 if (ancestorID !== enterID) {
7343 traverseParentPath(ancestorID, enterID, cb, downArg, true, false);
7344 }
7345 },
7346
7347 /**
7348 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
7349 *
7350 * NOTE: This traversal happens on IDs without touching the DOM.
7351 *
7352 * @param {string} targetID ID of the target node.
7353 * @param {function} cb Callback to invoke.
7354 * @param {*} arg Argument to invoke the callback with.
7355 * @internal
7356 */
7357 traverseTwoPhase: function(targetID, cb, arg) {
7358 if (targetID) {
7359 traverseParentPath('', targetID, cb, arg, true, false);
7360 traverseParentPath(targetID, '', cb, arg, false, true);
7361 }
7362 },
7363
7364 /**
7365 * Exposed for unit testing.
7366 * @private
7367 */
7368 _getFirstCommonAncestorID: getFirstCommonAncestorID,
7369
7370 /**
7371 * Exposed for unit testing.
7372 * @private
7373 */
7374 _getNextDescendantID: getNextDescendantID,
7375
7376 isAncestorIDOf: isAncestorIDOf,
7377
7378 SEPARATOR: SEPARATOR
7379
7380};
7381
7382module.exports = ReactInstanceHandles;
7383
7384},{"./invariant":89}],44:[function(require,module,exports){
7385/**
7386 * Copyright 2013 Facebook, Inc.
7387 *
7388 * Licensed under the Apache License, Version 2.0 (the "License");
7389 * you may not use this file except in compliance with the License.
7390 * You may obtain a copy of the License at
7391 *
7392 * http://www.apache.org/licenses/LICENSE-2.0
7393 *
7394 * Unless required by applicable law or agreed to in writing, software
7395 * distributed under the License is distributed on an "AS IS" BASIS,
7396 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7397 * See the License for the specific language governing permissions and
7398 * limitations under the License.
7399 *
7400 * @providesModule ReactMarkupChecksum
7401 */
7402
7403"use strict";
7404
7405var adler32 = require("./adler32");
7406
7407var ReactMarkupChecksum = {
7408 CHECKSUM_ATTR_NAME: 'data-react-checksum',
7409
7410 /**
7411 * @param {string} markup Markup string
7412 * @return {string} Markup string with checksum attribute attached
7413 */
7414 addChecksumToMarkup: function(markup) {
7415 var checksum = adler32(markup);
7416 return markup.replace(
7417 '>',
7418 ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">'
7419 );
7420 },
7421
7422 /**
7423 * @param {string} markup to use
7424 * @param {DOMElement} element root React element
7425 * @returns {boolean} whether or not the markup is the same
7426 */
7427 canReuseMarkup: function(markup, element) {
7428 var existingChecksum = element.getAttribute(
7429 ReactMarkupChecksum.CHECKSUM_ATTR_NAME
7430 );
7431 existingChecksum = existingChecksum && parseInt(existingChecksum, 10);
7432 var markupChecksum = adler32(markup);
7433 return markupChecksum === existingChecksum;
7434 }
7435};
7436
7437module.exports = ReactMarkupChecksum;
7438
7439},{"./adler32":71}],45:[function(require,module,exports){
7440/**
7441 * Copyright 2013 Facebook, Inc.
7442 *
7443 * Licensed under the Apache License, Version 2.0 (the "License");
7444 * you may not use this file except in compliance with the License.
7445 * You may obtain a copy of the License at
7446 *
7447 * http://www.apache.org/licenses/LICENSE-2.0
7448 *
7449 * Unless required by applicable law or agreed to in writing, software
7450 * distributed under the License is distributed on an "AS IS" BASIS,
7451 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7452 * See the License for the specific language governing permissions and
7453 * limitations under the License.
7454 *
7455 * @providesModule ReactMount
7456 */
7457
7458"use strict";
7459
7460var invariant = require("./invariant");
7461var getReactRootElementInContainer = require("./getReactRootElementInContainer");
7462var ReactEventEmitter = require("./ReactEventEmitter");
7463var ReactInstanceHandles = require("./ReactInstanceHandles");
7464
7465var SEPARATOR = ReactInstanceHandles.SEPARATOR;
7466
7467var ATTR_NAME = 'data-reactid';
7468var nodeCache = {};
7469
7470var ELEMENT_NODE_TYPE = 1;
7471var DOC_NODE_TYPE = 9;
7472
7473var $ = require("./$");
7474
7475/** Mapping from reactRootID to React component instance. */
7476var instancesByReactRootID = {};
7477
7478/** Mapping from reactRootID to `container` nodes. */
7479var containersByReactRootID = {};
7480
7481if (true) {
7482 /** __DEV__-only mapping from reactRootID to root elements. */
7483 var rootElementsByReactRootID = {};
7484}
7485
7486/**
7487 * @param {DOMElement} container DOM element that may contain a React component.
7488 * @return {?string} A "reactRoot" ID, if a React component is rendered.
7489 */
7490function getReactRootID(container) {
7491 var rootElement = getReactRootElementInContainer(container);
7492 return rootElement && ReactMount.getID(rootElement);
7493}
7494
7495/**
7496 * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
7497 * element can return its control whose name or ID equals ATTR_NAME. All
7498 * DOM nodes support `getAttributeNode` but this can also get called on
7499 * other objects so just return '' if we're given something other than a
7500 * DOM node (such as window).
7501 *
7502 * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.
7503 * @return {string} ID of the supplied `domNode`.
7504 */
7505function getID(node) {
7506 var id = internalGetID(node);
7507 if (id) {
7508 if (nodeCache.hasOwnProperty(id)) {
7509 var cached = nodeCache[id];
7510 if (cached !== node) {
7511 invariant(
7512 !isValid(cached, id),
7513 'ReactMount: Two valid but unequal nodes with the same `%s`: %s',
7514 ATTR_NAME, id
7515 );
7516
7517 nodeCache[id] = node;
7518 }
7519 } else {
7520 nodeCache[id] = node;
7521 }
7522 }
7523
7524 return id;
7525}
7526
7527function internalGetID(node) {
7528 // If node is something like a window, document, or text node, none of
7529 // which support attributes or a .getAttribute method, gracefully return
7530 // the empty string, as if the attribute were missing.
7531 return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
7532}
7533
7534/**
7535 * Sets the React-specific ID of the given node.
7536 *
7537 * @param {DOMElement} node The DOM node whose ID will be set.
7538 * @param {string} id The value of the ID attribute.
7539 */
7540function setID(node, id) {
7541 var oldID = internalGetID(node);
7542 if (oldID !== id) {
7543 delete nodeCache[oldID];
7544 }
7545 node.setAttribute(ATTR_NAME, id);
7546 nodeCache[id] = node;
7547}
7548
7549/**
7550 * Finds the node with the supplied React-generated DOM ID.
7551 *
7552 * @param {string} id A React-generated DOM ID.
7553 * @return {DOMElement} DOM node with the suppled `id`.
7554 * @internal
7555 */
7556function getNode(id) {
7557 if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
7558 nodeCache[id] = ReactMount.findReactNodeByID(id);
7559 }
7560 return nodeCache[id];
7561}
7562
7563/**
7564 * A node is "valid" if it is contained by a currently mounted container.
7565 *
7566 * This means that the node does not have to be contained by a document in
7567 * order to be considered valid.
7568 *
7569 * @param {?DOMElement} node The candidate DOM node.
7570 * @param {string} id The expected ID of the node.
7571 * @return {boolean} Whether the node is contained by a mounted container.
7572 */
7573function isValid(node, id) {
7574 if (node) {
7575 invariant(
7576 internalGetID(node) === id,
7577 'ReactMount: Unexpected modification of `%s`',
7578 ATTR_NAME
7579 );
7580
7581 var container = ReactMount.findReactContainerForID(id);
7582 if (container && contains(container, node)) {
7583 return true;
7584 }
7585 }
7586
7587 return false;
7588}
7589
7590function contains(ancestor, descendant) {
7591 if (ancestor.contains) {
7592 // Supported natively in virtually all browsers, but not in jsdom.
7593 return ancestor.contains(descendant);
7594 }
7595
7596 if (descendant === ancestor) {
7597 return true;
7598 }
7599
7600 if (descendant.nodeType === 3) {
7601 // If descendant is a text node, start from descendant.parentNode
7602 // instead, so that we can assume all ancestors worth considering are
7603 // element nodes with nodeType === 1.
7604 descendant = descendant.parentNode;
7605 }
7606
7607 while (descendant && descendant.nodeType === 1) {
7608 if (descendant === ancestor) {
7609 return true;
7610 }
7611 descendant = descendant.parentNode;
7612 }
7613
7614 return false;
7615}
7616
7617/**
7618 * Causes the cache to forget about one React-specific ID.
7619 *
7620 * @param {string} id The ID to forget.
7621 */
7622function purgeID(id) {
7623 delete nodeCache[id];
7624}
7625
7626/**
7627 * Mounting is the process of initializing a React component by creatings its
7628 * representative DOM elements and inserting them into a supplied `container`.
7629 * Any prior content inside `container` is destroyed in the process.
7630 *
7631 * ReactMount.renderComponent(component, $('container'));
7632 *
7633 * <div id="container"> <-- Supplied `container`.
7634 * <div data-reactid=".r[3]"> <-- Rendered reactRoot of React
7635 * // ... component.
7636 * </div>
7637 * </div>
7638 *
7639 * Inside of `container`, the first element rendered is the "reactRoot".
7640 */
7641var ReactMount = {
7642 /**
7643 * Safety guard to prevent accidentally rendering over the entire HTML tree.
7644 */
7645 allowFullPageRender: false,
7646
7647 /** Time spent generating markup. */
7648 totalInstantiationTime: 0,
7649
7650 /** Time spent inserting markup into the DOM. */
7651 totalInjectionTime: 0,
7652
7653 /** Whether support for touch events should be initialized. */
7654 useTouchEvents: false,
7655
7656 /** Exposed for debugging purposes **/
7657 _instancesByReactRootID: instancesByReactRootID,
7658
7659 /**
7660 * This is a hook provided to support rendering React components while
7661 * ensuring that the apparent scroll position of its `container` does not
7662 * change.
7663 *
7664 * @param {DOMElement} container The `container` being rendered into.
7665 * @param {function} renderCallback This must be called once to do the render.
7666 */
7667 scrollMonitor: function(container, renderCallback) {
7668 renderCallback();
7669 },
7670
7671 /**
7672 * Ensures that the top-level event delegation listener is set up. This will
7673 * be invoked some time before the first time any React component is rendered.
7674 * @param {DOMElement} container container we're rendering into
7675 *
7676 * @private
7677 */
7678 prepareEnvironmentForDOM: function(container) {
7679 invariant(
7680 container && (
7681 container.nodeType === ELEMENT_NODE_TYPE ||
7682 container.nodeType === DOC_NODE_TYPE
7683 ),
7684 'prepareEnvironmentForDOM(...): Target container is not a DOM element.'
7685 );
7686 var doc = container.nodeType === ELEMENT_NODE_TYPE ?
7687 container.ownerDocument :
7688 container;
7689 ReactEventEmitter.ensureListening(ReactMount.useTouchEvents, doc);
7690 },
7691
7692 /**
7693 * Take a component that's already mounted into the DOM and replace its props
7694 * @param {ReactComponent} prevComponent component instance already in the DOM
7695 * @param {ReactComponent} nextComponent component instance to render
7696 * @param {DOMElement} container container to render into
7697 * @param {?function} callback function triggered on completion
7698 */
7699 _updateRootComponent: function(
7700 prevComponent,
7701 nextComponent,
7702 container,
7703 callback) {
7704 var nextProps = nextComponent.props;
7705 ReactMount.scrollMonitor(container, function() {
7706 prevComponent.replaceProps(nextProps, callback);
7707 });
7708
7709 if (true) {
7710 // Record the root element in case it later gets transplanted.
7711 rootElementsByReactRootID[getReactRootID(container)] =
7712 getReactRootElementInContainer(container);
7713 }
7714
7715 return prevComponent;
7716 },
7717
7718 /**
7719 * Register a component into the instance map and start the events system.
7720 * @param {ReactComponent} nextComponent component instance to render
7721 * @param {DOMElement} container container to render into
7722 * @return {string} reactRoot ID prefix
7723 */
7724 _registerComponent: function(nextComponent, container) {
7725 ReactMount.prepareEnvironmentForDOM(container);
7726
7727 var reactRootID = ReactMount.registerContainer(container);
7728 instancesByReactRootID[reactRootID] = nextComponent;
7729 return reactRootID;
7730 },
7731
7732 /**
7733 * Render a new component into the DOM.
7734 * @param {ReactComponent} nextComponent component instance to render
7735 * @param {DOMElement} container container to render into
7736 * @param {boolean} shouldReuseMarkup if we should skip the markup insertion
7737 * @return {ReactComponent} nextComponent
7738 */
7739 _renderNewRootComponent: function(
7740 nextComponent,
7741 container,
7742 shouldReuseMarkup) {
7743 var reactRootID = ReactMount._registerComponent(nextComponent, container);
7744 nextComponent.mountComponentIntoNode(
7745 reactRootID,
7746 container,
7747 shouldReuseMarkup
7748 );
7749
7750 if (true) {
7751 // Record the root element in case it later gets transplanted.
7752 rootElementsByReactRootID[reactRootID] =
7753 getReactRootElementInContainer(container);
7754 }
7755
7756 return nextComponent;
7757 },
7758
7759 /**
7760 * Renders a React component into the DOM in the supplied `container`.
7761 *
7762 * If the React component was previously rendered into `container`, this will
7763 * perform an update on it and only mutate the DOM as necessary to reflect the
7764 * latest React component.
7765 *
7766 * @param {ReactComponent} nextComponent Component instance to render.
7767 * @param {DOMElement} container DOM element to render into.
7768 * @param {?function} callback function triggered on completion
7769 * @return {ReactComponent} Component instance rendered in `container`.
7770 */
7771 renderComponent: function(nextComponent, container, callback) {
7772 var registeredComponent = instancesByReactRootID[getReactRootID(container)];
7773
7774 if (registeredComponent) {
7775 if (registeredComponent.constructor === nextComponent.constructor) {
7776 return ReactMount._updateRootComponent(
7777 registeredComponent,
7778 nextComponent,
7779 container,
7780 callback
7781 );
7782 } else {
7783 ReactMount.unmountAndReleaseReactRootNode(container);
7784 }
7785 }
7786
7787 var reactRootElement = getReactRootElementInContainer(container);
7788 var containerHasReactMarkup =
7789 reactRootElement && ReactMount.isRenderedByReact(reactRootElement);
7790
7791 var shouldReuseMarkup = containerHasReactMarkup && !registeredComponent;
7792
7793 var component = ReactMount._renderNewRootComponent(
7794 nextComponent,
7795 container,
7796 shouldReuseMarkup
7797 );
7798 callback && callback();
7799 return component;
7800 },
7801
7802 /**
7803 * Constructs a component instance of `constructor` with `initialProps` and
7804 * renders it into the supplied `container`.
7805 *
7806 * @param {function} constructor React component constructor.
7807 * @param {?object} props Initial props of the component instance.
7808 * @param {DOMElement} container DOM element to render into.
7809 * @return {ReactComponent} Component instance rendered in `container`.
7810 */
7811 constructAndRenderComponent: function(constructor, props, container) {
7812 return ReactMount.renderComponent(constructor(props), container);
7813 },
7814
7815 /**
7816 * Constructs a component instance of `constructor` with `initialProps` and
7817 * renders it into a container node identified by supplied `id`.
7818 *
7819 * @param {function} componentConstructor React component constructor
7820 * @param {?object} props Initial props of the component instance.
7821 * @param {string} id ID of the DOM element to render into.
7822 * @return {ReactComponent} Component instance rendered in the container node.
7823 */
7824 constructAndRenderComponentByID: function(constructor, props, id) {
7825 return ReactMount.constructAndRenderComponent(constructor, props, $(id));
7826 },
7827
7828 /**
7829 * Registers a container node into which React components will be rendered.
7830 * This also creates the "reatRoot" ID that will be assigned to the element
7831 * rendered within.
7832 *
7833 * @param {DOMElement} container DOM element to register as a container.
7834 * @return {string} The "reactRoot" ID of elements rendered within.
7835 */
7836 registerContainer: function(container) {
7837 var reactRootID = getReactRootID(container);
7838 if (reactRootID) {
7839 // If one exists, make sure it is a valid "reactRoot" ID.
7840 reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);
7841 }
7842 if (!reactRootID) {
7843 // No valid "reactRoot" ID found, create one.
7844 reactRootID = ReactInstanceHandles.createReactRootID();
7845 }
7846 containersByReactRootID[reactRootID] = container;
7847 return reactRootID;
7848 },
7849
7850 /**
7851 * Unmounts and destroys the React component rendered in the `container`.
7852 *
7853 * @param {DOMElement} container DOM element containing a React component.
7854 * @return {boolean} True if a component was found in and unmounted from
7855 * `container`
7856 */
7857 unmountAndReleaseReactRootNode: function(container) {
7858 var reactRootID = getReactRootID(container);
7859 var component = instancesByReactRootID[reactRootID];
7860 if (!component) {
7861 return false;
7862 }
7863 ReactMount.unmountComponentFromNode(component, container);
7864 delete instancesByReactRootID[reactRootID];
7865 delete containersByReactRootID[reactRootID];
7866 if (true) {
7867 delete rootElementsByReactRootID[reactRootID];
7868 }
7869 return true;
7870 },
7871
7872 /**
7873 * Unmounts a component and removes it from the DOM.
7874 *
7875 * @param {ReactComponent} instance React component instance.
7876 * @param {DOMElement} container DOM element to unmount from.
7877 * @final
7878 * @internal
7879 * @see {ReactMount.unmountAndReleaseReactRootNode}
7880 */
7881 unmountComponentFromNode: function(instance, container) {
7882 instance.unmountComponent();
7883
7884 // http://jsperf.com/emptying-a-node
7885 while (container.lastChild) {
7886 container.removeChild(container.lastChild);
7887 }
7888 },
7889
7890 /**
7891 * Finds the container DOM element that contains React component to which the
7892 * supplied DOM `id` belongs.
7893 *
7894 * @param {string} id The ID of an element rendered by a React component.
7895 * @return {?DOMElement} DOM element that contains the `id`.
7896 */
7897 findReactContainerForID: function(id) {
7898 var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);
7899 var container = containersByReactRootID[reactRootID];
7900
7901 if (true) {
7902 var rootElement = rootElementsByReactRootID[reactRootID];
7903 if (rootElement && rootElement.parentNode !== container) {
7904 invariant(
7905 // Call internalGetID here because getID calls isValid which calls
7906 // findReactContainerForID (this function).
7907 internalGetID(rootElement) === reactRootID,
7908 'ReactMount: Root element ID differed from reactRootID.'
7909 );
7910
7911 var containerChild = container.firstChild;
7912 if (containerChild &&
7913 reactRootID === internalGetID(containerChild)) {
7914 // If the container has a new child with the same ID as the old
7915 // root element, then rootElementsByReactRootID[reactRootID] is
7916 // just stale and needs to be updated. The case that deserves a
7917 // warning is when the container is empty.
7918 rootElementsByReactRootID[reactRootID] = containerChild;
7919 } else {
7920 console.warn(
7921 'ReactMount: Root element has been removed from its original ' +
7922 'container. New container:', rootElement.parentNode
7923 );
7924 }
7925 }
7926 }
7927
7928 return container;
7929 },
7930
7931 /**
7932 * Finds an element rendered by React with the supplied ID.
7933 *
7934 * @param {string} id ID of a DOM node in the React component.
7935 * @return {DOMElement} Root DOM node of the React component.
7936 */
7937 findReactNodeByID: function(id) {
7938 var reactRoot = ReactMount.findReactContainerForID(id);
7939 return ReactMount.findComponentRoot(reactRoot, id);
7940 },
7941
7942 /**
7943 * True if the supplied `node` is rendered by React.
7944 *
7945 * @param {*} node DOM Element to check.
7946 * @return {boolean} True if the DOM Element appears to be rendered by React.
7947 * @internal
7948 */
7949 isRenderedByReact: function(node) {
7950 if (node.nodeType !== 1) {
7951 // Not a DOMElement, therefore not a React component
7952 return false;
7953 }
7954 var id = ReactMount.getID(node);
7955 return id ? id.charAt(0) === SEPARATOR : false;
7956 },
7957
7958 /**
7959 * Traverses up the ancestors of the supplied node to find a node that is a
7960 * DOM representation of a React component.
7961 *
7962 * @param {*} node
7963 * @return {?DOMEventTarget}
7964 * @internal
7965 */
7966 getFirstReactDOM: function(node) {
7967 var current = node;
7968 while (current && current.parentNode !== current) {
7969 if (ReactMount.isRenderedByReact(current)) {
7970 return current;
7971 }
7972 current = current.parentNode;
7973 }
7974 return null;
7975 },
7976
7977 /**
7978 * Finds a node with the supplied `id` inside of the supplied `ancestorNode`.
7979 * Exploits the ID naming scheme to perform the search quickly.
7980 *
7981 * @param {DOMEventTarget} ancestorNode Search from this root.
7982 * @pararm {string} id ID of the DOM representation of the component.
7983 * @return {DOMEventTarget} DOM node with the supplied `id`.
7984 * @internal
7985 */
7986 findComponentRoot: function(ancestorNode, id) {
7987 var firstChildren = [ancestorNode.firstChild];
7988 var childIndex = 0;
7989
7990 while (childIndex < firstChildren.length) {
7991 var child = firstChildren[childIndex++];
7992 while (child) {
7993 var childID = ReactMount.getID(child);
7994 if (childID) {
7995 if (id === childID) {
7996 return child;
7997 } else if (ReactInstanceHandles.isAncestorIDOf(childID, id)) {
7998 // If we find a child whose ID is an ancestor of the given ID,
7999 // then we can be sure that we only want to search the subtree
8000 // rooted at this child, so we can throw out the rest of the
8001 // search state.
8002 firstChildren.length = childIndex = 0;
8003 firstChildren.push(child.firstChild);
8004 break;
8005 } else {
8006 // TODO This should not be necessary if the ID hierarchy is
8007 // correct, but is occasionally necessary if the DOM has been
8008 // modified in unexpected ways.
8009 firstChildren.push(child.firstChild);
8010 }
8011 } else {
8012 // If this child had no ID, then there's a chance that it was
8013 // injected automatically by the browser, as when a `<table>`
8014 // element sprouts an extra `<tbody>` child as a side effect of
8015 // `.innerHTML` parsing. Optimistically continue down this
8016 // branch, but not before examining the other siblings.
8017 firstChildren.push(child.firstChild);
8018 }
8019 child = child.nextSibling;
8020 }
8021 }
8022
8023 if (true) {
8024 console.error(
8025 'Error while invoking `findComponentRoot` with the following ' +
8026 'ancestor node:',
8027 ancestorNode
8028 );
8029 }
8030 invariant(
8031 false,
8032 'findComponentRoot(..., %s): Unable to find element. This probably ' +
8033 'means the DOM was unexpectedly mutated (e.g. by the browser).',
8034 id,
8035 ReactMount.getID(ancestorNode)
8036 );
8037 },
8038
8039
8040 /**
8041 * React ID utilities.
8042 */
8043
8044 ATTR_NAME: ATTR_NAME,
8045
8046 getID: getID,
8047
8048 setID: setID,
8049
8050 getNode: getNode,
8051
8052 purgeID: purgeID,
8053
8054 injection: {}
8055};
8056
8057module.exports = ReactMount;
8058
8059},{"./$":1,"./ReactEventEmitter":39,"./ReactInstanceHandles":43,"./getReactRootElementInContainer":86,"./invariant":89}],46:[function(require,module,exports){
8060/**
8061 * Copyright 2013 Facebook, Inc.
8062 *
8063 * Licensed under the Apache License, Version 2.0 (the "License");
8064 * you may not use this file except in compliance with the License.
8065 * You may obtain a copy of the License at
8066 *
8067 * http://www.apache.org/licenses/LICENSE-2.0
8068 *
8069 * Unless required by applicable law or agreed to in writing, software
8070 * distributed under the License is distributed on an "AS IS" BASIS,
8071 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8072 * See the License for the specific language governing permissions and
8073 * limitations under the License.
8074 *
8075 * @providesModule ReactMultiChild
8076 * @typechecks static-only
8077 */
8078
8079"use strict";
8080
8081var ReactComponent = require("./ReactComponent");
8082var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
8083
8084/**
8085 * Given a `curChild` and `newChild`, determines if `curChild` should be
8086 * updated as opposed to being destroyed or replaced.
8087 *
8088 * @param {?ReactComponent} curChild
8089 * @param {?ReactComponent} newChild
8090 * @return {boolean} True if `curChild` should be updated with `newChild`.
8091 * @protected
8092 */
8093function shouldUpdateChild(curChild, newChild) {
8094 return curChild && newChild && curChild.constructor === newChild.constructor;
8095}
8096
8097/**
8098 * Updating children of a component may trigger recursive updates. The depth is
8099 * used to batch recursive updates to render markup more efficiently.
8100 *
8101 * @type {number}
8102 * @private
8103 */
8104var updateDepth = 0;
8105
8106/**
8107 * Queue of update configuration objects.
8108 *
8109 * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`.
8110 *
8111 * @type {array<object>}
8112 * @private
8113 */
8114var updateQueue = [];
8115
8116/**
8117 * Queue of markup to be rendered.
8118 *
8119 * @type {array<string>}
8120 * @private
8121 */
8122var markupQueue = [];
8123
8124/**
8125 * Enqueues markup to be rendered and inserted at a supplied index.
8126 *
8127 * @param {string} parentID ID of the parent component.
8128 * @param {string} markup Markup that renders into an element.
8129 * @param {number} toIndex Destination index.
8130 * @private
8131 */
8132function enqueueMarkup(parentID, markup, toIndex) {
8133 // NOTE: Null values reduce hidden classes.
8134 updateQueue.push({
8135 parentID: parentID,
8136 parentNode: null,
8137 type: ReactMultiChildUpdateTypes.INSERT_MARKUP,
8138 markupIndex: markupQueue.push(markup) - 1,
8139 fromIndex: null,
8140 textContent: null,
8141 toIndex: toIndex
8142 });
8143}
8144
8145/**
8146 * Enqueues moving an existing element to another index.
8147 *
8148 * @param {string} parentID ID of the parent component.
8149 * @param {number} fromIndex Source index of the existing element.
8150 * @param {number} toIndex Destination index of the element.
8151 * @private
8152 */
8153function enqueueMove(parentID, fromIndex, toIndex) {
8154 // NOTE: Null values reduce hidden classes.
8155 updateQueue.push({
8156 parentID: parentID,
8157 parentNode: null,
8158 type: ReactMultiChildUpdateTypes.MOVE_EXISTING,
8159 markupIndex: null,
8160 textContent: null,
8161 fromIndex: fromIndex,
8162 toIndex: toIndex
8163 });
8164}
8165
8166/**
8167 * Enqueues removing an element at an index.
8168 *
8169 * @param {string} parentID ID of the parent component.
8170 * @param {number} fromIndex Index of the element to remove.
8171 * @private
8172 */
8173function enqueueRemove(parentID, fromIndex) {
8174 // NOTE: Null values reduce hidden classes.
8175 updateQueue.push({
8176 parentID: parentID,
8177 parentNode: null,
8178 type: ReactMultiChildUpdateTypes.REMOVE_NODE,
8179 markupIndex: null,
8180 textContent: null,
8181 fromIndex: fromIndex,
8182 toIndex: null
8183 });
8184}
8185
8186/**
8187 * Enqueues setting the text content.
8188 *
8189 * @param {string} parentID ID of the parent component.
8190 * @param {string} textContent Text content to set.
8191 * @private
8192 */
8193function enqueueTextContent(parentID, textContent) {
8194 // NOTE: Null values reduce hidden classes.
8195 updateQueue.push({
8196 parentID: parentID,
8197 parentNode: null,
8198 type: ReactMultiChildUpdateTypes.TEXT_CONTENT,
8199 markupIndex: null,
8200 textContent: textContent,
8201 fromIndex: null,
8202 toIndex: null
8203 });
8204}
8205
8206/**
8207 * Processes any enqueued updates.
8208 *
8209 * @private
8210 */
8211function processQueue() {
8212 if (updateQueue.length) {
8213 ReactComponent.DOMIDOperations.dangerouslyProcessChildrenUpdates(
8214 updateQueue,
8215 markupQueue
8216 );
8217 clearQueue();
8218 }
8219}
8220
8221/**
8222 * Clears any enqueued updates.
8223 *
8224 * @private
8225 */
8226function clearQueue() {
8227 updateQueue.length = 0;
8228 markupQueue.length = 0;
8229}
8230
8231/**
8232 * ReactMultiChild are capable of reconciling multiple children.
8233 *
8234 * @class ReactMultiChild
8235 * @internal
8236 */
8237var ReactMultiChild = {
8238
8239 /**
8240 * Provides common functionality for components that must reconcile multiple
8241 * children. This is used by `ReactNativeComponent` to mount, update, and
8242 * unmount child components.
8243 *
8244 * @lends {ReactMultiChild.prototype}
8245 */
8246 Mixin: {
8247
8248 /**
8249 * Generates a "mount image" for each of the supplied children. In the case
8250 * of `ReactNativeComponent`, a mount image is a string of markup.
8251 *
8252 * @param {?object} children As returned by `flattenChildren`.
8253 * @return {array} An array of mounted representations.
8254 * @internal
8255 */
8256 mountChildren: function(children, transaction) {
8257 var mountImages = [];
8258 var index = 0;
8259 for (var name in children) {
8260 var child = children[name];
8261 if (children.hasOwnProperty(name) && child) {
8262 // Inlined for performance, see `ReactInstanceHandles.createReactID`.
8263 var rootID = this._rootNodeID + '.' + name;
8264 var mountImage = child.mountComponent(rootID, transaction);
8265 child._mountImage = mountImage;
8266 child._mountIndex = index;
8267 mountImages.push(mountImage);
8268 index++;
8269 }
8270 }
8271 this._renderedChildren = children;
8272 return mountImages;
8273 },
8274
8275 /**
8276 * Replaces any rendered children with a text content string.
8277 *
8278 * @param {string} nextContent String of content.
8279 * @internal
8280 */
8281 updateTextContent: function(nextContent) {
8282 updateDepth++;
8283 try {
8284 var prevChildren = this._renderedChildren;
8285 // Remove any rendered children.
8286 for (var name in prevChildren) {
8287 if (prevChildren.hasOwnProperty(name) &&
8288 prevChildren[name]) {
8289 this._unmountChildByName(prevChildren[name], name);
8290 }
8291 }
8292 // Set new text content.
8293 this.setTextContent(nextContent);
8294 } catch (error) {
8295 updateDepth--;
8296 updateDepth || clearQueue();
8297 throw error;
8298 }
8299 updateDepth--;
8300 updateDepth || processQueue();
8301 },
8302
8303 /**
8304 * Updates the rendered children with new children.
8305 *
8306 * @param {?object} nextChildren As returned by `flattenChildren`.
8307 * @param {ReactReconcileTransaction} transaction
8308 * @internal
8309 */
8310 updateChildren: function(nextChildren, transaction) {
8311 updateDepth++;
8312 try {
8313 this._updateChildren(nextChildren, transaction);
8314 } catch (error) {
8315 updateDepth--;
8316 updateDepth || clearQueue();
8317 throw error;
8318 }
8319 updateDepth--;
8320 updateDepth || processQueue();
8321 },
8322
8323 /**
8324 * Improve performance by isolating this hot code path from the try/catch
8325 * block in `updateChildren`.
8326 *
8327 * @param {?object} nextChildren As returned by `flattenChildren`.
8328 * @param {ReactReconcileTransaction} transaction
8329 * @final
8330 * @protected
8331 */
8332 _updateChildren: function(nextChildren, transaction) {
8333 var prevChildren = this._renderedChildren;
8334 if (!nextChildren && !prevChildren) {
8335 return;
8336 }
8337 var name;
8338 // `nextIndex` will increment for each child in `nextChildren`, but
8339 // `lastIndex` will be the last index visited in `prevChildren`.
8340 var lastIndex = 0;
8341 var nextIndex = 0;
8342 for (name in nextChildren) {
8343 if (!nextChildren.hasOwnProperty(name)) {
8344 continue;
8345 }
8346 var prevChild = prevChildren && prevChildren[name];
8347 var nextChild = nextChildren[name];
8348 if (shouldUpdateChild(prevChild, nextChild)) {
8349 this.moveChild(prevChild, nextIndex, lastIndex);
8350 lastIndex = Math.max(prevChild._mountIndex, lastIndex);
8351 prevChild.receiveProps(nextChild.props, transaction);
8352 prevChild._mountIndex = nextIndex;
8353 } else {
8354 if (prevChild) {
8355 // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
8356 lastIndex = Math.max(prevChild._mountIndex, lastIndex);
8357 this._unmountChildByName(prevChild, name);
8358 }
8359 if (nextChild) {
8360 this._mountChildByNameAtIndex(
8361 nextChild, name, nextIndex, transaction
8362 );
8363 }
8364 }
8365 if (nextChild) {
8366 nextIndex++;
8367 }
8368 }
8369 // Remove children that are no longer present.
8370 for (name in prevChildren) {
8371 if (prevChildren.hasOwnProperty(name) &&
8372 prevChildren[name] &&
8373 !(nextChildren && nextChildren[name])) {
8374 this._unmountChildByName(prevChildren[name], name);
8375 }
8376 }
8377 },
8378
8379 /**
8380 * Unmounts all rendered children. This should be used to clean up children
8381 * when this component is unmounted.
8382 *
8383 * @internal
8384 */
8385 unmountChildren: function() {
8386 var renderedChildren = this._renderedChildren;
8387 for (var name in renderedChildren) {
8388 var renderedChild = renderedChildren[name];
8389 if (renderedChild && renderedChild.unmountComponent) {
8390 renderedChild.unmountComponent();
8391 }
8392 }
8393 this._renderedChildren = null;
8394 },
8395
8396 /**
8397 * Moves a child component to the supplied index.
8398 *
8399 * @param {ReactComponent} child Component to move.
8400 * @param {number} toIndex Destination index of the element.
8401 * @param {number} lastIndex Last index visited of the siblings of `child`.
8402 * @protected
8403 */
8404 moveChild: function(child, toIndex, lastIndex) {
8405 // If the index of `child` is less than `lastIndex`, then it needs to
8406 // be moved. Otherwise, we do not need to move it because a child will be
8407 // inserted or moved before `child`.
8408 if (child._mountIndex < lastIndex) {
8409 enqueueMove(this._rootNodeID, child._mountIndex, toIndex);
8410 }
8411 },
8412
8413 /**
8414 * Creates a child component.
8415 *
8416 * @param {ReactComponent} child Component to create.
8417 * @protected
8418 */
8419 createChild: function(child) {
8420 enqueueMarkup(this._rootNodeID, child._mountImage, child._mountIndex);
8421 },
8422
8423 /**
8424 * Removes a child component.
8425 *
8426 * @param {ReactComponent} child Child to remove.
8427 * @protected
8428 */
8429 removeChild: function(child) {
8430 enqueueRemove(this._rootNodeID, child._mountIndex);
8431 },
8432
8433 /**
8434 * Sets this text content string.
8435 *
8436 * @param {string} textContent Text content to set.
8437 * @protected
8438 */
8439 setTextContent: function(textContent) {
8440 enqueueTextContent(this._rootNodeID, textContent);
8441 },
8442
8443 /**
8444 * Mounts a child with the supplied name.
8445 *
8446 * NOTE: This is part of `updateChildren` and is here for readability.
8447 *
8448 * @param {ReactComponent} child Component to mount.
8449 * @param {string} name Name of the child.
8450 * @param {number} index Index at which to insert the child.
8451 * @param {ReactReconcileTransaction} transaction
8452 * @private
8453 */
8454 _mountChildByNameAtIndex: function(child, name, index, transaction) {
8455 // Inlined for performance, see `ReactInstanceHandles.createReactID`.
8456 var rootID = this._rootNodeID + '.' + name;
8457 var mountImage = child.mountComponent(rootID, transaction);
8458 child._mountImage = mountImage;
8459 child._mountIndex = index;
8460 this.createChild(child);
8461 this._renderedChildren = this._renderedChildren || {};
8462 this._renderedChildren[name] = child;
8463 },
8464
8465 /**
8466 * Unmounts a rendered child by name.
8467 *
8468 * NOTE: This is part of `updateChildren` and is here for readability.
8469 *
8470 * @param {ReactComponent} child Component to unmount.
8471 * @param {string} name Name of the child in `this._renderedChildren`.
8472 * @private
8473 */
8474 _unmountChildByName: function(child, name) {
8475 if (ReactComponent.isValidComponent(child)) {
8476 this.removeChild(child);
8477 child._mountImage = null;
8478 child._mountIndex = null;
8479 child.unmountComponent();
8480 delete this._renderedChildren[name];
8481 }
8482 }
8483
8484 }
8485
8486};
8487
8488module.exports = ReactMultiChild;
8489
8490},{"./ReactComponent":23,"./ReactMultiChildUpdateTypes":47}],47:[function(require,module,exports){
8491/**
8492 * Copyright 2013 Facebook, Inc.
8493 *
8494 * Licensed under the Apache License, Version 2.0 (the "License");
8495 * you may not use this file except in compliance with the License.
8496 * You may obtain a copy of the License at
8497 *
8498 * http://www.apache.org/licenses/LICENSE-2.0
8499 *
8500 * Unless required by applicable law or agreed to in writing, software
8501 * distributed under the License is distributed on an "AS IS" BASIS,
8502 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8503 * See the License for the specific language governing permissions and
8504 * limitations under the License.
8505 *
8506 * @providesModule ReactMultiChildUpdateTypes
8507 */
8508
8509var keyMirror = require("./keyMirror");
8510
8511/**
8512 * When a component's children are updated, a series of update configuration
8513 * objects are created in order to batch and serialize the required changes.
8514 *
8515 * Enumerates all the possible types of update configurations.
8516 *
8517 * @internal
8518 */
8519var ReactMultiChildUpdateTypes = keyMirror({
8520 INSERT_MARKUP: null,
8521 MOVE_EXISTING: null,
8522 REMOVE_NODE: null,
8523 TEXT_CONTENT: null
8524});
8525
8526module.exports = ReactMultiChildUpdateTypes;
8527
8528},{"./keyMirror":92}],48:[function(require,module,exports){
8529/**
8530 * Copyright 2013 Facebook, Inc.
8531 *
8532 * Licensed under the Apache License, Version 2.0 (the "License");
8533 * you may not use this file except in compliance with the License.
8534 * You may obtain a copy of the License at
8535 *
8536 * http://www.apache.org/licenses/LICENSE-2.0
8537 *
8538 * Unless required by applicable law or agreed to in writing, software
8539 * distributed under the License is distributed on an "AS IS" BASIS,
8540 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8541 * See the License for the specific language governing permissions and
8542 * limitations under the License.
8543 *
8544 * @providesModule ReactNativeComponent
8545 * @typechecks static-only
8546 */
8547
8548"use strict";
8549
8550var CSSPropertyOperations = require("./CSSPropertyOperations");
8551var DOMProperty = require("./DOMProperty");
8552var DOMPropertyOperations = require("./DOMPropertyOperations");
8553var ReactComponent = require("./ReactComponent");
8554var ReactEventEmitter = require("./ReactEventEmitter");
8555var ReactMultiChild = require("./ReactMultiChild");
8556var ReactMount = require("./ReactMount");
8557var ReactPerf = require("./ReactPerf");
8558
8559var escapeTextForBrowser = require("./escapeTextForBrowser");
8560var flattenChildren = require("./flattenChildren");
8561var invariant = require("./invariant");
8562var keyOf = require("./keyOf");
8563var merge = require("./merge");
8564var mixInto = require("./mixInto");
8565
8566var putListener = ReactEventEmitter.putListener;
8567var deleteListener = ReactEventEmitter.deleteListener;
8568var registrationNames = ReactEventEmitter.registrationNames;
8569
8570// For quickly matching children type, to test if can be treated as content.
8571var CONTENT_TYPES = {'string': true, 'number': true};
8572
8573var DANGEROUSLY_SET_INNER_HTML = keyOf({dangerouslySetInnerHTML: null});
8574var STYLE = keyOf({style: null});
8575
8576/**
8577 * @param {?object} props
8578 */
8579function assertValidProps(props) {
8580 if (!props) {
8581 return;
8582 }
8583 // Note the use of `==` which checks for null or undefined.
8584 invariant(
8585 props.children == null || props.dangerouslySetInnerHTML == null,
8586 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
8587 );
8588 invariant(
8589 props.style == null || typeof props.style === 'object',
8590 'The `style` prop expects a mapping from style properties to values, ' +
8591 'not a string.'
8592 );
8593}
8594
8595/**
8596 * @constructor ReactNativeComponent
8597 * @extends ReactComponent
8598 * @extends ReactMultiChild
8599 */
8600function ReactNativeComponent(tag, omitClose) {
8601 this._tagOpen = '<' + tag;
8602 this._tagClose = omitClose ? '' : '</' + tag + '>';
8603 this.tagName = tag.toUpperCase();
8604}
8605
8606ReactNativeComponent.Mixin = {
8607
8608 /**
8609 * Generates root tag markup then recurses. This method has side effects and
8610 * is not idempotent.
8611 *
8612 * @internal
8613 * @param {string} rootID The root DOM ID for this node.
8614 * @param {ReactReconcileTransaction} transaction
8615 * @return {string} The computed markup.
8616 */
8617 mountComponent: ReactPerf.measure(
8618 'ReactNativeComponent',
8619 'mountComponent',
8620 function(rootID, transaction) {
8621 ReactComponent.Mixin.mountComponent.call(this, rootID, transaction);
8622 assertValidProps(this.props);
8623 return (
8624 this._createOpenTagMarkup() +
8625 this._createContentMarkup(transaction) +
8626 this._tagClose
8627 );
8628 }
8629 ),
8630
8631 /**
8632 * Creates markup for the open tag and all attributes.
8633 *
8634 * This method has side effects because events get registered.
8635 *
8636 * Iterating over object properties is faster than iterating over arrays.
8637 * @see http://jsperf.com/obj-vs-arr-iteration
8638 *
8639 * @private
8640 * @return {string} Markup of opening tag.
8641 */
8642 _createOpenTagMarkup: function() {
8643 var props = this.props;
8644 var ret = this._tagOpen;
8645
8646 for (var propKey in props) {
8647 if (!props.hasOwnProperty(propKey)) {
8648 continue;
8649 }
8650 var propValue = props[propKey];
8651 if (propValue == null) {
8652 continue;
8653 }
8654 if (registrationNames[propKey]) {
8655 putListener(this._rootNodeID, propKey, propValue);
8656 } else {
8657 if (propKey === STYLE) {
8658 if (propValue) {
8659 propValue = props.style = merge(props.style);
8660 }
8661 propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
8662 }
8663 var markup =
8664 DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
8665 if (markup) {
8666 ret += ' ' + markup;
8667 }
8668 }
8669 }
8670
8671 var escapedID = escapeTextForBrowser(this._rootNodeID);
8672 return ret + ' ' + ReactMount.ATTR_NAME + '="' + escapedID + '">';
8673 },
8674
8675 /**
8676 * Creates markup for the content between the tags.
8677 *
8678 * @private
8679 * @param {ReactReconcileTransaction} transaction
8680 * @return {string} Content markup.
8681 */
8682 _createContentMarkup: function(transaction) {
8683 // Intentional use of != to avoid catching zero/false.
8684 var innerHTML = this.props.dangerouslySetInnerHTML;
8685 if (innerHTML != null) {
8686 if (innerHTML.__html != null) {
8687 return innerHTML.__html;
8688 }
8689 } else {
8690 var contentToUse =
8691 CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;
8692 var childrenToUse = contentToUse != null ? null : this.props.children;
8693 if (contentToUse != null) {
8694 return escapeTextForBrowser(contentToUse);
8695 } else if (childrenToUse != null) {
8696 var mountImages = this.mountChildren(
8697 flattenChildren(childrenToUse),
8698 transaction
8699 );
8700 return mountImages.join('');
8701 }
8702 }
8703 return '';
8704 },
8705
8706 receiveProps: function(nextProps, transaction) {
8707 assertValidProps(nextProps);
8708 ReactComponent.Mixin.receiveProps.call(this, nextProps, transaction);
8709 },
8710
8711 /**
8712 * Updates a native DOM component after it has already been allocated and
8713 * attached to the DOM. Reconciles the root DOM node, then recurses.
8714 *
8715 * @param {ReactReconcileTransaction} transaction
8716 * @param {object} prevProps
8717 * @internal
8718 * @overridable
8719 */
8720 updateComponent: ReactPerf.measure(
8721 'ReactNativeComponent',
8722 'updateComponent',
8723 function(transaction, prevProps) {
8724 ReactComponent.Mixin.updateComponent.call(this, transaction, prevProps);
8725 this._updateDOMProperties(prevProps);
8726 this._updateDOMChildren(prevProps, transaction);
8727 }
8728 ),
8729
8730 /**
8731 * Reconciles the properties by detecting differences in property values and
8732 * updating the DOM as necessary. This function is probably the single most
8733 * critical path for performance optimization.
8734 *
8735 * TODO: Benchmark whether checking for changed values in memory actually
8736 * improves performance (especially statically positioned elements).
8737 * TODO: Benchmark the effects of putting this at the top since 99% of props
8738 * do not change for a given reconciliation.
8739 * TODO: Benchmark areas that can be improved with caching.
8740 *
8741 * @private
8742 * @param {object} lastProps
8743 */
8744 _updateDOMProperties: function(lastProps) {
8745 var nextProps = this.props;
8746 var propKey;
8747 var styleName;
8748 var styleUpdates;
8749 for (propKey in lastProps) {
8750 if (nextProps.hasOwnProperty(propKey) ||
8751 !lastProps.hasOwnProperty(propKey)) {
8752 continue;
8753 }
8754 if (propKey === STYLE) {
8755 var lastStyle = lastProps[propKey];
8756 for (styleName in lastStyle) {
8757 if (lastStyle.hasOwnProperty(styleName)) {
8758 styleUpdates = styleUpdates || {};
8759 styleUpdates[styleName] = '';
8760 }
8761 }
8762 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8763 // http://jsperf.com/emptying-speed
8764 ReactComponent.DOMIDOperations.updateTextContentByID(
8765 this._rootNodeID,
8766 ''
8767 );
8768 } else if (registrationNames[propKey]) {
8769 deleteListener(this._rootNodeID, propKey);
8770 } else {
8771 ReactComponent.DOMIDOperations.deletePropertyByID(
8772 this._rootNodeID,
8773 propKey
8774 );
8775 }
8776 }
8777 for (propKey in nextProps) {
8778 var nextProp = nextProps[propKey];
8779 var lastProp = lastProps[propKey];
8780 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
8781 continue;
8782 }
8783 if (propKey === STYLE) {
8784 if (nextProp) {
8785 nextProp = nextProps.style = merge(nextProp);
8786 }
8787 if (lastProp) {
8788 // Unset styles on `lastProp` but not on `nextProp`.
8789 for (styleName in lastProp) {
8790 if (lastProp.hasOwnProperty(styleName) &&
8791 !nextProp.hasOwnProperty(styleName)) {
8792 styleUpdates = styleUpdates || {};
8793 styleUpdates[styleName] = '';
8794 }
8795 }
8796 // Update styles that changed since `lastProp`.
8797 for (styleName in nextProp) {
8798 if (nextProp.hasOwnProperty(styleName) &&
8799 lastProp[styleName] !== nextProp[styleName]) {
8800 styleUpdates = styleUpdates || {};
8801 styleUpdates[styleName] = nextProp[styleName];
8802 }
8803 }
8804 } else {
8805 // Relies on `updateStylesByID` not mutating `styleUpdates`.
8806 styleUpdates = nextProp;
8807 }
8808 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8809 var lastHtml = lastProp && lastProp.__html;
8810 var nextHtml = nextProp && nextProp.__html;
8811 if (lastHtml !== nextHtml) {
8812 ReactComponent.DOMIDOperations.updateInnerHTMLByID(
8813 this._rootNodeID,
8814 nextProp
8815 );
8816 }
8817 } else if (registrationNames[propKey]) {
8818 putListener(this._rootNodeID, propKey, nextProp);
8819 } else if (
8820 DOMProperty.isStandardName[propKey] ||
8821 DOMProperty.isCustomAttribute(propKey)) {
8822 ReactComponent.DOMIDOperations.updatePropertyByID(
8823 this._rootNodeID,
8824 propKey,
8825 nextProp
8826 );
8827 }
8828 }
8829 if (styleUpdates) {
8830 ReactComponent.DOMIDOperations.updateStylesByID(
8831 this._rootNodeID,
8832 styleUpdates
8833 );
8834 }
8835 },
8836
8837 /**
8838 * Reconciles the children with the various properties that affect the
8839 * children content.
8840 *
8841 * @param {object} lastProps
8842 * @param {ReactReconcileTransaction} transaction
8843 */
8844 _updateDOMChildren: function(lastProps, transaction) {
8845 var nextProps = this.props;
8846
8847 var lastUsedContent =
8848 CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
8849 var contentToUse =
8850 CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
8851
8852 // Note the use of `!=` which checks for null or undefined.
8853
8854 var lastUsedChildren =
8855 lastUsedContent != null ? null : lastProps.children;
8856 var childrenToUse = contentToUse != null ? null : nextProps.children;
8857
8858 if (contentToUse != null) {
8859 var childrenRemoved = lastUsedChildren != null && childrenToUse == null;
8860 if (childrenRemoved) {
8861 this.updateChildren(null, transaction);
8862 }
8863 if (lastUsedContent !== contentToUse) {
8864 this.updateTextContent('' + contentToUse);
8865 }
8866 } else {
8867 var contentRemoved = lastUsedContent != null && contentToUse == null;
8868 if (contentRemoved) {
8869 this.updateTextContent('');
8870 }
8871 this.updateChildren(flattenChildren(nextProps.children), transaction);
8872 }
8873 },
8874
8875 /**
8876 * Destroys all event registrations for this instance. Does not remove from
8877 * the DOM. That must be done by the parent.
8878 *
8879 * @internal
8880 */
8881 unmountComponent: function() {
8882 ReactEventEmitter.deleteAllListeners(this._rootNodeID);
8883 ReactComponent.Mixin.unmountComponent.call(this);
8884 this.unmountChildren();
8885 }
8886
8887};
8888
8889mixInto(ReactNativeComponent, ReactComponent.Mixin);
8890mixInto(ReactNativeComponent, ReactNativeComponent.Mixin);
8891mixInto(ReactNativeComponent, ReactMultiChild.Mixin);
8892
8893module.exports = ReactNativeComponent;
8894
8895},{"./CSSPropertyOperations":3,"./DOMProperty":7,"./DOMPropertyOperations":8,"./ReactComponent":23,"./ReactEventEmitter":39,"./ReactMount":45,"./ReactMultiChild":46,"./ReactPerf":51,"./escapeTextForBrowser":78,"./flattenChildren":81,"./invariant":89,"./keyOf":93,"./merge":95,"./mixInto":98}],49:[function(require,module,exports){
8896/**
8897 * Copyright 2013 Facebook, Inc.
8898 *
8899 * Licensed under the Apache License, Version 2.0 (the "License");
8900 * you may not use this file except in compliance with the License.
8901 * You may obtain a copy of the License at
8902 *
8903 * http://www.apache.org/licenses/LICENSE-2.0
8904 *
8905 * Unless required by applicable law or agreed to in writing, software
8906 * distributed under the License is distributed on an "AS IS" BASIS,
8907 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8908 * See the License for the specific language governing permissions and
8909 * limitations under the License.
8910 *
8911 * @providesModule ReactOnDOMReady
8912 */
8913
8914"use strict";
8915
8916var PooledClass = require("./PooledClass");
8917
8918var mixInto = require("./mixInto");
8919
8920/**
8921 * A specialized pseudo-event module to help keep track of components waiting to
8922 * be notified when their DOM representations are available for use.
8923 *
8924 * This implements `PooledClass`, so you should never need to instantiate this.
8925 * Instead, use `ReactOnDOMReady.getPooled()`.
8926 *
8927 * @param {?array<function>} initialCollection
8928 * @class ReactOnDOMReady
8929 * @implements PooledClass
8930 * @internal
8931 */
8932function ReactOnDOMReady(initialCollection) {
8933 this._queue = initialCollection || null;
8934}
8935
8936mixInto(ReactOnDOMReady, {
8937
8938 /**
8939 * Enqueues a callback to be invoked when `notifyAll` is invoked. This is used
8940 * to enqueue calls to `componentDidMount` and `componentDidUpdate`.
8941 *
8942 * @param {ReactComponent} component Component being rendered.
8943 * @param {function(DOMElement)} callback Invoked when `notifyAll` is invoked.
8944 * @internal
8945 */
8946 enqueue: function(component, callback) {
8947 this._queue = this._queue || [];
8948 this._queue.push({component: component, callback: callback});
8949 },
8950
8951 /**
8952 * Invokes all enqueued callbacks and clears the queue. This is invoked after
8953 * the DOM representation of a component has been created or updated.
8954 *
8955 * @internal
8956 */
8957 notifyAll: function() {
8958 var queue = this._queue;
8959 if (queue) {
8960 this._queue = null;
8961 for (var i = 0, l = queue.length; i < l; i++) {
8962 var component = queue[i].component;
8963 var callback = queue[i].callback;
8964 callback.call(component, component.getDOMNode());
8965 }
8966 queue.length = 0;
8967 }
8968 },
8969
8970 /**
8971 * Resets the internal queue.
8972 *
8973 * @internal
8974 */
8975 reset: function() {
8976 this._queue = null;
8977 },
8978
8979 /**
8980 * `PooledClass` looks for this.
8981 */
8982 destructor: function() {
8983 this.reset();
8984 }
8985
8986});
8987
8988PooledClass.addPoolingTo(ReactOnDOMReady);
8989
8990module.exports = ReactOnDOMReady;
8991
8992},{"./PooledClass":21,"./mixInto":98}],50:[function(require,module,exports){
8993/**
8994 * Copyright 2013 Facebook, Inc.
8995 *
8996 * Licensed under the Apache License, Version 2.0 (the "License");
8997 * you may not use this file except in compliance with the License.
8998 * You may obtain a copy of the License at
8999 *
9000 * http://www.apache.org/licenses/LICENSE-2.0
9001 *
9002 * Unless required by applicable law or agreed to in writing, software
9003 * distributed under the License is distributed on an "AS IS" BASIS,
9004 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9005 * See the License for the specific language governing permissions and
9006 * limitations under the License.
9007 *
9008 * @providesModule ReactOwner
9009 */
9010
9011"use strict";
9012
9013var invariant = require("./invariant");
9014
9015/**
9016 * ReactOwners are capable of storing references to owned components.
9017 *
9018 * All components are capable of //being// referenced by owner components, but
9019 * only ReactOwner components are capable of //referencing// owned components.
9020 * The named reference is known as a "ref".
9021 *
9022 * Refs are available when mounted and updated during reconciliation.
9023 *
9024 * var MyComponent = React.createClass({
9025 * render: function() {
9026 * return (
9027 * <div onClick={this.handleClick}>
9028 * <CustomComponent ref="custom" />
9029 * </div>
9030 * );
9031 * },
9032 * handleClick: function() {
9033 * this.refs.custom.handleClick();
9034 * },
9035 * componentDidMount: function() {
9036 * this.refs.custom.initialize();
9037 * }
9038 * });
9039 *
9040 * Refs should rarely be used. When refs are used, they should only be done to
9041 * control data that is not handled by React's data flow.
9042 *
9043 * @class ReactOwner
9044 */
9045var ReactOwner = {
9046
9047 /**
9048 * @param {?object} object
9049 * @return {boolean} True if `object` is a valid owner.
9050 * @final
9051 */
9052 isValidOwner: function(object) {
9053 return !!(
9054 object &&
9055 typeof object.attachRef === 'function' &&
9056 typeof object.detachRef === 'function'
9057 );
9058 },
9059
9060 /**
9061 * Adds a component by ref to an owner component.
9062 *
9063 * @param {ReactComponent} component Component to reference.
9064 * @param {string} ref Name by which to refer to the component.
9065 * @param {ReactOwner} owner Component on which to record the ref.
9066 * @final
9067 * @internal
9068 */
9069 addComponentAsRefTo: function(component, ref, owner) {
9070 invariant(
9071 ReactOwner.isValidOwner(owner),
9072 'addComponentAsRefTo(...): Only a ReactOwner can have refs.'
9073 );
9074 owner.attachRef(ref, component);
9075 },
9076
9077 /**
9078 * Removes a component by ref from an owner component.
9079 *
9080 * @param {ReactComponent} component Component to dereference.
9081 * @param {string} ref Name of the ref to remove.
9082 * @param {ReactOwner} owner Component on which the ref is recorded.
9083 * @final
9084 * @internal
9085 */
9086 removeComponentAsRefFrom: function(component, ref, owner) {
9087 invariant(
9088 ReactOwner.isValidOwner(owner),
9089 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs.'
9090 );
9091 // Check that `component` is still the current ref because we do not want to
9092 // detach the ref if another component stole it.
9093 if (owner.refs[ref] === component) {
9094 owner.detachRef(ref);
9095 }
9096 },
9097
9098 /**
9099 * A ReactComponent must mix this in to have refs.
9100 *
9101 * @lends {ReactOwner.prototype}
9102 */
9103 Mixin: {
9104
9105 /**
9106 * Lazily allocates the refs object and stores `component` as `ref`.
9107 *
9108 * @param {string} ref Reference name.
9109 * @param {component} component Component to store as `ref`.
9110 * @final
9111 * @private
9112 */
9113 attachRef: function(ref, component) {
9114 invariant(
9115 component.isOwnedBy(this),
9116 'attachRef(%s, ...): Only a component\'s owner can store a ref to it.',
9117 ref
9118 );
9119 var refs = this.refs || (this.refs = {});
9120 refs[ref] = component;
9121 },
9122
9123 /**
9124 * Detaches a reference name.
9125 *
9126 * @param {string} ref Name to dereference.
9127 * @final
9128 * @private
9129 */
9130 detachRef: function(ref) {
9131 delete this.refs[ref];
9132 }
9133
9134 }
9135
9136};
9137
9138module.exports = ReactOwner;
9139
9140},{"./invariant":89}],51:[function(require,module,exports){
9141/**
9142 * Copyright 2013 Facebook, Inc.
9143 *
9144 * Licensed under the Apache License, Version 2.0 (the "License");
9145 * you may not use this file except in compliance with the License.
9146 * You may obtain a copy of the License at
9147 *
9148 * http://www.apache.org/licenses/LICENSE-2.0
9149 *
9150 * Unless required by applicable law or agreed to in writing, software
9151 * distributed under the License is distributed on an "AS IS" BASIS,
9152 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9153 * See the License for the specific language governing permissions and
9154 * limitations under the License.
9155 *
9156 * @providesModule ReactPerf
9157 * @typechecks static-only
9158 */
9159
9160"use strict";
9161
9162var ReactPerf = {
9163 /**
9164 * Boolean to enable/disable measurement. Set to false by default to prevent
9165 * accidental logging and perf loss.
9166 */
9167 enableMeasure: false,
9168
9169 /**
9170 * Holds onto the measure function in use. By default, don't measure
9171 * anything, but we'll override this if we inject a measure function.
9172 */
9173 storedMeasure: _noMeasure,
9174
9175 /**
9176 * Use this to wrap methods you want to measure.
9177 *
9178 * @param {string} objName
9179 * @param {string} fnName
9180 * @param {function} func
9181 * @return {function}
9182 */
9183 measure: function(objName, fnName, func) {
9184 if (true) {
9185 if (this.enableMeasure) {
9186 var measuredFunc = null;
9187 return function() {
9188 if (!measuredFunc) {
9189 measuredFunc = ReactPerf.storedMeasure(objName, fnName, func);
9190 }
9191 return measuredFunc.apply(this, arguments);
9192 };
9193 }
9194 }
9195 return func;
9196 },
9197
9198 injection: {
9199 /**
9200 * @param {function} measure
9201 */
9202 injectMeasure: function(measure) {
9203 ReactPerf.storedMeasure = measure;
9204 }
9205 }
9206};
9207
9208if (true) {
9209 var ExecutionEnvironment = require("./ExecutionEnvironment");
9210 var URL = ExecutionEnvironment.canUseDOM ? window.location.href : '';
9211 ReactPerf.enableMeasure = ReactPerf.enableMeasure ||
9212 !!URL.match(/[?&]react_perf\b/);
9213}
9214
9215/**
9216 * Simply passes through the measured function, without measuring it.
9217 *
9218 * @param {string} objName
9219 * @param {string} fnName
9220 * @param {function} func
9221 * @return {function}
9222 */
9223function _noMeasure(objName, fnName, func) {
9224 return func;
9225}
9226
9227module.exports = ReactPerf;
9228
9229},{"./ExecutionEnvironment":19}],52:[function(require,module,exports){
9230/**
9231 * Copyright 2013 Facebook, Inc.
9232 *
9233 * Licensed under the Apache License, Version 2.0 (the "License");
9234 * you may not use this file except in compliance with the License.
9235 * You may obtain a copy of the License at
9236 *
9237 * http://www.apache.org/licenses/LICENSE-2.0
9238 *
9239 * Unless required by applicable law or agreed to in writing, software
9240 * distributed under the License is distributed on an "AS IS" BASIS,
9241 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9242 * See the License for the specific language governing permissions and
9243 * limitations under the License.
9244 *
9245 * @providesModule ReactPropTransferer
9246 */
9247
9248"use strict";
9249
9250var emptyFunction = require("./emptyFunction");
9251var joinClasses = require("./joinClasses");
9252var merge = require("./merge");
9253
9254/**
9255 * Creates a transfer strategy that will merge prop values using the supplied
9256 * `mergeStrategy`. If a prop was previously unset, this just sets it.
9257 *
9258 * @param {function} mergeStrategy
9259 * @return {function}
9260 */
9261function createTransferStrategy(mergeStrategy) {
9262 return function(props, key, value) {
9263 if (!props.hasOwnProperty(key)) {
9264 props[key] = value;
9265 } else {
9266 props[key] = mergeStrategy(props[key], value);
9267 }
9268 };
9269}
9270
9271/**
9272 * Transfer strategies dictate how props are transferred by `transferPropsTo`.
9273 */
9274var TransferStrategies = {
9275 /**
9276 * Never transfer `children`.
9277 */
9278 children: emptyFunction,
9279 /**
9280 * Transfer the `className` prop by merging them.
9281 */
9282 className: createTransferStrategy(joinClasses),
9283 /**
9284 * Never transfer the `ref` prop.
9285 */
9286 ref: emptyFunction,
9287 /**
9288 * Transfer the `style` prop (which is an object) by merging them.
9289 */
9290 style: createTransferStrategy(merge)
9291};
9292
9293/**
9294 * ReactPropTransferer are capable of transferring props to another component
9295 * using a `transferPropsTo` method.
9296 *
9297 * @class ReactPropTransferer
9298 */
9299var ReactPropTransferer = {
9300
9301 TransferStrategies: TransferStrategies,
9302
9303 /**
9304 * @lends {ReactPropTransferer.prototype}
9305 */
9306 Mixin: {
9307
9308 /**
9309 * Transfer props from this component to a target component.
9310 *
9311 * Props that do not have an explicit transfer strategy will be transferred
9312 * only if the target component does not already have the prop set.
9313 *
9314 * This is usually used to pass down props to a returned root component.
9315 *
9316 * @param {ReactComponent} component Component receiving the properties.
9317 * @return {ReactComponent} The supplied `component`.
9318 * @final
9319 * @protected
9320 */
9321 transferPropsTo: function(component) {
9322 var props = {};
9323 for (var thatKey in component.props) {
9324 if (component.props.hasOwnProperty(thatKey)) {
9325 props[thatKey] = component.props[thatKey];
9326 }
9327 }
9328 for (var thisKey in this.props) {
9329 if (!this.props.hasOwnProperty(thisKey)) {
9330 continue;
9331 }
9332 var transferStrategy = TransferStrategies[thisKey];
9333 if (transferStrategy) {
9334 transferStrategy(props, thisKey, this.props[thisKey]);
9335 } else if (!props.hasOwnProperty(thisKey)) {
9336 props[thisKey] = this.props[thisKey];
9337 }
9338 }
9339 component.props = props;
9340 return component;
9341 }
9342
9343 }
9344
9345};
9346
9347module.exports = ReactPropTransferer;
9348
9349},{"./emptyFunction":77,"./joinClasses":91,"./merge":95}],53:[function(require,module,exports){
9350/**
9351 * Copyright 2013 Facebook, Inc.
9352 *
9353 * Licensed under the Apache License, Version 2.0 (the "License");
9354 * you may not use this file except in compliance with the License.
9355 * You may obtain a copy of the License at
9356 *
9357 * http://www.apache.org/licenses/LICENSE-2.0
9358 *
9359 * Unless required by applicable law or agreed to in writing, software
9360 * distributed under the License is distributed on an "AS IS" BASIS,
9361 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9362 * See the License for the specific language governing permissions and
9363 * limitations under the License.
9364 *
9365 * @providesModule ReactPropTypes
9366 */
9367
9368"use strict";
9369
9370var createObjectFrom = require("./createObjectFrom");
9371var invariant = require("./invariant");
9372
9373/**
9374 * Collection of methods that allow declaration and validation of props that are
9375 * supplied to React components. Example usage:
9376 *
9377 * var Props = require('ReactPropTypes');
9378 * var MyArticle = React.createClass({
9379 * propTypes: {
9380 * // An optional string prop named "description".
9381 * description: Props.string,
9382 *
9383 * // A required enum prop named "category".
9384 * category: Props.oneOf(['News','Photos']).isRequired,
9385 *
9386 * // A prop named "dialog" that requires an instance of Dialog.
9387 * dialog: Props.instanceOf(Dialog).isRequired
9388 * },
9389 * render: function() { ... }
9390 * });
9391 *
9392 * A more formal specification of how these methods are used:
9393 *
9394 * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
9395 * decl := ReactPropTypes.{type}(.isRequired)?
9396 *
9397 * Each and every declaration produces a function with the same signature. This
9398 * allows the creation of custom validation functions. For example:
9399 *
9400 * var Props = require('ReactPropTypes');
9401 * var MyLink = React.createClass({
9402 * propTypes: {
9403 * // An optional string or URI prop named "href".
9404 * href: function(props, propName, componentName) {
9405 * var propValue = props[propName];
9406 * invariant(
9407 * propValue == null ||
9408 * typeof propValue === 'string' ||
9409 * propValue instanceof URI,
9410 * 'Invalid `%s` supplied to `%s`, expected string or URI.',
9411 * propName,
9412 * componentName
9413 * );
9414 * }
9415 * },
9416 * render: function() { ... }
9417 * });
9418 *
9419 * @internal
9420 */
9421var Props = {
9422
9423 array: createPrimitiveTypeChecker('array'),
9424 bool: createPrimitiveTypeChecker('boolean'),
9425 func: createPrimitiveTypeChecker('function'),
9426 number: createPrimitiveTypeChecker('number'),
9427 object: createPrimitiveTypeChecker('object'),
9428 string: createPrimitiveTypeChecker('string'),
9429
9430 oneOf: createEnumTypeChecker,
9431
9432 instanceOf: createInstanceTypeChecker
9433
9434};
9435
9436var ANONYMOUS = '<<anonymous>>';
9437
9438function createPrimitiveTypeChecker(expectedType) {
9439 function validatePrimitiveType(propValue, propName, componentName) {
9440 var propType = typeof propValue;
9441 if (propType === 'object' && Array.isArray(propValue)) {
9442 propType = 'array';
9443 }
9444 invariant(
9445 propType === expectedType,
9446 'Invalid prop `%s` of type `%s` supplied to `%s`, expected `%s`.',
9447 propName,
9448 propType,
9449 componentName,
9450 expectedType
9451 );
9452 }
9453 return createChainableTypeChecker(validatePrimitiveType);
9454}
9455
9456function createEnumTypeChecker(expectedValues) {
9457 var expectedEnum = createObjectFrom(expectedValues);
9458 function validateEnumType(propValue, propName, componentName) {
9459 invariant(
9460 expectedEnum[propValue],
9461 'Invalid prop `%s` supplied to `%s`, expected one of %s.',
9462 propName,
9463 componentName,
9464 JSON.stringify(Object.keys(expectedEnum))
9465 );
9466 }
9467 return createChainableTypeChecker(validateEnumType);
9468}
9469
9470function createInstanceTypeChecker(expectedClass) {
9471 function validateInstanceType(propValue, propName, componentName) {
9472 invariant(
9473 propValue instanceof expectedClass,
9474 'Invalid prop `%s` supplied to `%s`, expected instance of `%s`.',
9475 propName,
9476 componentName,
9477 expectedClass.name || ANONYMOUS
9478 );
9479 }
9480 return createChainableTypeChecker(validateInstanceType);
9481}
9482
9483function createChainableTypeChecker(validate) {
9484 function createTypeChecker(isRequired) {
9485 function checkType(props, propName, componentName) {
9486 var propValue = props[propName];
9487 if (propValue != null) {
9488 // Only validate if there is a value to check.
9489 validate(propValue, propName, componentName || ANONYMOUS);
9490 } else {
9491 invariant(
9492 !isRequired,
9493 'Required prop `%s` was not specified in `%s`.',
9494 propName,
9495 componentName || ANONYMOUS
9496 );
9497 }
9498 }
9499 if (!isRequired) {
9500 checkType.isRequired = createTypeChecker(true);
9501 }
9502 return checkType;
9503 }
9504 return createTypeChecker(false);
9505}
9506
9507module.exports = Props;
9508
9509},{"./createObjectFrom":75,"./invariant":89}],54:[function(require,module,exports){
9510/**
9511 * Copyright 2013 Facebook, Inc.
9512 *
9513 * Licensed under the Apache License, Version 2.0 (the "License");
9514 * you may not use this file except in compliance with the License.
9515 * You may obtain a copy of the License at
9516 *
9517 * http://www.apache.org/licenses/LICENSE-2.0
9518 *
9519 * Unless required by applicable law or agreed to in writing, software
9520 * distributed under the License is distributed on an "AS IS" BASIS,
9521 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9522 * See the License for the specific language governing permissions and
9523 * limitations under the License.
9524 *
9525 * @providesModule ReactReconcileTransaction
9526 * @typechecks static-only
9527 */
9528
9529"use strict";
9530
9531var ExecutionEnvironment = require("./ExecutionEnvironment");
9532var PooledClass = require("./PooledClass");
9533var ReactEventEmitter = require("./ReactEventEmitter");
9534var ReactInputSelection = require("./ReactInputSelection");
9535var ReactOnDOMReady = require("./ReactOnDOMReady");
9536var Transaction = require("./Transaction");
9537
9538var mixInto = require("./mixInto");
9539
9540/**
9541 * Ensures that, when possible, the selection range (currently selected text
9542 * input) is not disturbed by performing the transaction.
9543 */
9544var SELECTION_RESTORATION = {
9545 /**
9546 * @return {Selection} Selection information.
9547 */
9548 initialize: ReactInputSelection.getSelectionInformation,
9549 /**
9550 * @param {Selection} sel Selection information returned from `initialize`.
9551 */
9552 close: ReactInputSelection.restoreSelection
9553};
9554
9555/**
9556 * Suppresses events (blur/focus) that could be inadvertently dispatched due to
9557 * high level DOM manipulations (like temporarily removing a text input from the
9558 * DOM).
9559 */
9560var EVENT_SUPPRESSION = {
9561 /**
9562 * @return {boolean} The enabled status of `ReactEventEmitter` before the
9563 * reconciliation.
9564 */
9565 initialize: function() {
9566 var currentlyEnabled = ReactEventEmitter.isEnabled();
9567 ReactEventEmitter.setEnabled(false);
9568 return currentlyEnabled;
9569 },
9570
9571 /**
9572 * @param {boolean} previouslyEnabled Enabled status of `ReactEventEmitter`
9573 * before the reconciliation occured. `close` restores the previous value.
9574 */
9575 close: function(previouslyEnabled) {
9576 ReactEventEmitter.setEnabled(previouslyEnabled);
9577 }
9578};
9579
9580/**
9581 * Provides a `ReactOnDOMReady` queue for collecting `onDOMReady` callbacks
9582 * during the performing of the transaction.
9583 */
9584var ON_DOM_READY_QUEUEING = {
9585 /**
9586 * Initializes the internal `onDOMReady` queue.
9587 */
9588 initialize: function() {
9589 this.reactOnDOMReady.reset();
9590 },
9591
9592 /**
9593 * After DOM is flushed, invoke all registered `onDOMReady` callbacks.
9594 */
9595 close: function() {
9596 this.reactOnDOMReady.notifyAll();
9597 }
9598};
9599
9600/**
9601 * Executed within the scope of the `Transaction` instance. Consider these as
9602 * being member methods, but with an implied ordering while being isolated from
9603 * each other.
9604 */
9605var TRANSACTION_WRAPPERS = [
9606 SELECTION_RESTORATION,
9607 EVENT_SUPPRESSION,
9608 ON_DOM_READY_QUEUEING
9609];
9610
9611/**
9612 * Currently:
9613 * - The order that these are listed in the transaction is critical:
9614 * - Suppresses events.
9615 * - Restores selection range.
9616 *
9617 * Future:
9618 * - Restore document/overflow scroll positions that were unintentionally
9619 * modified via DOM insertions above the top viewport boundary.
9620 * - Implement/integrate with customized constraint based layout system and keep
9621 * track of which dimensions must be remeasured.
9622 *
9623 * @class ReactReconcileTransaction
9624 */
9625function ReactReconcileTransaction() {
9626 this.reinitializeTransaction();
9627 this.reactOnDOMReady = ReactOnDOMReady.getPooled(null);
9628}
9629
9630var Mixin = {
9631 /**
9632 * @see Transaction
9633 * @abstract
9634 * @final
9635 * @return {array<object>} List of operation wrap proceedures.
9636 * TODO: convert to array<TransactionWrapper>
9637 */
9638 getTransactionWrappers: function() {
9639 if (ExecutionEnvironment.canUseDOM) {
9640 return TRANSACTION_WRAPPERS;
9641 } else {
9642 return [];
9643 }
9644 },
9645
9646 /**
9647 * @return {object} The queue to collect `onDOMReady` callbacks with.
9648 * TODO: convert to ReactOnDOMReady
9649 */
9650 getReactOnDOMReady: function() {
9651 return this.reactOnDOMReady;
9652 },
9653
9654 /**
9655 * `PooledClass` looks for this, and will invoke this before allowing this
9656 * instance to be resused.
9657 */
9658 destructor: function() {
9659 ReactOnDOMReady.release(this.reactOnDOMReady);
9660 this.reactOnDOMReady = null;
9661 }
9662};
9663
9664
9665mixInto(ReactReconcileTransaction, Transaction.Mixin);
9666mixInto(ReactReconcileTransaction, Mixin);
9667
9668PooledClass.addPoolingTo(ReactReconcileTransaction);
9669
9670module.exports = ReactReconcileTransaction;
9671
9672},{"./ExecutionEnvironment":19,"./PooledClass":21,"./ReactEventEmitter":39,"./ReactInputSelection":42,"./ReactOnDOMReady":49,"./Transaction":68,"./mixInto":98}],55:[function(require,module,exports){
9673/**
9674 * Copyright 2013 Facebook, Inc.
9675 *
9676 * Licensed under the Apache License, Version 2.0 (the "License");
9677 * you may not use this file except in compliance with the License.
9678 * You may obtain a copy of the License at
9679 *
9680 * http://www.apache.org/licenses/LICENSE-2.0
9681 *
9682 * Unless required by applicable law or agreed to in writing, software
9683 * distributed under the License is distributed on an "AS IS" BASIS,
9684 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9685 * See the License for the specific language governing permissions and
9686 * limitations under the License.
9687 *
9688 * @typechecks static-only
9689 * @providesModule ReactServerRendering
9690 */
9691"use strict";
9692
9693var ReactMarkupChecksum = require("./ReactMarkupChecksum");
9694var ReactReconcileTransaction = require("./ReactReconcileTransaction");
9695var ReactInstanceHandles = require("./ReactInstanceHandles");
9696
9697/**
9698 * @param {object} component
9699 * @param {function} callback
9700 */
9701function renderComponentToString(component, callback) {
9702 // We use a callback API to keep the API async in case in the future we ever
9703 // need it, but in reality this is a synchronous operation.
9704 var id = ReactInstanceHandles.createReactRootID();
9705 var transaction = ReactReconcileTransaction.getPooled();
9706 transaction.reinitializeTransaction();
9707 try {
9708 transaction.perform(function() {
9709 var markup = component.mountComponent(id, transaction);
9710 markup = ReactMarkupChecksum.addChecksumToMarkup(markup);
9711 callback(markup);
9712 }, null);
9713 } finally {
9714 ReactReconcileTransaction.release(transaction);
9715 }
9716}
9717
9718module.exports = {
9719 renderComponentToString: renderComponentToString
9720};
9721
9722},{"./ReactInstanceHandles":43,"./ReactMarkupChecksum":44,"./ReactReconcileTransaction":54}],56:[function(require,module,exports){
9723/**
9724 * Copyright 2013 Facebook, Inc.
9725 *
9726 * Licensed under the Apache License, Version 2.0 (the "License");
9727 * you may not use this file except in compliance with the License.
9728 * You may obtain a copy of the License at
9729 *
9730 * http://www.apache.org/licenses/LICENSE-2.0
9731 *
9732 * Unless required by applicable law or agreed to in writing, software
9733 * distributed under the License is distributed on an "AS IS" BASIS,
9734 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9735 * See the License for the specific language governing permissions and
9736 * limitations under the License.
9737 *
9738 * @providesModule ReactTextComponent
9739 * @typechecks static-only
9740 */
9741
9742"use strict";
9743
9744var ReactComponent = require("./ReactComponent");
9745var ReactMount = require("./ReactMount");
9746
9747var escapeTextForBrowser = require("./escapeTextForBrowser");
9748var mixInto = require("./mixInto");
9749
9750/**
9751 * Text nodes violate a couple assumptions that React makes about components:
9752 *
9753 * - When mounting text into the DOM, adjacent text nodes are merged.
9754 * - Text nodes cannot be assigned a React root ID.
9755 *
9756 * This component is used to wrap strings in elements so that they can undergo
9757 * the same reconciliation that is applied to elements.
9758 *
9759 * TODO: Investigate representing React components in the DOM with text nodes.
9760 *
9761 * @class ReactTextComponent
9762 * @extends ReactComponent
9763 * @internal
9764 */
9765var ReactTextComponent = function(initialText) {
9766 this.construct({text: initialText});
9767};
9768
9769mixInto(ReactTextComponent, ReactComponent.Mixin);
9770mixInto(ReactTextComponent, {
9771
9772 /**
9773 * Creates the markup for this text node. This node is not intended to have
9774 * any features besides containing text content.
9775 *
9776 * @param {string} rootID DOM ID of the root node.
9777 * @return {string} Markup for this text node.
9778 * @internal
9779 */
9780 mountComponent: function(rootID) {
9781 ReactComponent.Mixin.mountComponent.call(this, rootID);
9782 return (
9783 '<span ' + ReactMount.ATTR_NAME + '="' + rootID + '">' +
9784 escapeTextForBrowser(this.props.text) +
9785 '</span>'
9786 );
9787 },
9788
9789 /**
9790 * Updates this component by updating the text content.
9791 *
9792 * @param {object} nextProps Contains the next text content.
9793 * @param {ReactReconcileTransaction} transaction
9794 * @internal
9795 */
9796 receiveProps: function(nextProps, transaction) {
9797 if (nextProps.text !== this.props.text) {
9798 this.props.text = nextProps.text;
9799 ReactComponent.DOMIDOperations.updateTextContentByID(
9800 this._rootNodeID,
9801 nextProps.text
9802 );
9803 }
9804 }
9805
9806});
9807
9808module.exports = ReactTextComponent;
9809
9810},{"./ReactComponent":23,"./ReactMount":45,"./escapeTextForBrowser":78,"./mixInto":98}],57:[function(require,module,exports){
9811/**
9812 * Copyright 2013 Facebook, Inc.
9813 *
9814 * Licensed under the Apache License, Version 2.0 (the "License");
9815 * you may not use this file except in compliance with the License.
9816 * You may obtain a copy of the License at
9817 *
9818 * http://www.apache.org/licenses/LICENSE-2.0
9819 *
9820 * Unless required by applicable law or agreed to in writing, software
9821 * distributed under the License is distributed on an "AS IS" BASIS,
9822 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9823 * See the License for the specific language governing permissions and
9824 * limitations under the License.
9825 *
9826 * @providesModule ReactUpdates
9827 */
9828
9829"use strict";
9830
9831var invariant = require("./invariant");
9832
9833var dirtyComponents = [];
9834
9835var batchingStrategy = null;
9836
9837function ensureBatchingStrategy() {
9838 invariant(batchingStrategy, 'ReactUpdates: must inject a batching strategy');
9839}
9840
9841function batchedUpdates(callback, param) {
9842 ensureBatchingStrategy();
9843 batchingStrategy.batchedUpdates(callback, param);
9844}
9845
9846function runBatchedUpdates() {
9847 // TODO: Sort components by depth such that parent components update first
9848 for (var i = 0; i < dirtyComponents.length; i++) {
9849 // If a component is unmounted before pending changes apply, ignore them
9850 // TODO: Queue unmounts in the same list to avoid this happening at all
9851 var component = dirtyComponents[i];
9852 if (component.isMounted()) {
9853 // If performUpdateIfNecessary happens to enqueue any new updates, we
9854 // shouldn't execute the callbacks until the next render happens, so
9855 // stash the callbacks first
9856 var callbacks = component._pendingCallbacks;
9857 component._pendingCallbacks = null;
9858 component.performUpdateIfNecessary();
9859 if (callbacks) {
9860 for (var j = 0; j < callbacks.length; j++) {
9861 callbacks[j].call(component);
9862 }
9863 }
9864 }
9865 }
9866}
9867
9868function clearDirtyComponents() {
9869 dirtyComponents.length = 0;
9870}
9871
9872function flushBatchedUpdates() {
9873 // Run these in separate functions so the JIT can optimize
9874 try {
9875 runBatchedUpdates();
9876 } catch (e) {
9877 // IE 8 requires catch to use finally.
9878 throw e;
9879 } finally {
9880 clearDirtyComponents();
9881 }
9882}
9883
9884/**
9885 * Mark a component as needing a rerender, adding an optional callback to a
9886 * list of functions which will be executed once the rerender occurs.
9887 */
9888function enqueueUpdate(component, callback) {
9889 invariant(
9890 !callback || typeof callback === "function",
9891 'enqueueUpdate(...): You called `setProps`, `replaceProps`, ' +
9892 '`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
9893 'isn\'t callable.'
9894 );
9895 ensureBatchingStrategy();
9896
9897 if (!batchingStrategy.isBatchingUpdates) {
9898 component.performUpdateIfNecessary();
9899 callback && callback();
9900 return;
9901 }
9902
9903 dirtyComponents.push(component);
9904
9905 if (callback) {
9906 if (component._pendingCallbacks) {
9907 component._pendingCallbacks.push(callback);
9908 } else {
9909 component._pendingCallbacks = [callback];
9910 }
9911 }
9912}
9913
9914var ReactUpdatesInjection = {
9915 injectBatchingStrategy: function(_batchingStrategy) {
9916 invariant(
9917 _batchingStrategy,
9918 'ReactUpdates: must provide a batching strategy'
9919 );
9920 invariant(
9921 typeof _batchingStrategy.batchedUpdates === 'function',
9922 'ReactUpdates: must provide a batchedUpdates() function'
9923 );
9924 invariant(
9925 typeof _batchingStrategy.isBatchingUpdates === 'boolean',
9926 'ReactUpdates: must provide an isBatchingUpdates boolean attribute'
9927 );
9928 batchingStrategy = _batchingStrategy;
9929 }
9930};
9931
9932var ReactUpdates = {
9933 batchedUpdates: batchedUpdates,
9934 enqueueUpdate: enqueueUpdate,
9935 flushBatchedUpdates: flushBatchedUpdates,
9936 injection: ReactUpdatesInjection
9937};
9938
9939module.exports = ReactUpdates;
9940
9941},{"./invariant":89}],58:[function(require,module,exports){
9942/**
9943 * Copyright 2013 Facebook, Inc.
9944 *
9945 * Licensed under the Apache License, Version 2.0 (the "License");
9946 * you may not use this file except in compliance with the License.
9947 * You may obtain a copy of the License at
9948 *
9949 * http://www.apache.org/licenses/LICENSE-2.0
9950 *
9951 * Unless required by applicable law or agreed to in writing, software
9952 * distributed under the License is distributed on an "AS IS" BASIS,
9953 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9954 * See the License for the specific language governing permissions and
9955 * limitations under the License.
9956 *
9957 * @providesModule SimpleEventPlugin
9958 */
9959
9960"use strict";
9961
9962var EventConstants = require("./EventConstants");
9963var EventPropagators = require("./EventPropagators");
9964var SyntheticClipboardEvent = require("./SyntheticClipboardEvent");
9965var SyntheticEvent = require("./SyntheticEvent");
9966var SyntheticFocusEvent = require("./SyntheticFocusEvent");
9967var SyntheticKeyboardEvent = require("./SyntheticKeyboardEvent");
9968var SyntheticMouseEvent = require("./SyntheticMouseEvent");
9969var SyntheticMutationEvent = require("./SyntheticMutationEvent");
9970var SyntheticTouchEvent = require("./SyntheticTouchEvent");
9971var SyntheticUIEvent = require("./SyntheticUIEvent");
9972var SyntheticWheelEvent = require("./SyntheticWheelEvent");
9973
9974var invariant = require("./invariant");
9975var keyOf = require("./keyOf");
9976
9977var topLevelTypes = EventConstants.topLevelTypes;
9978
9979var eventTypes = {
9980 blur: {
9981 phasedRegistrationNames: {
9982 bubbled: keyOf({onBlur: true}),
9983 captured: keyOf({onBlurCapture: true})
9984 }
9985 },
9986 click: {
9987 phasedRegistrationNames: {
9988 bubbled: keyOf({onClick: true}),
9989 captured: keyOf({onClickCapture: true})
9990 }
9991 },
9992 copy: {
9993 phasedRegistrationNames: {
9994 bubbled: keyOf({onCopy: true}),
9995 captured: keyOf({onCopyCapture: true})
9996 }
9997 },
9998 cut: {
9999 phasedRegistrationNames: {
10000 bubbled: keyOf({onCut: true}),
10001 captured: keyOf({onCutCapture: true})
10002 }
10003 },
10004 doubleClick: {
10005 phasedRegistrationNames: {
10006 bubbled: keyOf({onDoubleClick: true}),
10007 captured: keyOf({onDoubleClickCapture: true})
10008 }
10009 },
10010 drag: {
10011 phasedRegistrationNames: {
10012 bubbled: keyOf({onDrag: true}),
10013 captured: keyOf({onDragCapture: true})
10014 }
10015 },
10016 dragEnd: {
10017 phasedRegistrationNames: {
10018 bubbled: keyOf({onDragEnd: true}),
10019 captured: keyOf({onDragEndCapture: true})
10020 }
10021 },
10022 dragEnter: {
10023 phasedRegistrationNames: {
10024 bubbled: keyOf({onDragEnter: true}),
10025 captured: keyOf({onDragEnterCapture: true})
10026 }
10027 },
10028 dragExit: {
10029 phasedRegistrationNames: {
10030 bubbled: keyOf({onDragExit: true}),
10031 captured: keyOf({onDragExitCapture: true})
10032 }
10033 },
10034 dragLeave: {
10035 phasedRegistrationNames: {
10036 bubbled: keyOf({onDragLeave: true}),
10037 captured: keyOf({onDragLeaveCapture: true})
10038 }
10039 },
10040 dragOver: {
10041 phasedRegistrationNames: {
10042 bubbled: keyOf({onDragOver: true}),
10043 captured: keyOf({onDragOverCapture: true})
10044 }
10045 },
10046 dragStart: {
10047 phasedRegistrationNames: {
10048 bubbled: keyOf({onDragStart: true}),
10049 captured: keyOf({onDragStartCapture: true})
10050 }
10051 },
10052 drop: {
10053 phasedRegistrationNames: {
10054 bubbled: keyOf({onDrop: true}),
10055 captured: keyOf({onDropCapture: true})
10056 }
10057 },
10058 DOMCharacterDataModified: {
10059 phasedRegistrationNames: {
10060 bubbled: keyOf({onDOMCharacterDataModified: true}),
10061 captured: keyOf({onDOMCharacterDataModifiedCapture: true})
10062 }
10063 },
10064 focus: {
10065 phasedRegistrationNames: {
10066 bubbled: keyOf({onFocus: true}),
10067 captured: keyOf({onFocusCapture: true})
10068 }
10069 },
10070 input: {
10071 phasedRegistrationNames: {
10072 bubbled: keyOf({onInput: true}),
10073 captured: keyOf({onInputCapture: true})
10074 }
10075 },
10076 keyDown: {
10077 phasedRegistrationNames: {
10078 bubbled: keyOf({onKeyDown: true}),
10079 captured: keyOf({onKeyDownCapture: true})
10080 }
10081 },
10082 keyPress: {
10083 phasedRegistrationNames: {
10084 bubbled: keyOf({onKeyPress: true}),
10085 captured: keyOf({onKeyPressCapture: true})
10086 }
10087 },
10088 keyUp: {
10089 phasedRegistrationNames: {
10090 bubbled: keyOf({onKeyUp: true}),
10091 captured: keyOf({onKeyUpCapture: true})
10092 }
10093 },
10094 // Note: We do not allow listening to mouseOver events. Instead, use the
10095 // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`.
10096 mouseDown: {
10097 phasedRegistrationNames: {
10098 bubbled: keyOf({onMouseDown: true}),
10099 captured: keyOf({onMouseDownCapture: true})
10100 }
10101 },
10102 mouseMove: {
10103 phasedRegistrationNames: {
10104 bubbled: keyOf({onMouseMove: true}),
10105 captured: keyOf({onMouseMoveCapture: true})
10106 }
10107 },
10108 mouseUp: {
10109 phasedRegistrationNames: {
10110 bubbled: keyOf({onMouseUp: true}),
10111 captured: keyOf({onMouseUpCapture: true})
10112 }
10113 },
10114 paste: {
10115 phasedRegistrationNames: {
10116 bubbled: keyOf({onPaste: true}),
10117 captured: keyOf({onPasteCapture: true})
10118 }
10119 },
10120 scroll: {
10121 phasedRegistrationNames: {
10122 bubbled: keyOf({onScroll: true}),
10123 captured: keyOf({onScrollCapture: true})
10124 }
10125 },
10126 submit: {
10127 phasedRegistrationNames: {
10128 bubbled: keyOf({onSubmit: true}),
10129 captured: keyOf({onSubmitCapture: true})
10130 }
10131 },
10132 touchCancel: {
10133 phasedRegistrationNames: {
10134 bubbled: keyOf({onTouchCancel: true}),
10135 captured: keyOf({onTouchCancelCapture: true})
10136 }
10137 },
10138 touchEnd: {
10139 phasedRegistrationNames: {
10140 bubbled: keyOf({onTouchEnd: true}),
10141 captured: keyOf({onTouchEndCapture: true})
10142 }
10143 },
10144 touchMove: {
10145 phasedRegistrationNames: {
10146 bubbled: keyOf({onTouchMove: true}),
10147 captured: keyOf({onTouchMoveCapture: true})
10148 }
10149 },
10150 touchStart: {
10151 phasedRegistrationNames: {
10152 bubbled: keyOf({onTouchStart: true}),
10153 captured: keyOf({onTouchStartCapture: true})
10154 }
10155 },
10156 wheel: {
10157 phasedRegistrationNames: {
10158 bubbled: keyOf({onWheel: true}),
10159 captured: keyOf({onWheelCapture: true})
10160 }
10161 }
10162};
10163
10164var topLevelEventsToDispatchConfig = {
10165 topBlur: eventTypes.blur,
10166 topClick: eventTypes.click,
10167 topCopy: eventTypes.copy,
10168 topCut: eventTypes.cut,
10169 topDoubleClick: eventTypes.doubleClick,
10170 topDOMCharacterDataModified: eventTypes.DOMCharacterDataModified,
10171 topDrag: eventTypes.drag,
10172 topDragEnd: eventTypes.dragEnd,
10173 topDragEnter: eventTypes.dragEnter,
10174 topDragExit: eventTypes.dragExit,
10175 topDragLeave: eventTypes.dragLeave,
10176 topDragOver: eventTypes.dragOver,
10177 topDragStart: eventTypes.dragStart,
10178 topDrop: eventTypes.drop,
10179 topFocus: eventTypes.focus,
10180 topInput: eventTypes.input,
10181 topKeyDown: eventTypes.keyDown,
10182 topKeyPress: eventTypes.keyPress,
10183 topKeyUp: eventTypes.keyUp,
10184 topMouseDown: eventTypes.mouseDown,
10185 topMouseMove: eventTypes.mouseMove,
10186 topMouseUp: eventTypes.mouseUp,
10187 topPaste: eventTypes.paste,
10188 topScroll: eventTypes.scroll,
10189 topSubmit: eventTypes.submit,
10190 topTouchCancel: eventTypes.touchCancel,
10191 topTouchEnd: eventTypes.touchEnd,
10192 topTouchMove: eventTypes.touchMove,
10193 topTouchStart: eventTypes.touchStart,
10194 topWheel: eventTypes.wheel
10195};
10196
10197var SimpleEventPlugin = {
10198
10199 eventTypes: eventTypes,
10200
10201 /**
10202 * Same as the default implementation, except cancels the event when return
10203 * value is false.
10204 *
10205 * @param {object} Event to be dispatched.
10206 * @param {function} Application-level callback.
10207 * @param {string} domID DOM ID to pass to the callback.
10208 */
10209 executeDispatch: function(event, listener, domID) {
10210 var returnValue = listener(event, domID);
10211 if (returnValue === false) {
10212 event.stopPropagation();
10213 event.preventDefault();
10214 }
10215 },
10216
10217 /**
10218 * @param {string} topLevelType Record from `EventConstants`.
10219 * @param {DOMEventTarget} topLevelTarget The listening component root node.
10220 * @param {string} topLevelTargetID ID of `topLevelTarget`.
10221 * @param {object} nativeEvent Native browser event.
10222 * @return {*} An accumulation of synthetic events.
10223 * @see {EventPluginHub.extractEvents}
10224 */
10225 extractEvents: function(
10226 topLevelType,
10227 topLevelTarget,
10228 topLevelTargetID,
10229 nativeEvent) {
10230 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
10231 if (!dispatchConfig) {
10232 return null;
10233 }
10234 var EventConstructor;
10235 switch(topLevelType) {
10236 case topLevelTypes.topInput:
10237 case topLevelTypes.topSubmit:
10238 // HTML Events
10239 // @see http://www.w3.org/TR/html5/index.html#events-0
10240 EventConstructor = SyntheticEvent;
10241 break;
10242 case topLevelTypes.topKeyDown:
10243 case topLevelTypes.topKeyPress:
10244 case topLevelTypes.topKeyUp:
10245 EventConstructor = SyntheticKeyboardEvent;
10246 break;
10247 case topLevelTypes.topBlur:
10248 case topLevelTypes.topFocus:
10249 EventConstructor = SyntheticFocusEvent;
10250 break;
10251 case topLevelTypes.topClick:
10252 case topLevelTypes.topDoubleClick:
10253 case topLevelTypes.topDrag:
10254 case topLevelTypes.topDragEnd:
10255 case topLevelTypes.topDragEnter:
10256 case topLevelTypes.topDragExit:
10257 case topLevelTypes.topDragLeave:
10258 case topLevelTypes.topDragOver:
10259 case topLevelTypes.topDragStart:
10260 case topLevelTypes.topDrop:
10261 case topLevelTypes.topMouseDown:
10262 case topLevelTypes.topMouseMove:
10263 case topLevelTypes.topMouseUp:
10264 EventConstructor = SyntheticMouseEvent;
10265 break;
10266 case topLevelTypes.topDOMCharacterDataModified:
10267 EventConstructor = SyntheticMutationEvent;
10268 break;
10269 case topLevelTypes.topTouchCancel:
10270 case topLevelTypes.topTouchEnd:
10271 case topLevelTypes.topTouchMove:
10272 case topLevelTypes.topTouchStart:
10273 EventConstructor = SyntheticTouchEvent;
10274 break;
10275 case topLevelTypes.topScroll:
10276 EventConstructor = SyntheticUIEvent;
10277 break;
10278 case topLevelTypes.topWheel:
10279 EventConstructor = SyntheticWheelEvent;
10280 break;
10281 case topLevelTypes.topCopy:
10282 case topLevelTypes.topCut:
10283 case topLevelTypes.topPaste:
10284 EventConstructor = SyntheticClipboardEvent;
10285 break;
10286 }
10287 invariant(
10288 EventConstructor,
10289 'SimpleEventPlugin: Unhandled event type, `%s`.',
10290 topLevelType
10291 );
10292 var event = EventConstructor.getPooled(
10293 dispatchConfig,
10294 topLevelTargetID,
10295 nativeEvent
10296 );
10297 EventPropagators.accumulateTwoPhaseDispatches(event);
10298 return event;
10299 }
10300
10301};
10302
10303module.exports = SimpleEventPlugin;
10304
10305},{"./EventConstants":13,"./EventPropagators":18,"./SyntheticClipboardEvent":59,"./SyntheticEvent":60,"./SyntheticFocusEvent":61,"./SyntheticKeyboardEvent":62,"./SyntheticMouseEvent":63,"./SyntheticMutationEvent":64,"./SyntheticTouchEvent":65,"./SyntheticUIEvent":66,"./SyntheticWheelEvent":67,"./invariant":89,"./keyOf":93}],59:[function(require,module,exports){
10306/**
10307 * Copyright 2013 Facebook, Inc.
10308 *
10309 * Licensed under the Apache License, Version 2.0 (the "License");
10310 * you may not use this file except in compliance with the License.
10311 * You may obtain a copy of the License at
10312 *
10313 * http://www.apache.org/licenses/LICENSE-2.0
10314 *
10315 * Unless required by applicable law or agreed to in writing, software
10316 * distributed under the License is distributed on an "AS IS" BASIS,
10317 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10318 * See the License for the specific language governing permissions and
10319 * limitations under the License.
10320 *
10321 * @providesModule SyntheticClipboardEvent
10322 * @typechecks static-only
10323 */
10324
10325"use strict";
10326
10327var SyntheticEvent = require("./SyntheticEvent");
10328
10329/**
10330 * @interface Event
10331 * @see http://www.w3.org/TR/clipboard-apis/
10332 */
10333var ClipboardEventInterface = {
10334 clipboardData: null
10335};
10336
10337/**
10338 * @param {object} dispatchConfig Configuration used to dispatch this event.
10339 * @param {string} dispatchMarker Marker identifying the event target.
10340 * @param {object} nativeEvent Native browser event.
10341 * @extends {SyntheticUIEvent}
10342 */
10343function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
10344 SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
10345}
10346
10347SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface);
10348
10349module.exports = SyntheticClipboardEvent;
10350
10351
10352},{"./SyntheticEvent":60}],60:[function(require,module,exports){
10353/**
10354 * Copyright 2013 Facebook, Inc.
10355 *
10356 * Licensed under the Apache License, Version 2.0 (the "License");
10357 * you may not use this file except in compliance with the License.
10358 * You may obtain a copy of the License at
10359 *
10360 * http://www.apache.org/licenses/LICENSE-2.0
10361 *
10362 * Unless required by applicable law or agreed to in writing, software
10363 * distributed under the License is distributed on an "AS IS" BASIS,
10364 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10365 * See the License for the specific language governing permissions and
10366 * limitations under the License.
10367 *
10368 * @providesModule SyntheticEvent
10369 * @typechecks static-only
10370 */
10371
10372"use strict";
10373
10374var PooledClass = require("./PooledClass");
10375
10376var emptyFunction = require("./emptyFunction");
10377var getEventTarget = require("./getEventTarget");
10378var merge = require("./merge");
10379var mergeInto = require("./mergeInto");
10380
10381/**
10382 * @interface Event
10383 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10384 */
10385var EventInterface = {
10386 type: null,
10387 target: getEventTarget,
10388 currentTarget: null,
10389 eventPhase: null,
10390 bubbles: null,
10391 cancelable: null,
10392 timeStamp: function(event) {
10393 return event.timeStamp || Date.now();
10394 },
10395 defaultPrevented: null,
10396 isTrusted: null
10397};
10398
10399/**
10400 * Synthetic events are dispatched by event plugins, typically in response to a
10401 * top-level event delegation handler.
10402 *
10403 * These systems should generally use pooling to reduce the frequency of garbage
10404 * collection. The system should check `isPersistent` to determine whether the
10405 * event should be released into the pool after being dispatched. Users that
10406 * need a persisted event should invoke `persist`.
10407 *
10408 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
10409 * normalizing browser quirks. Subclasses do not necessarily have to implement a
10410 * DOM interface; custom application-specific events can also subclass this.
10411 *
10412 * @param {object} dispatchConfig Configuration used to dispatch this event.
10413 * @param {string} dispatchMarker Marker identifying the event target.
10414 * @param {object} nativeEvent Native browser event.
10415 */
10416function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) {
10417 this.dispatchConfig = dispatchConfig;
10418 this.dispatchMarker = dispatchMarker;
10419 this.nativeEvent = nativeEvent;
10420
10421 var Interface = this.constructor.Interface;
10422 for (var propName in Interface) {
10423 if (!Interface.hasOwnProperty(propName)) {
10424 continue;
10425 }
10426 var normalize = Interface[propName];
10427 if (normalize) {
10428 this[propName] = normalize(nativeEvent);
10429 } else {
10430 this[propName] = nativeEvent[propName];
10431 }
10432 }
10433
10434 if (nativeEvent.defaultPrevented || nativeEvent.returnValue === false) {
10435 this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
10436 } else {
10437 this.isDefaultPrevented = emptyFunction.thatReturnsFalse;
10438 }
10439 this.isPropagationStopped = emptyFunction.thatReturnsFalse;
10440}
10441
10442mergeInto(SyntheticEvent.prototype, {
10443
10444 preventDefault: function() {
10445 this.defaultPrevented = true;
10446 var event = this.nativeEvent;
10447 event.preventDefault ? event.preventDefault() : event.returnValue = false;
10448 this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
10449 },
10450
10451 stopPropagation: function() {
10452 var event = this.nativeEvent;
10453 event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
10454 this.isPropagationStopped = emptyFunction.thatReturnsTrue;
10455 },
10456
10457 /**
10458 * We release all dispatched `SyntheticEvent`s after each event loop, adding
10459 * them back into the pool. This allows a way to hold onto a reference that
10460 * won't be added back into the pool.
10461 */
10462 persist: function() {
10463 this.isPersistent = emptyFunction.thatReturnsTrue;
10464 },
10465
10466 /**
10467 * Checks if this event should be released back into the pool.
10468 *
10469 * @return {boolean} True if this should not be released, false otherwise.
10470 */
10471 isPersistent: emptyFunction.thatReturnsFalse,
10472
10473 /**
10474 * `PooledClass` looks for `destructor` on each instance it releases.
10475 */
10476 destructor: function() {
10477 var Interface = this.constructor.Interface;
10478 for (var propName in Interface) {
10479 this[propName] = null;
10480 }
10481 this.dispatchConfig = null;
10482 this.dispatchMarker = null;
10483 this.nativeEvent = null;
10484 }
10485
10486});
10487
10488SyntheticEvent.Interface = EventInterface;
10489
10490/**
10491 * Helper to reduce boilerplate when creating subclasses.
10492 *
10493 * @param {function} Class
10494 * @param {?object} Interface
10495 */
10496SyntheticEvent.augmentClass = function(Class, Interface) {
10497 var Super = this;
10498
10499 var prototype = Object.create(Super.prototype);
10500 mergeInto(prototype, Class.prototype);
10501 Class.prototype = prototype;
10502 Class.prototype.constructor = Class;
10503
10504 Class.Interface = merge(Super.Interface, Interface);
10505 Class.augmentClass = Super.augmentClass;
10506
10507 PooledClass.addPoolingTo(Class, PooledClass.threeArgumentPooler);
10508};
10509
10510PooledClass.addPoolingTo(SyntheticEvent, PooledClass.threeArgumentPooler);
10511
10512module.exports = SyntheticEvent;
10513
10514},{"./PooledClass":21,"./emptyFunction":77,"./getEventTarget":84,"./merge":95,"./mergeInto":97}],61:[function(require,module,exports){
10515/**
10516 * Copyright 2013 Facebook, Inc.
10517 *
10518 * Licensed under the Apache License, Version 2.0 (the "License");
10519 * you may not use this file except in compliance with the License.
10520 * You may obtain a copy of the License at
10521 *
10522 * http://www.apache.org/licenses/LICENSE-2.0
10523 *
10524 * Unless required by applicable law or agreed to in writing, software
10525 * distributed under the License is distributed on an "AS IS" BASIS,
10526 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10527 * See the License for the specific language governing permissions and
10528 * limitations under the License.
10529 *
10530 * @providesModule SyntheticFocusEvent
10531 * @typechecks static-only
10532 */
10533
10534"use strict";
10535
10536var SyntheticUIEvent = require("./SyntheticUIEvent");
10537
10538/**
10539 * @interface FocusEvent
10540 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10541 */
10542var FocusEventInterface = {
10543 relatedTarget: null
10544};
10545
10546/**
10547 * @param {object} dispatchConfig Configuration used to dispatch this event.
10548 * @param {string} dispatchMarker Marker identifying the event target.
10549 * @param {object} nativeEvent Native browser event.
10550 * @extends {SyntheticUIEvent}
10551 */
10552function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent) {
10553 SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
10554}
10555
10556SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface);
10557
10558module.exports = SyntheticFocusEvent;
10559
10560},{"./SyntheticUIEvent":66}],62:[function(require,module,exports){
10561/**
10562 * Copyright 2013 Facebook, Inc.
10563 *
10564 * Licensed under the Apache License, Version 2.0 (the "License");
10565 * you may not use this file except in compliance with the License.
10566 * You may obtain a copy of the License at
10567 *
10568 * http://www.apache.org/licenses/LICENSE-2.0
10569 *
10570 * Unless required by applicable law or agreed to in writing, software
10571 * distributed under the License is distributed on an "AS IS" BASIS,
10572 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10573 * See the License for the specific language governing permissions and
10574 * limitations under the License.
10575 *
10576 * @providesModule SyntheticKeyboardEvent
10577 * @typechecks static-only
10578 */
10579
10580"use strict";
10581
10582var SyntheticUIEvent = require("./SyntheticUIEvent");
10583
10584/**
10585 * @interface KeyboardEvent
10586 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10587 */
10588var KeyboardEventInterface = {
10589 'char': null,
10590 key: null,
10591 location: null,
10592 ctrlKey: null,
10593 shiftKey: null,
10594 altKey: null,
10595 metaKey: null,
10596 repeat: null,
10597 locale: null,
10598 // Legacy Interface
10599 charCode: null,
10600 keyCode: null,
10601 which: null
10602};
10603
10604/**
10605 * @param {object} dispatchConfig Configuration used to dispatch this event.
10606 * @param {string} dispatchMarker Marker identifying the event target.
10607 * @param {object} nativeEvent Native browser event.
10608 * @extends {SyntheticUIEvent}
10609 */
10610function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
10611 SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
10612}
10613
10614SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface);
10615
10616module.exports = SyntheticKeyboardEvent;
10617
10618},{"./SyntheticUIEvent":66}],63:[function(require,module,exports){
10619/**
10620 * Copyright 2013 Facebook, Inc.
10621 *
10622 * Licensed under the Apache License, Version 2.0 (the "License");
10623 * you may not use this file except in compliance with the License.
10624 * You may obtain a copy of the License at
10625 *
10626 * http://www.apache.org/licenses/LICENSE-2.0
10627 *
10628 * Unless required by applicable law or agreed to in writing, software
10629 * distributed under the License is distributed on an "AS IS" BASIS,
10630 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10631 * See the License for the specific language governing permissions and
10632 * limitations under the License.
10633 *
10634 * @providesModule SyntheticMouseEvent
10635 * @typechecks static-only
10636 */
10637
10638"use strict";
10639
10640var SyntheticUIEvent = require("./SyntheticUIEvent");
10641var ViewportMetrics = require("./ViewportMetrics");
10642
10643/**
10644 * @interface MouseEvent
10645 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10646 */
10647var MouseEventInterface = {
10648 screenX: null,
10649 screenY: null,
10650 clientX: null,
10651 clientY: null,
10652 ctrlKey: null,
10653 shiftKey: null,
10654 altKey: null,
10655 metaKey: null,
10656 button: function(event) {
10657 // Webkit, Firefox, IE9+
10658 // which: 1 2 3
10659 // button: 0 1 2 (standard)
10660 var button = event.button;
10661 if ('which' in event) {
10662 return button;
10663 }
10664 // IE<9
10665 // which: undefined
10666 // button: 0 0 0
10667 // button: 1 4 2 (onmouseup)
10668 return button === 2 ? 2 : button === 4 ? 1 : 0;
10669 },
10670 buttons: null,
10671 relatedTarget: function(event) {
10672 return event.relatedTarget || (
10673 event.fromElement === event.srcElement ?
10674 event.toElement :
10675 event.fromElement
10676 );
10677 },
10678 // "Proprietary" Interface.
10679 pageX: function(event) {
10680 return 'pageX' in event ?
10681 event.pageX :
10682 event.clientX + ViewportMetrics.currentScrollLeft;
10683 },
10684 pageY: function(event) {
10685 return 'pageY' in event ?
10686 event.pageY :
10687 event.clientY + ViewportMetrics.currentScrollTop;
10688 }
10689};
10690
10691/**
10692 * @param {object} dispatchConfig Configuration used to dispatch this event.
10693 * @param {string} dispatchMarker Marker identifying the event target.
10694 * @param {object} nativeEvent Native browser event.
10695 * @extends {SyntheticUIEvent}
10696 */
10697function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent) {
10698 SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
10699}
10700
10701SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);
10702
10703module.exports = SyntheticMouseEvent;
10704
10705},{"./SyntheticUIEvent":66,"./ViewportMetrics":69}],64:[function(require,module,exports){
10706/**
10707 * Copyright 2013 Facebook, Inc.
10708 *
10709 * Licensed under the Apache License, Version 2.0 (the "License");
10710 * you may not use this file except in compliance with the License.
10711 * You may obtain a copy of the License at
10712 *
10713 * http://www.apache.org/licenses/LICENSE-2.0
10714 *
10715 * Unless required by applicable law or agreed to in writing, software
10716 * distributed under the License is distributed on an "AS IS" BASIS,
10717 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10718 * See the License for the specific language governing permissions and
10719 * limitations under the License.
10720 *
10721 * @providesModule SyntheticMutationEvent
10722 * @typechecks static-only
10723 */
10724
10725"use strict";
10726
10727var SyntheticEvent = require("./SyntheticEvent");
10728
10729/**
10730 * @interface MutationEvent
10731 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10732 */
10733var MutationEventInterface = {
10734 relatedNode: null,
10735 prevValue: null,
10736 newValue: null,
10737 attrName: null,
10738 attrChange: null
10739};
10740
10741/**
10742 * @param {object} dispatchConfig Configuration used to dispatch this event.
10743 * @param {string} dispatchMarker Marker identifying the event target.
10744 * @param {object} nativeEvent Native browser event.
10745 * @extends {SyntheticEvent}
10746 */
10747function SyntheticMutationEvent(dispatchConfig, dispatchMarker, nativeEvent) {
10748 SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
10749}
10750
10751SyntheticEvent.augmentClass(SyntheticMutationEvent, MutationEventInterface);
10752
10753module.exports = SyntheticMutationEvent;
10754
10755},{"./SyntheticEvent":60}],65:[function(require,module,exports){
10756/**
10757 * Copyright 2013 Facebook, Inc.
10758 *
10759 * Licensed under the Apache License, Version 2.0 (the "License");
10760 * you may not use this file except in compliance with the License.
10761 * You may obtain a copy of the License at
10762 *
10763 * http://www.apache.org/licenses/LICENSE-2.0
10764 *
10765 * Unless required by applicable law or agreed to in writing, software
10766 * distributed under the License is distributed on an "AS IS" BASIS,
10767 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10768 * See the License for the specific language governing permissions and
10769 * limitations under the License.
10770 *
10771 * @providesModule SyntheticTouchEvent
10772 * @typechecks static-only
10773 */
10774
10775"use strict";
10776
10777var SyntheticUIEvent = require("./SyntheticUIEvent");
10778
10779/**
10780 * @interface TouchEvent
10781 * @see http://www.w3.org/TR/touch-events/
10782 */
10783var TouchEventInterface = {
10784 touches: null,
10785 targetTouches: null,
10786 changedTouches: null,
10787 altKey: null,
10788 metaKey: null,
10789 ctrlKey: null,
10790 shiftKey: null
10791};
10792
10793/**
10794 * @param {object} dispatchConfig Configuration used to dispatch this event.
10795 * @param {string} dispatchMarker Marker identifying the event target.
10796 * @param {object} nativeEvent Native browser event.
10797 * @extends {SyntheticUIEvent}
10798 */
10799function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent) {
10800 SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
10801}
10802
10803SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface);
10804
10805module.exports = SyntheticTouchEvent;
10806
10807},{"./SyntheticUIEvent":66}],66:[function(require,module,exports){
10808/**
10809 * Copyright 2013 Facebook, Inc.
10810 *
10811 * Licensed under the Apache License, Version 2.0 (the "License");
10812 * you may not use this file except in compliance with the License.
10813 * You may obtain a copy of the License at
10814 *
10815 * http://www.apache.org/licenses/LICENSE-2.0
10816 *
10817 * Unless required by applicable law or agreed to in writing, software
10818 * distributed under the License is distributed on an "AS IS" BASIS,
10819 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10820 * See the License for the specific language governing permissions and
10821 * limitations under the License.
10822 *
10823 * @providesModule SyntheticUIEvent
10824 * @typechecks static-only
10825 */
10826
10827"use strict";
10828
10829var SyntheticEvent = require("./SyntheticEvent");
10830
10831/**
10832 * @interface UIEvent
10833 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10834 */
10835var UIEventInterface = {
10836 view: null,
10837 detail: null
10838};
10839
10840/**
10841 * @param {object} dispatchConfig Configuration used to dispatch this event.
10842 * @param {string} dispatchMarker Marker identifying the event target.
10843 * @param {object} nativeEvent Native browser event.
10844 * @extends {SyntheticEvent}
10845 */
10846function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent) {
10847 SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
10848}
10849
10850SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface);
10851
10852module.exports = SyntheticUIEvent;
10853
10854},{"./SyntheticEvent":60}],67:[function(require,module,exports){
10855/**
10856 * Copyright 2013 Facebook, Inc.
10857 *
10858 * Licensed under the Apache License, Version 2.0 (the "License");
10859 * you may not use this file except in compliance with the License.
10860 * You may obtain a copy of the License at
10861 *
10862 * http://www.apache.org/licenses/LICENSE-2.0
10863 *
10864 * Unless required by applicable law or agreed to in writing, software
10865 * distributed under the License is distributed on an "AS IS" BASIS,
10866 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10867 * See the License for the specific language governing permissions and
10868 * limitations under the License.
10869 *
10870 * @providesModule SyntheticWheelEvent
10871 * @typechecks static-only
10872 */
10873
10874"use strict";
10875
10876var SyntheticMouseEvent = require("./SyntheticMouseEvent");
10877
10878/**
10879 * @interface WheelEvent
10880 * @see http://www.w3.org/TR/DOM-Level-3-Events/
10881 */
10882var WheelEventInterface = {
10883 deltaX: function(event) {
10884 // NOTE: IE<9 does not support x-axis delta.
10885 return (
10886 'deltaX' in event ? event.deltaX :
10887 // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
10888 'wheelDeltaX' in event ? -event.wheelDeltaX : 0
10889 );
10890 },
10891 deltaY: function(event) {
10892 return (
10893 // Normalize (up is positive).
10894 'deltaY' in event ? -event.deltaY :
10895 // Fallback to `wheelDeltaY` for Webkit.
10896 'wheelDeltaY' in event ? event.wheelDeltaY :
10897 // Fallback to `wheelDelta` for IE<9.
10898 'wheelDelta' in event ? event.wheelData : 0
10899 );
10900 },
10901 deltaZ: null,
10902 deltaMode: null
10903};
10904
10905/**
10906 * @param {object} dispatchConfig Configuration used to dispatch this event.
10907 * @param {string} dispatchMarker Marker identifying the event target.
10908 * @param {object} nativeEvent Native browser event.
10909 * @extends {SyntheticMouseEvent}
10910 */
10911function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent) {
10912 SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
10913}
10914
10915SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface);
10916
10917module.exports = SyntheticWheelEvent;
10918
10919},{"./SyntheticMouseEvent":63}],68:[function(require,module,exports){
10920/**
10921 * Copyright 2013 Facebook, Inc.
10922 *
10923 * Licensed under the Apache License, Version 2.0 (the "License");
10924 * you may not use this file except in compliance with the License.
10925 * You may obtain a copy of the License at
10926 *
10927 * http://www.apache.org/licenses/LICENSE-2.0
10928 *
10929 * Unless required by applicable law or agreed to in writing, software
10930 * distributed under the License is distributed on an "AS IS" BASIS,
10931 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10932 * See the License for the specific language governing permissions and
10933 * limitations under the License.
10934 *
10935 * @providesModule Transaction
10936 */
10937
10938"use strict";
10939
10940var invariant = require("./invariant");
10941
10942/**
10943 * `Transaction` creates a black box that is able to wrap any method such that
10944 * certain invariants are maintained before and after the method is invoked
10945 * (Even if an exception is thrown while invoking the wrapped method). Whoever
10946 * instantiates a transaction can provide enforcers of the invariants at
10947 * creation time. The `Transaction` class itself will supply one additional
10948 * automatic invariant for you - the invariant that any transaction instance
10949 * should not be ran while it is already being ran. You would typically create a
10950 * single instance of a `Transaction` for reuse multiple times, that potentially
10951 * is used to wrap several different methods. Wrappers are extremely simple -
10952 * they only require implementing two methods.
10953 *
10954 * <pre>
10955 * wrappers (injected at creation time)
10956 * + +
10957 * | |
10958 * +-----------------|--------|--------------+
10959 * | v | |
10960 * | +---------------+ | |
10961 * | +--| wrapper1 |---|----+ |
10962 * | | +---------------+ v | |
10963 * | | +-------------+ | |
10964 * | | +----| wrapper2 |--------+ |
10965 * | | | +-------------+ | | |
10966 * | | | | | |
10967 * | v v v v | wrapper
10968 * | +---+ +---+ +---------+ +---+ +---+ | invariants
10969 * perform(anyMethod) | | | | | | | | | | | | maintained
10970 * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
10971 * | | | | | | | | | | | |
10972 * | | | | | | | | | | | |
10973 * | | | | | | | | | | | |
10974 * | +---+ +---+ +---------+ +---+ +---+ |
10975 * | initialize close |
10976 * +-----------------------------------------+
10977 * </pre>
10978 *
10979 * Bonus:
10980 * - Reports timing metrics by method name and wrapper index.
10981 *
10982 * Use cases:
10983 * - Preserving the input selection ranges before/after reconciliation.
10984 * Restoring selection even in the event of an unexpected error.
10985 * - Deactivating events while rearranging the DOM, preventing blurs/focuses,
10986 * while guaranteeing that afterwards, the event system is reactivated.
10987 * - Flushing a queue of collected DOM mutations to the main UI thread after a
10988 * reconciliation takes place in a worker thread.
10989 * - Invoking any collected `componentDidRender` callbacks after rendering new
10990 * content.
10991 * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue
10992 * to preserve the `scrollTop` (an automatic scroll aware DOM).
10993 * - (Future use case): Layout calculations before and after DOM upates.
10994 *
10995 * Transactional plugin API:
10996 * - A module that has an `initialize` method that returns any precomputation.
10997 * - and a `close` method that accepts the precomputation. `close` is invoked
10998 * when the wrapped process is completed, or has failed.
10999 *
11000 * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules
11001 * that implement `initialize` and `close`.
11002 * @return {Transaction} Single transaction for reuse in thread.
11003 *
11004 * @class Transaction
11005 */
11006var Mixin = {
11007 /**
11008 * Sets up this instance so that it is prepared for collecting metrics. Does
11009 * so such that this setup method may be used on an instance that is already
11010 * initialized, in a way that does not consume additional memory upon reuse.
11011 * That can be useful if you decide to make your subclass of this mixin a
11012 * "PooledClass".
11013 */
11014 reinitializeTransaction: function() {
11015 this.transactionWrappers = this.getTransactionWrappers();
11016 if (!this.wrapperInitData) {
11017 this.wrapperInitData = [];
11018 } else {
11019 this.wrapperInitData.length = 0;
11020 }
11021 if (!this.timingMetrics) {
11022 this.timingMetrics = {};
11023 }
11024 this.timingMetrics.methodInvocationTime = 0;
11025 if (!this.timingMetrics.wrapperInitTimes) {
11026 this.timingMetrics.wrapperInitTimes = [];
11027 } else {
11028 this.timingMetrics.wrapperInitTimes.length = 0;
11029 }
11030 if (!this.timingMetrics.wrapperCloseTimes) {
11031 this.timingMetrics.wrapperCloseTimes = [];
11032 } else {
11033 this.timingMetrics.wrapperCloseTimes.length = 0;
11034 }
11035 this._isInTransaction = false;
11036 },
11037
11038 _isInTransaction: false,
11039
11040 /**
11041 * @abstract
11042 * @return {Array<TransactionWrapper>} Array of transaction wrappers.
11043 */
11044 getTransactionWrappers: null,
11045
11046 isInTransaction: function() {
11047 return !!this._isInTransaction;
11048 },
11049
11050 /**
11051 * Executes the function within a safety window. Use this for the top level
11052 * methods that result in large amounts of computation/mutations that would
11053 * need to be safety checked.
11054 *
11055 * @param {function} method Member of scope to call.
11056 * @param {Object} scope Scope to invoke from.
11057 * @param {Object?=} args... Arguments to pass to the method (optional).
11058 * Helps prevent need to bind in many cases.
11059 * @return Return value from `method`.
11060 */
11061 perform: function(method, scope, a, b, c, d, e, f) {
11062 invariant(
11063 !this.isInTransaction(),
11064 'Transaction.perform(...): Cannot initialize a transaction when there ' +
11065 'is already an outstanding transaction.'
11066 );
11067 var memberStart = Date.now();
11068 var errorToThrow = null;
11069 var ret;
11070 try {
11071 this.initializeAll();
11072 ret = method.call(scope, a, b, c, d, e, f);
11073 } catch (error) {
11074 // IE8 requires `catch` in order to use `finally`.
11075 errorToThrow = error;
11076 } finally {
11077 var memberEnd = Date.now();
11078 this.methodInvocationTime += (memberEnd - memberStart);
11079 try {
11080 this.closeAll();
11081 } catch (closeError) {
11082 // If `method` throws, prefer to show that stack trace over any thrown
11083 // by invoking `closeAll`.
11084 errorToThrow = errorToThrow || closeError;
11085 }
11086 }
11087 if (errorToThrow) {
11088 throw errorToThrow;
11089 }
11090 return ret;
11091 },
11092
11093 initializeAll: function() {
11094 this._isInTransaction = true;
11095 var transactionWrappers = this.transactionWrappers;
11096 var wrapperInitTimes = this.timingMetrics.wrapperInitTimes;
11097 var errorToThrow = null;
11098 for (var i = 0; i < transactionWrappers.length; i++) {
11099 var initStart = Date.now();
11100 var wrapper = transactionWrappers[i];
11101 try {
11102 this.wrapperInitData[i] = wrapper.initialize ?
11103 wrapper.initialize.call(this) :
11104 null;
11105 } catch (initError) {
11106 // Prefer to show the stack trace of the first error.
11107 errorToThrow = errorToThrow || initError;
11108 this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
11109 } finally {
11110 var curInitTime = wrapperInitTimes[i];
11111 var initEnd = Date.now();
11112 wrapperInitTimes[i] = (curInitTime || 0) + (initEnd - initStart);
11113 }
11114 }
11115 if (errorToThrow) {
11116 throw errorToThrow;
11117 }
11118 },
11119
11120 /**
11121 * Invokes each of `this.transactionWrappers.close[i]` functions, passing into
11122 * them the respective return values of `this.transactionWrappers.init[i]`
11123 * (`close`rs that correspond to initializers that failed will not be
11124 * invoked).
11125 */
11126 closeAll: function() {
11127 invariant(
11128 this.isInTransaction(),
11129 'Transaction.closeAll(): Cannot close transaction when none are open.'
11130 );
11131 var transactionWrappers = this.transactionWrappers;
11132 var wrapperCloseTimes = this.timingMetrics.wrapperCloseTimes;
11133 var errorToThrow = null;
11134 for (var i = 0; i < transactionWrappers.length; i++) {
11135 var wrapper = transactionWrappers[i];
11136 var closeStart = Date.now();
11137 var initData = this.wrapperInitData[i];
11138 try {
11139 if (initData !== Transaction.OBSERVED_ERROR) {
11140 wrapper.close && wrapper.close.call(this, initData);
11141 }
11142 } catch (closeError) {
11143 // Prefer to show the stack trace of the first error.
11144 errorToThrow = errorToThrow || closeError;
11145 } finally {
11146 var closeEnd = Date.now();
11147 var curCloseTime = wrapperCloseTimes[i];
11148 wrapperCloseTimes[i] = (curCloseTime || 0) + (closeEnd - closeStart);
11149 }
11150 }
11151 this.wrapperInitData.length = 0;
11152 this._isInTransaction = false;
11153 if (errorToThrow) {
11154 throw errorToThrow;
11155 }
11156 }
11157};
11158
11159var Transaction = {
11160
11161 Mixin: Mixin,
11162
11163 /**
11164 * Token to look for to determine if an error occured.
11165 */
11166 OBSERVED_ERROR: {}
11167
11168};
11169
11170module.exports = Transaction;
11171
11172},{"./invariant":89}],69:[function(require,module,exports){
11173/**
11174 * Copyright 2013 Facebook, Inc.
11175 *
11176 * Licensed under the Apache License, Version 2.0 (the "License");
11177 * you may not use this file except in compliance with the License.
11178 * You may obtain a copy of the License at
11179 *
11180 * http://www.apache.org/licenses/LICENSE-2.0
11181 *
11182 * Unless required by applicable law or agreed to in writing, software
11183 * distributed under the License is distributed on an "AS IS" BASIS,
11184 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11185 * See the License for the specific language governing permissions and
11186 * limitations under the License.
11187 *
11188 * @providesModule ViewportMetrics
11189 */
11190
11191"use strict";
11192
11193var ViewportMetrics = {
11194
11195 currentScrollLeft: 0,
11196
11197 currentScrollTop: 0,
11198
11199 refreshScrollValues: function() {
11200 ViewportMetrics.currentScrollLeft =
11201 document.body.scrollLeft + document.documentElement.scrollLeft;
11202 ViewportMetrics.currentScrollTop =
11203 document.body.scrollTop + document.documentElement.scrollTop;
11204 }
11205
11206};
11207
11208module.exports = ViewportMetrics;
11209
11210},{}],70:[function(require,module,exports){
11211/**
11212 * Copyright 2013 Facebook, Inc.
11213 *
11214 * Licensed under the Apache License, Version 2.0 (the "License");
11215 * you may not use this file except in compliance with the License.
11216 * You may obtain a copy of the License at
11217 *
11218 * http://www.apache.org/licenses/LICENSE-2.0
11219 *
11220 * Unless required by applicable law or agreed to in writing, software
11221 * distributed under the License is distributed on an "AS IS" BASIS,
11222 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11223 * See the License for the specific language governing permissions and
11224 * limitations under the License.
11225 *
11226 * @providesModule accumulate
11227 */
11228
11229"use strict";
11230
11231var invariant = require("./invariant");
11232
11233/**
11234 * Accumulates items that must not be null or undefined.
11235 *
11236 * This is used to conserve memory by avoiding array allocations.
11237 *
11238 * @return {*|array<*>} An accumulation of items.
11239 */
11240function accumulate(current, next) {
11241 invariant(
11242 next != null,
11243 'accumulate(...): Accumulated items must be not be null or undefined.'
11244 );
11245 if (current == null) {
11246 return next;
11247 } else {
11248 // Both are not empty. Warning: Never call x.concat(y) when you are not
11249 // certain that x is an Array (x could be a string with concat method).
11250 var currentIsArray = Array.isArray(current);
11251 var nextIsArray = Array.isArray(next);
11252 if (currentIsArray) {
11253 return current.concat(next);
11254 } else {
11255 if (nextIsArray) {
11256 return [current].concat(next);
11257 } else {
11258 return [current, next];
11259 }
11260 }
11261 }
11262}
11263
11264module.exports = accumulate;
11265
11266},{"./invariant":89}],71:[function(require,module,exports){
11267/**
11268 * Copyright 2013 Facebook, Inc.
11269 *
11270 * Licensed under the Apache License, Version 2.0 (the "License");
11271 * you may not use this file except in compliance with the License.
11272 * You may obtain a copy of the License at
11273 *
11274 * http://www.apache.org/licenses/LICENSE-2.0
11275 *
11276 * Unless required by applicable law or agreed to in writing, software
11277 * distributed under the License is distributed on an "AS IS" BASIS,
11278 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11279 * See the License for the specific language governing permissions and
11280 * limitations under the License.
11281 *
11282 * @providesModule adler32
11283 */
11284
11285"use strict";
11286
11287var MOD = 65521;
11288
11289// This is a clean-room implementation of adler32 designed for detecting
11290// if markup is not what we expect it to be. It does not need to be
11291// cryptographically strong, only reasonable good at detecting if markup
11292// generated on the server is different than that on the client.
11293function adler32(data) {
11294 var a = 1;
11295 var b = 0;
11296 for (var i = 0; i < data.length; i++) {
11297 a = (a + data.charCodeAt(i)) % MOD;
11298 b = (b + a) % MOD;
11299 }
11300 return a | (b << 16);
11301}
11302
11303module.exports = adler32;
11304
11305},{}],72:[function(require,module,exports){
11306/**
11307 * Copyright 2013 Facebook, Inc.
11308 *
11309 * Licensed under the Apache License, Version 2.0 (the "License");
11310 * you may not use this file except in compliance with the License.
11311 * You may obtain a copy of the License at
11312 *
11313 * http://www.apache.org/licenses/LICENSE-2.0
11314 *
11315 * Unless required by applicable law or agreed to in writing, software
11316 * distributed under the License is distributed on an "AS IS" BASIS,
11317 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11318 * See the License for the specific language governing permissions and
11319 * limitations under the License.
11320 *
11321 * @providesModule copyProperties
11322 */
11323
11324/**
11325 * Copy properties from one or more objects (up to 5) into the first object.
11326 * This is a shallow copy. It mutates the first object and also returns it.
11327 *
11328 * NOTE: `arguments` has a very significant performance penalty, which is why
11329 * we don't support unlimited arguments.
11330 */
11331function copyProperties(obj, a, b, c, d, e, f) {
11332 obj = obj || {};
11333
11334 if (true) {
11335 if (f) {
11336 throw new Error('Too many arguments passed to copyProperties');
11337 }
11338 }
11339
11340 var args = [a, b, c, d, e];
11341 var ii = 0, v;
11342 while (args[ii]) {
11343 v = args[ii++];
11344 for (var k in v) {
11345 obj[k] = v[k];
11346 }
11347
11348 // IE ignores toString in object iteration.. See:
11349 // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html
11350 if (v.hasOwnProperty && v.hasOwnProperty('toString') &&
11351 (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) {
11352 obj.toString = v.toString;
11353 }
11354 }
11355
11356 return obj;
11357}
11358
11359module.exports = copyProperties;
11360
11361},{}],73:[function(require,module,exports){
11362/**
11363 * Copyright 2013 Facebook, Inc.
11364 *
11365 * Licensed under the Apache License, Version 2.0 (the "License");
11366 * you may not use this file except in compliance with the License.
11367 * You may obtain a copy of the License at
11368 *
11369 * http://www.apache.org/licenses/LICENSE-2.0
11370 *
11371 * Unless required by applicable law or agreed to in writing, software
11372 * distributed under the License is distributed on an "AS IS" BASIS,
11373 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11374 * See the License for the specific language governing permissions and
11375 * limitations under the License.
11376 *
11377 * @providesModule createArrayFrom
11378 * @typechecks
11379 */
11380
11381/**
11382 * NOTE: if you are a previous user of this function, it has been considered
11383 * unsafe because it's inconsistent across browsers for some inputs.
11384 * Instead use `Array.isArray()`.
11385 *
11386 * Perform a heuristic test to determine if an object is "array-like".
11387 *
11388 * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
11389 * Joshu replied: "Mu."
11390 *
11391 * This function determines if its argument has "array nature": it returns
11392 * true if the argument is an actual array, an `arguments' object, or an
11393 * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
11394 *
11395 * @param {*} obj
11396 * @return {boolean}
11397 */
11398function hasArrayNature(obj) {
11399 return (
11400 // not null/false
11401 !!obj &&
11402 // arrays are objects, NodeLists are functions in Safari
11403 (typeof obj == 'object' || typeof obj == 'function') &&
11404 // quacks like an array
11405 ('length' in obj) &&
11406 // not window
11407 !('setInterval' in obj) &&
11408 // no DOM node should be considered an array-like
11409 // a 'select' element has 'length' and 'item' properties on IE8
11410 (typeof obj.nodeType != 'number') &&
11411 (
11412 // a real array
11413 (// HTMLCollection/NodeList
11414 (Array.isArray(obj) ||
11415 // arguments
11416 ('callee' in obj) || 'item' in obj))
11417 )
11418 );
11419}
11420
11421/**
11422 * Ensure that the argument is an array by wrapping it in an array if it is not.
11423 * Creates a copy of the argument if it is already an array.
11424 *
11425 * This is mostly useful idiomatically:
11426 *
11427 * var createArrayFrom = require('createArrayFrom');
11428 *
11429 * function takesOneOrMoreThings(things) {
11430 * things = createArrayFrom(things);
11431 * ...
11432 * }
11433 *
11434 * This allows you to treat `things' as an array, but accept scalars in the API.
11435 *
11436 * This is also good for converting certain pseudo-arrays, like `arguments` or
11437 * HTMLCollections, into arrays.
11438 *
11439 * @param {*} obj
11440 * @return {array}
11441 */
11442function createArrayFrom(obj) {
11443 if (!hasArrayNature(obj)) {
11444 return [obj];
11445 }
11446 if (obj.item) {
11447 // IE does not support Array#slice on HTMLCollections
11448 var l = obj.length, ret = new Array(l);
11449 while (l--) { ret[l] = obj[l]; }
11450 return ret;
11451 }
11452 return Array.prototype.slice.call(obj);
11453}
11454
11455module.exports = createArrayFrom;
11456
11457},{}],74:[function(require,module,exports){
11458/**
11459 * Copyright 2013 Facebook, Inc.
11460 *
11461 * Licensed under the Apache License, Version 2.0 (the "License");
11462 * you may not use this file except in compliance with the License.
11463 * You may obtain a copy of the License at
11464 *
11465 * http://www.apache.org/licenses/LICENSE-2.0
11466 *
11467 * Unless required by applicable law or agreed to in writing, software
11468 * distributed under the License is distributed on an "AS IS" BASIS,
11469 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11470 * See the License for the specific language governing permissions and
11471 * limitations under the License.
11472 *
11473 * @providesModule createNodesFromMarkup
11474 * @typechecks
11475 */
11476
11477/*jslint evil: true, sub: true */
11478
11479var ExecutionEnvironment = require("./ExecutionEnvironment");
11480
11481var createArrayFrom = require("./createArrayFrom");
11482var getMarkupWrap = require("./getMarkupWrap");
11483var invariant = require("./invariant");
11484
11485/**
11486 * Dummy container used to render all markup.
11487 */
11488var dummyNode =
11489 ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
11490
11491/**
11492 * Pattern used by `getNodeName`.
11493 */
11494var nodeNamePattern = /^\s*<(\w+)/;
11495
11496/**
11497 * Extracts the `nodeName` of the first element in a string of markup.
11498 *
11499 * @param {string} markup String of markup.
11500 * @return {?string} Node name of the supplied markup.
11501 */
11502function getNodeName(markup) {
11503 var nodeNameMatch = markup.match(nodeNamePattern);
11504 return nodeNameMatch && nodeNameMatch[1].toLowerCase();
11505}
11506
11507/**
11508 * Creates an array containing the nodes rendered from the supplied markup. The
11509 * optionally supplied `handleScript` function will be invoked once for each
11510 * <script> element that is rendered. If no `handleScript` function is supplied,
11511 * an exception is thrown if any <script> elements are rendered.
11512 *
11513 * @param {string} markup A string of valid HTML markup.
11514 * @param {?function} handleScript Invoked once for each rendered <script>.
11515 * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.
11516 */
11517function createNodesFromMarkup(markup, handleScript) {
11518 var node = dummyNode;
11519 invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized');
11520 var nodeName = getNodeName(markup);
11521
11522 var wrap = nodeName && getMarkupWrap(nodeName);
11523 if (wrap) {
11524 node.innerHTML = wrap[1] + markup + wrap[2];
11525
11526 var wrapDepth = wrap[0];
11527 while (wrapDepth--) {
11528 node = node.lastChild;
11529 }
11530 } else {
11531 node.innerHTML = markup;
11532 }
11533
11534 var scripts = node.getElementsByTagName('script');
11535 if (scripts.length) {
11536 invariant(
11537 handleScript,
11538 'createNodesFromMarkup(...): Unexpected <script> element rendered.'
11539 );
11540 createArrayFrom(scripts).forEach(handleScript);
11541 }
11542
11543 var nodes = createArrayFrom(node.childNodes);
11544 while (node.lastChild) {
11545 node.removeChild(node.lastChild);
11546 }
11547 return nodes;
11548}
11549
11550module.exports = createNodesFromMarkup;
11551
11552},{"./ExecutionEnvironment":19,"./createArrayFrom":73,"./getMarkupWrap":85,"./invariant":89}],75:[function(require,module,exports){
11553/**
11554 * Copyright 2013 Facebook, Inc.
11555 *
11556 * Licensed under the Apache License, Version 2.0 (the "License");
11557 * you may not use this file except in compliance with the License.
11558 * You may obtain a copy of the License at
11559 *
11560 * http://www.apache.org/licenses/LICENSE-2.0
11561 *
11562 * Unless required by applicable law or agreed to in writing, software
11563 * distributed under the License is distributed on an "AS IS" BASIS,
11564 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11565 * See the License for the specific language governing permissions and
11566 * limitations under the License.
11567 *
11568 * @providesModule createObjectFrom
11569 */
11570
11571/**
11572 * Construct an object from an array of keys
11573 * and optionally specified value or list of values.
11574 *
11575 * >>> createObjectFrom(['a','b','c']);
11576 * {a: true, b: true, c: true}
11577 *
11578 * >>> createObjectFrom(['a','b','c'], false);
11579 * {a: false, b: false, c: false}
11580 *
11581 * >>> createObjectFrom(['a','b','c'], 'monkey');
11582 * {c:'monkey', b:'monkey' c:'monkey'}
11583 *
11584 * >>> createObjectFrom(['a','b','c'], [1,2,3]);
11585 * {a: 1, b: 2, c: 3}
11586 *
11587 * >>> createObjectFrom(['women', 'men'], [true, false]);
11588 * {women: true, men: false}
11589 *
11590 * @param Array list of keys
11591 * @param mixed optional value or value array. defaults true.
11592 * @returns object
11593 */
11594function createObjectFrom(keys, values /* = true */) {
11595 if (true) {
11596 if (!Array.isArray(keys)) {
11597 throw new TypeError('Must pass an array of keys.');
11598 }
11599 }
11600
11601 var object = {};
11602 var isArray = Array.isArray(values);
11603 if (typeof values == 'undefined') {
11604 values = true;
11605 }
11606
11607 for (var ii = keys.length; ii--;) {
11608 object[keys[ii]] = isArray ? values[ii] : values;
11609 }
11610 return object;
11611}
11612
11613module.exports = createObjectFrom;
11614
11615},{}],76:[function(require,module,exports){
11616/**
11617 * Copyright 2013 Facebook, Inc.
11618 *
11619 * Licensed under the Apache License, Version 2.0 (the "License");
11620 * you may not use this file except in compliance with the License.
11621 * You may obtain a copy of the License at
11622 *
11623 * http://www.apache.org/licenses/LICENSE-2.0
11624 *
11625 * Unless required by applicable law or agreed to in writing, software
11626 * distributed under the License is distributed on an "AS IS" BASIS,
11627 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11628 * See the License for the specific language governing permissions and
11629 * limitations under the License.
11630 *
11631 * @providesModule dangerousStyleValue
11632 * @typechecks static-only
11633 */
11634
11635"use strict";
11636
11637var CSSProperty = require("./CSSProperty");
11638
11639/**
11640 * Convert a value into the proper css writable value. The `styleName` name
11641 * name should be logical (no hyphens), as specified
11642 * in `CSSProperty.isUnitlessNumber`.
11643 *
11644 * @param {string} styleName CSS property name such as `topMargin`.
11645 * @param {*} value CSS property value such as `10px`.
11646 * @return {string} Normalized style value with dimensions applied.
11647 */
11648function dangerousStyleValue(styleName, value) {
11649 // Note that we've removed escapeTextForBrowser() calls here since the
11650 // whole string will be escaped when the attribute is injected into
11651 // the markup. If you provide unsafe user data here they can inject
11652 // arbitrary CSS which may be problematic (I couldn't repro this):
11653 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
11654 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
11655 // This is not an XSS hole but instead a potential CSS injection issue
11656 // which has lead to a greater discussion about how we're going to
11657 // trust URLs moving forward. See #2115901
11658
11659 var isEmpty = value == null || typeof value === 'boolean' || value === '';
11660 if (isEmpty) {
11661 return '';
11662 }
11663
11664 var isNonNumeric = isNaN(value);
11665 if (isNonNumeric || value === 0 || CSSProperty.isUnitlessNumber[styleName]) {
11666 return '' + value; // cast to string
11667 }
11668
11669 return value + 'px';
11670}
11671
11672module.exports = dangerousStyleValue;
11673
11674},{"./CSSProperty":2}],77:[function(require,module,exports){
11675/**
11676 * Copyright 2013 Facebook, Inc.
11677 *
11678 * Licensed under the Apache License, Version 2.0 (the "License");
11679 * you may not use this file except in compliance with the License.
11680 * You may obtain a copy of the License at
11681 *
11682 * http://www.apache.org/licenses/LICENSE-2.0
11683 *
11684 * Unless required by applicable law or agreed to in writing, software
11685 * distributed under the License is distributed on an "AS IS" BASIS,
11686 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11687 * See the License for the specific language governing permissions and
11688 * limitations under the License.
11689 *
11690 * @providesModule emptyFunction
11691 */
11692
11693var copyProperties = require("./copyProperties");
11694
11695function makeEmptyFunction(arg) {
11696 return function() {
11697 return arg;
11698 };
11699}
11700
11701/**
11702 * This function accepts and discards inputs; it has no side effects. This is
11703 * primarily useful idiomatically for overridable function endpoints which
11704 * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
11705 */
11706function emptyFunction() {}
11707
11708copyProperties(emptyFunction, {
11709 thatReturns: makeEmptyFunction,
11710 thatReturnsFalse: makeEmptyFunction(false),
11711 thatReturnsTrue: makeEmptyFunction(true),
11712 thatReturnsNull: makeEmptyFunction(null),
11713 thatReturnsThis: function() { return this; },
11714 thatReturnsArgument: function(arg) { return arg; }
11715});
11716
11717module.exports = emptyFunction;
11718
11719},{"./copyProperties":72}],78:[function(require,module,exports){
11720/**
11721 * Copyright 2013 Facebook, Inc.
11722 *
11723 * Licensed under the Apache License, Version 2.0 (the "License");
11724 * you may not use this file except in compliance with the License.
11725 * You may obtain a copy of the License at
11726 *
11727 * http://www.apache.org/licenses/LICENSE-2.0
11728 *
11729 * Unless required by applicable law or agreed to in writing, software
11730 * distributed under the License is distributed on an "AS IS" BASIS,
11731 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11732 * See the License for the specific language governing permissions and
11733 * limitations under the License.
11734 *
11735 * @providesModule escapeTextForBrowser
11736 * @typechecks static-only
11737 */
11738
11739"use strict";
11740
11741var invariant = require("./invariant");
11742
11743var ESCAPE_LOOKUP = {
11744 "&": "&amp;",
11745 ">": "&gt;",
11746 "<": "&lt;",
11747 "\"": "&quot;",
11748 "'": "&#x27;",
11749 "/": "&#x2f;"
11750};
11751
11752function escaper(match) {
11753 return ESCAPE_LOOKUP[match];
11754}
11755
11756/**
11757 * Escapes text to prevent scripting attacks.
11758 *
11759 * @param {number|string} text Text value to escape.
11760 * @return {string} An escaped string.
11761 */
11762function escapeTextForBrowser(text) {
11763 var type = typeof text;
11764 invariant(
11765 type !== 'object',
11766 'escapeTextForBrowser(...): Attempted to escape an object.'
11767 );
11768 if (text === '') {
11769 return '';
11770 } else {
11771 if (type === 'string') {
11772 return text.replace(/[&><"'\/]/g, escaper);
11773 } else {
11774 return (''+text).replace(/[&><"'\/]/g, escaper);
11775 }
11776 }
11777}
11778
11779module.exports = escapeTextForBrowser;
11780
11781},{"./invariant":89}],79:[function(require,module,exports){
11782/**
11783 * Copyright 2013 Facebook, Inc.
11784 *
11785 * Licensed under the Apache License, Version 2.0 (the "License");
11786 * you may not use this file except in compliance with the License.
11787 * You may obtain a copy of the License at
11788 *
11789 * http://www.apache.org/licenses/LICENSE-2.0
11790 *
11791 * Unless required by applicable law or agreed to in writing, software
11792 * distributed under the License is distributed on an "AS IS" BASIS,
11793 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11794 * See the License for the specific language governing permissions and
11795 * limitations under the License.
11796 *
11797 * @providesModule ex
11798 * @typechecks
11799 * @nostacktrace
11800 */
11801
11802/**
11803 * This function transforms error message with arguments into plain text error
11804 * message, so that it can be passed to window.onerror without losing anything.
11805 * It can then be transformed back by `erx()` function.
11806 *
11807 * Usage:
11808 * throw new Error(ex('Error %s from %s', errorCode, userID));
11809 *
11810 * @param {string} errorMessage
11811 */
11812
11813var ex = function(errorMessage/*, arg1, arg2, ...*/) {
11814 var args = Array.prototype.slice.call(arguments).map(function(arg) {
11815 return String(arg);
11816 });
11817 var expectedLength = errorMessage.split('%s').length - 1;
11818
11819 if (expectedLength !== args.length - 1) {
11820 // something wrong with the formatting string
11821 return ex('ex args number mismatch: %s', JSON.stringify(args));
11822 }
11823
11824 return ex._prefix + JSON.stringify(args) + ex._suffix;
11825};
11826
11827ex._prefix = '<![EX[';
11828ex._suffix = ']]>';
11829
11830module.exports = ex;
11831
11832},{}],80:[function(require,module,exports){
11833/**
11834 * Copyright 2013 Facebook, Inc.
11835 *
11836 * Licensed under the Apache License, Version 2.0 (the "License");
11837 * you may not use this file except in compliance with the License.
11838 * You may obtain a copy of the License at
11839 *
11840 * http://www.apache.org/licenses/LICENSE-2.0
11841 *
11842 * Unless required by applicable law or agreed to in writing, software
11843 * distributed under the License is distributed on an "AS IS" BASIS,
11844 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11845 * See the License for the specific language governing permissions and
11846 * limitations under the License.
11847 *
11848 * @providesModule filterAttributes
11849 * @typechecks static-only
11850 */
11851
11852/*jslint evil: true */
11853
11854'use strict';
11855
11856/**
11857 * Like filter(), but for a DOM nodes attributes. Returns an array of
11858 * the filter DOMAttribute objects. Does some perf related this like
11859 * caching attributes.length.
11860 *
11861 * @param {DOMElement} node Node whose attributes you want to filter
11862 * @return {array} array of DOM attribute objects.
11863 */
11864function filterAttributes(node, func, context) {
11865 var attributes = node.attributes;
11866 var numAttributes = attributes.length;
11867 var accumulator = [];
11868 for (var i = 0; i < numAttributes; i++) {
11869 var attr = attributes.item(i);
11870 if (func.call(context, attr)) {
11871 accumulator.push(attr);
11872 }
11873 }
11874 return accumulator;
11875}
11876
11877module.exports = filterAttributes;
11878
11879},{}],81:[function(require,module,exports){
11880/**
11881 * Copyright 2013 Facebook, Inc.
11882 *
11883 * Licensed under the Apache License, Version 2.0 (the "License");
11884 * you may not use this file except in compliance with the License.
11885 * You may obtain a copy of the License at
11886 *
11887 * http://www.apache.org/licenses/LICENSE-2.0
11888 *
11889 * Unless required by applicable law or agreed to in writing, software
11890 * distributed under the License is distributed on an "AS IS" BASIS,
11891 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11892 * See the License for the specific language governing permissions and
11893 * limitations under the License.
11894 *
11895 * @providesModule flattenChildren
11896 */
11897
11898"use strict";
11899
11900var invariant = require("./invariant");
11901var traverseAllChildren = require("./traverseAllChildren");
11902
11903/**
11904 * @param {function} traverseContext Context passed through traversal.
11905 * @param {?ReactComponent} child React child component.
11906 * @param {!string} name String name of key path to child.
11907 */
11908function flattenSingleChildIntoContext(traverseContext, child, name) {
11909 // We found a component instance.
11910 var result = traverseContext;
11911 invariant(
11912 !result.hasOwnProperty(name),
11913 'flattenChildren(...): Encountered two children with the same key, `%s`. ' +
11914 'Children keys must be unique.',
11915 name
11916 );
11917 result[name] = child;
11918}
11919
11920/**
11921 * Flattens children that are typically specified as `props.children`.
11922 * @return {!object} flattened children keyed by name.
11923 */
11924function flattenChildren(children) {
11925 if (children == null) {
11926 return children;
11927 }
11928 var result = {};
11929 traverseAllChildren(children, flattenSingleChildIntoContext, result);
11930 return result;
11931}
11932
11933module.exports = flattenChildren;
11934
11935},{"./invariant":89,"./traverseAllChildren":103}],82:[function(require,module,exports){
11936/**
11937 * Copyright 2013 Facebook, Inc.
11938 *
11939 * Licensed under the Apache License, Version 2.0 (the "License");
11940 * you may not use this file except in compliance with the License.
11941 * You may obtain a copy of the License at
11942 *
11943 * http://www.apache.org/licenses/LICENSE-2.0
11944 *
11945 * Unless required by applicable law or agreed to in writing, software
11946 * distributed under the License is distributed on an "AS IS" BASIS,
11947 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11948 * See the License for the specific language governing permissions and
11949 * limitations under the License.
11950 *
11951 * @providesModule forEachAccumulated
11952 */
11953
11954"use strict";
11955
11956/**
11957 * @param {array} an "accumulation" of items which is either an Array or
11958 * a single item. Useful when paired with the `accumulate` module. This is a
11959 * simple utility that allows us to reason about a collection of items, but
11960 * handling the case when there is exactly one item (and we do not need to
11961 * allocate an array).
11962 */
11963var forEachAccumulated = function(arr, cb, scope) {
11964 if (Array.isArray(arr)) {
11965 arr.forEach(cb, scope);
11966 } else if (arr) {
11967 cb.call(scope, arr);
11968 }
11969};
11970
11971module.exports = forEachAccumulated;
11972
11973},{}],83:[function(require,module,exports){
11974/**
11975 * Copyright 2013 Facebook, Inc.
11976 *
11977 * Licensed under the Apache License, Version 2.0 (the "License");
11978 * you may not use this file except in compliance with the License.
11979 * You may obtain a copy of the License at
11980 *
11981 * http://www.apache.org/licenses/LICENSE-2.0
11982 *
11983 * Unless required by applicable law or agreed to in writing, software
11984 * distributed under the License is distributed on an "AS IS" BASIS,
11985 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11986 * See the License for the specific language governing permissions and
11987 * limitations under the License.
11988 *
11989 * @providesModule ge
11990 */
11991
11992/**
11993 * Find a node by ID. Optionally search a sub-tree outside of the document
11994 *
11995 * Use ge if you're not sure whether or not the element exists. You can test
11996 * for existence yourself in your application code.
11997 *
11998 * If your application code depends on the existence of the element, use $
11999 * instead, which will throw in DEV if the element doesn't exist.
12000 */
12001function ge(arg, root, tag) {
12002 return typeof arg != 'string' ? arg :
12003 !root ? document.getElementById(arg) :
12004 _geFromSubtree(arg, root, tag);
12005}
12006
12007function _geFromSubtree(id, root, tag) {
12008 var elem, children, ii;
12009
12010 if (_getNodeID(root) == id) {
12011 return root;
12012 } else if (root.getElementsByTagName) {
12013 // All Elements implement this, which does an iterative DFS, which is
12014 // faster than recursion and doesn't run into stack depth issues.
12015 children = root.getElementsByTagName(tag || '*');
12016 for (ii = 0; ii < children.length; ii++) {
12017 if (_getNodeID(children[ii]) == id) {
12018 return children[ii];
12019 }
12020 }
12021 } else {
12022 // DocumentFragment does not implement getElementsByTagName, so
12023 // recurse over its children. Its children must be Elements, so
12024 // each child will use the getElementsByTagName case instead.
12025 children = root.childNodes;
12026 for (ii = 0; ii < children.length; ii++) {
12027 elem = _geFromSubtree(id, children[ii]);
12028 if (elem) {
12029 return elem;
12030 }
12031 }
12032 }
12033
12034 return null;
12035}
12036
12037/**
12038 * Return the ID value for a given node. This allows us to avoid issues
12039 * with forms that contain inputs with name="id".
12040 *
12041 * @return string (null if attribute not set)
12042 */
12043function _getNodeID(node) {
12044 // #document and #document-fragment do not have getAttributeNode.
12045 var id = node.getAttributeNode && node.getAttributeNode('id');
12046 return id ? id.value : null;
12047}
12048
12049module.exports = ge;
12050
12051},{}],84:[function(require,module,exports){
12052/**
12053 * Copyright 2013 Facebook, Inc.
12054 *
12055 * Licensed under the Apache License, Version 2.0 (the "License");
12056 * you may not use this file except in compliance with the License.
12057 * You may obtain a copy of the License at
12058 *
12059 * http://www.apache.org/licenses/LICENSE-2.0
12060 *
12061 * Unless required by applicable law or agreed to in writing, software
12062 * distributed under the License is distributed on an "AS IS" BASIS,
12063 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12064 * See the License for the specific language governing permissions and
12065 * limitations under the License.
12066 *
12067 * @providesModule getEventTarget
12068 * @typechecks static-only
12069 */
12070
12071"use strict";
12072
12073/**
12074 * Gets the target node from a native browser event by accounting for
12075 * inconsistencies in browser DOM APIs.
12076 *
12077 * @param {object} nativeEvent Native browser event.
12078 * @return {DOMEventTarget} Target node.
12079 */
12080function getEventTarget(nativeEvent) {
12081 var target = nativeEvent.target || nativeEvent.srcElement || window;
12082 // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
12083 // @see http://www.quirksmode.org/js/events_properties.html
12084 return target.nodeType === 3 ? target.parentNode : target;
12085}
12086
12087module.exports = getEventTarget;
12088
12089},{}],85:[function(require,module,exports){
12090/**
12091 * Copyright 2013 Facebook, Inc.
12092 *
12093 * Licensed under the Apache License, Version 2.0 (the "License");
12094 * you may not use this file except in compliance with the License.
12095 * You may obtain a copy of the License at
12096 *
12097 * http://www.apache.org/licenses/LICENSE-2.0
12098 *
12099 * Unless required by applicable law or agreed to in writing, software
12100 * distributed under the License is distributed on an "AS IS" BASIS,
12101 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12102 * See the License for the specific language governing permissions and
12103 * limitations under the License.
12104 *
12105 * @providesModule getMarkupWrap
12106 */
12107
12108var ExecutionEnvironment = require("./ExecutionEnvironment");
12109
12110var invariant = require("./invariant");
12111
12112/**
12113 * Dummy container used to detect which wraps are necessary.
12114 */
12115var dummyNode =
12116 ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
12117
12118/**
12119 * Some browsers cannot use `innerHTML` to render certain elements standalone,
12120 * so we wrap them, render the wrapped nodes, then extract the desired node.
12121 *
12122 * In IE8, certain elements cannot render alone, so wrap all elements ('*').
12123 */
12124var shouldWrap = {};
12125var markupWrap = {
12126 'area': [1, '<map>', '</map>'],
12127 'caption': [1, '<table>', '</table>'],
12128 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
12129 'colgroup': [1, '<table>', '</table>'],
12130 'legend': [1, '<fieldset>', '</fieldset>'],
12131 'optgroup': [1, '<select multiple="true">', '</select>'],
12132 'option': [1, '<select multiple="true">', '</select>'],
12133 'param': [1, '<object>', '</object>'],
12134 'tbody': [1, '<table>', '</table>'],
12135 'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],
12136 'tfoot': [1, '<table>', '</table>'],
12137 'th': [3, '<table><tbody><tr>', '</tr></tbody></table>'],
12138 'thead': [1, '<table>', '</table>'],
12139 'tr': [2, '<table><tbody>', '</tbody></table>'],
12140 '*': [1, '?<div>', '</div>']
12141};
12142
12143/**
12144 * Gets the markup wrap configuration for the supplied `nodeName`.
12145 *
12146 * NOTE: This lazily detects which wraps are necessary for the current browser.
12147 *
12148 * @param {string} nodeName Lowercase `nodeName`.
12149 * @return {?array} Markup wrap configuration, if applicable.
12150 */
12151function getMarkupWrap(nodeName) {
12152 invariant(!!dummyNode, 'Markup wrapping node not initialized');
12153 if (!markupWrap.hasOwnProperty(nodeName)) {
12154 nodeName = '*';
12155 }
12156 if (!shouldWrap.hasOwnProperty(nodeName)) {
12157 if (nodeName === '*') {
12158 dummyNode.innerHTML = '<link />';
12159 } else {
12160 dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>';
12161 }
12162 shouldWrap[nodeName] = !dummyNode.firstChild;
12163 }
12164 return shouldWrap[nodeName] ? markupWrap[nodeName] : null;
12165}
12166
12167
12168module.exports = getMarkupWrap;
12169
12170},{"./ExecutionEnvironment":19,"./invariant":89}],86:[function(require,module,exports){
12171/**
12172 * Copyright 2013 Facebook, Inc.
12173 *
12174 * Licensed under the Apache License, Version 2.0 (the "License");
12175 * you may not use this file except in compliance with the License.
12176 * You may obtain a copy of the License at
12177 *
12178 * http://www.apache.org/licenses/LICENSE-2.0
12179 *
12180 * Unless required by applicable law or agreed to in writing, software
12181 * distributed under the License is distributed on an "AS IS" BASIS,
12182 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12183 * See the License for the specific language governing permissions and
12184 * limitations under the License.
12185 *
12186 * @providesModule getReactRootElementInContainer
12187 */
12188
12189"use strict";
12190
12191/**
12192 * @param {DOMElement} container DOM element that may contain a React component
12193 * @return {?*} DOM element that may have the reactRoot ID, or null.
12194 */
12195function getReactRootElementInContainer(container) {
12196 return container && container.firstChild;
12197}
12198
12199module.exports = getReactRootElementInContainer;
12200
12201},{}],87:[function(require,module,exports){
12202/**
12203 * Copyright 2013 Facebook, Inc.
12204 *
12205 * Licensed under the Apache License, Version 2.0 (the "License");
12206 * you may not use this file except in compliance with the License.
12207 * You may obtain a copy of the License at
12208 *
12209 * http://www.apache.org/licenses/LICENSE-2.0
12210 *
12211 * Unless required by applicable law or agreed to in writing, software
12212 * distributed under the License is distributed on an "AS IS" BASIS,
12213 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12214 * See the License for the specific language governing permissions and
12215 * limitations under the License.
12216 *
12217 * @providesModule getTextContentAccessor
12218 */
12219
12220"use strict";
12221
12222var ExecutionEnvironment = require("./ExecutionEnvironment");
12223
12224var contentKey = null;
12225
12226/**
12227 * Gets the key used to access text content on a DOM node.
12228 *
12229 * @return {?string} Key used to access text content.
12230 * @internal
12231 */
12232function getTextContentAccessor() {
12233 if (!contentKey && ExecutionEnvironment.canUseDOM) {
12234 contentKey = 'innerText' in document.createElement('div') ?
12235 'innerText' :
12236 'textContent';
12237 }
12238 return contentKey;
12239}
12240
12241module.exports = getTextContentAccessor;
12242
12243},{"./ExecutionEnvironment":19}],88:[function(require,module,exports){
12244/**
12245 * Copyright 2013 Facebook, Inc.
12246 *
12247 * Licensed under the Apache License, Version 2.0 (the "License");
12248 * you may not use this file except in compliance with the License.
12249 * You may obtain a copy of the License at
12250 *
12251 * http://www.apache.org/licenses/LICENSE-2.0
12252 *
12253 * Unless required by applicable law or agreed to in writing, software
12254 * distributed under the License is distributed on an "AS IS" BASIS,
12255 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12256 * See the License for the specific language governing permissions and
12257 * limitations under the License.
12258 *
12259 * @providesModule hyphenate
12260 * @typechecks
12261 */
12262
12263var _uppercasePattern = /([A-Z])/g;
12264
12265/**
12266 * Hyphenates a camelcased string, for example:
12267 *
12268 * > hyphenate('backgroundColor')
12269 * < "background-color"
12270 *
12271 * @param {string} string
12272 * @return {string}
12273 */
12274function hyphenate(string) {
12275 return string.replace(_uppercasePattern, '-$1').toLowerCase();
12276}
12277
12278module.exports = hyphenate;
12279
12280},{}],89:[function(require,module,exports){
12281/**
12282 * Copyright 2013 Facebook, Inc.
12283 *
12284 * Licensed under the Apache License, Version 2.0 (the "License");
12285 * you may not use this file except in compliance with the License.
12286 * You may obtain a copy of the License at
12287 *
12288 * http://www.apache.org/licenses/LICENSE-2.0
12289 *
12290 * Unless required by applicable law or agreed to in writing, software
12291 * distributed under the License is distributed on an "AS IS" BASIS,
12292 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12293 * See the License for the specific language governing permissions and
12294 * limitations under the License.
12295 *
12296 * @providesModule invariant
12297 */
12298
12299/**
12300 * Use invariant() to assert state which your program assumes to be true.
12301 *
12302 * Provide sprintf style format and arguments to provide information about
12303 * what broke and what you were expecting.
12304 *
12305 * The invariant message will be stripped in production, but the invariant
12306 * will remain to ensure logic does not differ in production.
12307 */
12308
12309function invariant(condition) {
12310 if (!condition) {
12311 throw new Error('Invariant Violation');
12312 }
12313}
12314
12315module.exports = invariant;
12316
12317if (true) {
12318 var invariantDev = function(condition, format, a, b, c, d, e, f) {
12319 if (format === undefined) {
12320 throw new Error('invariant requires an error message argument');
12321 }
12322
12323 if (!condition) {
12324 var args = [a, b, c, d, e, f];
12325 var argIndex = 0;
12326 throw new Error(
12327 'Invariant Violation: ' +
12328 format.replace(/%s/g, function() { return args[argIndex++]; })
12329 );
12330 }
12331 };
12332
12333 module.exports = invariantDev;
12334}
12335
12336},{}],90:[function(require,module,exports){
12337/**
12338 * Copyright 2013 Facebook, Inc.
12339 *
12340 * Licensed under the Apache License, Version 2.0 (the "License");
12341 * you may not use this file except in compliance with the License.
12342 * You may obtain a copy of the License at
12343 *
12344 * http://www.apache.org/licenses/LICENSE-2.0
12345 *
12346 * Unless required by applicable law or agreed to in writing, software
12347 * distributed under the License is distributed on an "AS IS" BASIS,
12348 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12349 * See the License for the specific language governing permissions and
12350 * limitations under the License.
12351 *
12352 * @providesModule isEventSupported
12353 */
12354
12355"use strict";
12356
12357var ExecutionEnvironment = require("./ExecutionEnvironment");
12358
12359var testNode, useHasFeature;
12360if (ExecutionEnvironment.canUseDOM) {
12361 testNode = document.createElement('div');
12362 useHasFeature =
12363 document.implementation &&
12364 document.implementation.hasFeature &&
12365 // `hasFeature` always returns true in Firefox 19+.
12366 document.implementation.hasFeature('', '') !== true;
12367}
12368
12369/**
12370 * Checks if an event is supported in the current execution environment.
12371 *
12372 * NOTE: This will not work correctly for non-generic events such as `change`,
12373 * `reset`, `load`, `error`, and `select`.
12374 *
12375 * Borrows from Modernizr.
12376 *
12377 * @param {string} eventNameSuffix Event name, e.g. "click".
12378 * @param {?boolean} capture Check if the capture phase is supported.
12379 * @return {boolean} True if the event is supported.
12380 * @internal
12381 * @license Modernizr 3.0.0pre (Custom Build) | MIT
12382 */
12383function isEventSupported(eventNameSuffix, capture) {
12384 if (!testNode || (capture && !testNode.addEventListener)) {
12385 return false;
12386 }
12387 var element = document.createElement('div');
12388
12389 var eventName = 'on' + eventNameSuffix;
12390 var isSupported = eventName in element;
12391
12392 if (!isSupported) {
12393 element.setAttribute(eventName, '');
12394 isSupported = typeof element[eventName] === 'function';
12395 if (typeof element[eventName] !== 'undefined') {
12396 element[eventName] = undefined;
12397 }
12398 element.removeAttribute(eventName);
12399 }
12400
12401 if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {
12402 // This is the only way to test support for the `wheel` event in IE9+.
12403 isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
12404 }
12405
12406 element = null;
12407 return isSupported;
12408}
12409
12410module.exports = isEventSupported;
12411
12412},{"./ExecutionEnvironment":19}],91:[function(require,module,exports){
12413/**
12414 * Copyright 2013 Facebook, Inc.
12415 *
12416 * Licensed under the Apache License, Version 2.0 (the "License");
12417 * you may not use this file except in compliance with the License.
12418 * You may obtain a copy of the License at
12419 *
12420 * http://www.apache.org/licenses/LICENSE-2.0
12421 *
12422 * Unless required by applicable law or agreed to in writing, software
12423 * distributed under the License is distributed on an "AS IS" BASIS,
12424 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425 * See the License for the specific language governing permissions and
12426 * limitations under the License.
12427 *
12428 * @providesModule joinClasses
12429 * @typechecks static-only
12430 */
12431
12432"use strict";
12433
12434/**
12435 * Combines multiple className strings into one.
12436 * http://jsperf.com/joinclasses-args-vs-array
12437 *
12438 * @param {...?string} classes
12439 * @return {string}
12440 */
12441function joinClasses(className/*, ... */) {
12442 if (!className) {
12443 className = '';
12444 }
12445 var nextClass;
12446 var argLength = arguments.length;
12447 if (argLength > 1) {
12448 for (var ii = 1; ii < argLength; ii++) {
12449 nextClass = arguments[ii];
12450 nextClass && (className += ' ' + nextClass);
12451 }
12452 }
12453 return className;
12454}
12455
12456module.exports = joinClasses;
12457
12458},{}],92:[function(require,module,exports){
12459/**
12460 * Copyright 2013 Facebook, Inc.
12461 *
12462 * Licensed under the Apache License, Version 2.0 (the "License");
12463 * you may not use this file except in compliance with the License.
12464 * You may obtain a copy of the License at
12465 *
12466 * http://www.apache.org/licenses/LICENSE-2.0
12467 *
12468 * Unless required by applicable law or agreed to in writing, software
12469 * distributed under the License is distributed on an "AS IS" BASIS,
12470 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12471 * See the License for the specific language governing permissions and
12472 * limitations under the License.
12473 *
12474 * @providesModule keyMirror
12475 * @typechecks static-only
12476 */
12477
12478"use strict";
12479
12480var invariant = require("./invariant");
12481
12482/**
12483 * Constructs an enumeration with keys equal to their value.
12484 *
12485 * For example:
12486 *
12487 * var COLORS = keyMirror({blue: null, red: null});
12488 * var myColor = COLORS.blue;
12489 * var isColorValid = !!COLORS[myColor];
12490 *
12491 * The last line could not be performed if the values of the generated enum were
12492 * not equal to their keys.
12493 *
12494 * Input: {key1: val1, key2: val2}
12495 * Output: {key1: key1, key2: key2}
12496 *
12497 * @param {object} obj
12498 * @return {object}
12499 */
12500var keyMirror = function(obj) {
12501 var ret = {};
12502 var key;
12503 invariant(
12504 obj instanceof Object && !Array.isArray(obj),
12505 'keyMirror(...): Argument must be an object.'
12506 );
12507 for (key in obj) {
12508 if (!obj.hasOwnProperty(key)) {
12509 continue;
12510 }
12511 ret[key] = key;
12512 }
12513 return ret;
12514};
12515
12516module.exports = keyMirror;
12517
12518},{"./invariant":89}],93:[function(require,module,exports){
12519/**
12520 * Copyright 2013 Facebook, Inc.
12521 *
12522 * Licensed under the Apache License, Version 2.0 (the "License");
12523 * you may not use this file except in compliance with the License.
12524 * You may obtain a copy of the License at
12525 *
12526 * http://www.apache.org/licenses/LICENSE-2.0
12527 *
12528 * Unless required by applicable law or agreed to in writing, software
12529 * distributed under the License is distributed on an "AS IS" BASIS,
12530 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12531 * See the License for the specific language governing permissions and
12532 * limitations under the License.
12533 *
12534 * @providesModule keyOf
12535 */
12536
12537/**
12538 * Allows extraction of a minified key. Let's the build system minify keys
12539 * without loosing the ability to dynamically use key strings as values
12540 * themselves. Pass in an object with a single key/val pair and it will return
12541 * you the string key of that single record. Suppose you want to grab the
12542 * value for a key 'className' inside of an object. Key/val minification may
12543 * have aliased that key to be 'xa12'. keyOf({className: null}) will return
12544 * 'xa12' in that case. Resolve keys you want to use once at startup time, then
12545 * reuse those resolutions.
12546 */
12547var keyOf = function(oneKeyObj) {
12548 var key;
12549 for (key in oneKeyObj) {
12550 if (!oneKeyObj.hasOwnProperty(key)) {
12551 continue;
12552 }
12553 return key;
12554 }
12555 return null;
12556};
12557
12558
12559module.exports = keyOf;
12560
12561},{}],94:[function(require,module,exports){
12562/**
12563 * Copyright 2013 Facebook, Inc.
12564 *
12565 * Licensed under the Apache License, Version 2.0 (the "License");
12566 * you may not use this file except in compliance with the License.
12567 * You may obtain a copy of the License at
12568 *
12569 * http://www.apache.org/licenses/LICENSE-2.0
12570 *
12571 * Unless required by applicable law or agreed to in writing, software
12572 * distributed under the License is distributed on an "AS IS" BASIS,
12573 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12574 * See the License for the specific language governing permissions and
12575 * limitations under the License.
12576 *
12577 * @providesModule memoizeStringOnly
12578 * @typechecks static-only
12579 */
12580
12581"use strict";
12582
12583/**
12584 * Memoizes the return value of a function that accepts one string argument.
12585 *
12586 * @param {function} callback
12587 * @return {function}
12588 */
12589function memoizeStringOnly(callback) {
12590 var cache = {};
12591 return function(string) {
12592 if (cache.hasOwnProperty(string)) {
12593 return cache[string];
12594 } else {
12595 return cache[string] = callback.call(this, string);
12596 }
12597 };
12598}
12599
12600module.exports = memoizeStringOnly;
12601
12602},{}],95:[function(require,module,exports){
12603/**
12604 * Copyright 2013 Facebook, Inc.
12605 *
12606 * Licensed under the Apache License, Version 2.0 (the "License");
12607 * you may not use this file except in compliance with the License.
12608 * You may obtain a copy of the License at
12609 *
12610 * http://www.apache.org/licenses/LICENSE-2.0
12611 *
12612 * Unless required by applicable law or agreed to in writing, software
12613 * distributed under the License is distributed on an "AS IS" BASIS,
12614 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12615 * See the License for the specific language governing permissions and
12616 * limitations under the License.
12617 *
12618 * @providesModule merge
12619 */
12620
12621"use strict";
12622
12623var mergeInto = require("./mergeInto");
12624
12625/**
12626 * Shallow merges two structures into a return value, without mutating either.
12627 *
12628 * @param {?object} one Optional object with properties to merge from.
12629 * @param {?object} two Optional object with properties to merge from.
12630 * @return {object} The shallow extension of one by two.
12631 */
12632var merge = function(one, two) {
12633 var result = {};
12634 mergeInto(result, one);
12635 mergeInto(result, two);
12636 return result;
12637};
12638
12639module.exports = merge;
12640
12641},{"./mergeInto":97}],96:[function(require,module,exports){
12642/**
12643 * Copyright 2013 Facebook, Inc.
12644 *
12645 * Licensed under the Apache License, Version 2.0 (the "License");
12646 * you may not use this file except in compliance with the License.
12647 * You may obtain a copy of the License at
12648 *
12649 * http://www.apache.org/licenses/LICENSE-2.0
12650 *
12651 * Unless required by applicable law or agreed to in writing, software
12652 * distributed under the License is distributed on an "AS IS" BASIS,
12653 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12654 * See the License for the specific language governing permissions and
12655 * limitations under the License.
12656 *
12657 * @providesModule mergeHelpers
12658 *
12659 * requiresPolyfills: Array.isArray
12660 */
12661
12662"use strict";
12663
12664var invariant = require("./invariant");
12665var keyMirror = require("./keyMirror");
12666
12667/**
12668 * Maximum number of levels to traverse. Will catch circular structures.
12669 * @const
12670 */
12671var MAX_MERGE_DEPTH = 36;
12672
12673/**
12674 * We won't worry about edge cases like new String('x') or new Boolean(true).
12675 * Functions are considered terminals, and arrays are not.
12676 * @param {*} o The item/object/value to test.
12677 * @return {boolean} true iff the argument is a terminal.
12678 */
12679var isTerminal = function(o) {
12680 return typeof o !== 'object' || o === null;
12681};
12682
12683var mergeHelpers = {
12684
12685 MAX_MERGE_DEPTH: MAX_MERGE_DEPTH,
12686
12687 isTerminal: isTerminal,
12688
12689 /**
12690 * Converts null/undefined values into empty object.
12691 *
12692 * @param {?Object=} arg Argument to be normalized (nullable optional)
12693 * @return {!Object}
12694 */
12695 normalizeMergeArg: function(arg) {
12696 return arg === undefined || arg === null ? {} : arg;
12697 },
12698
12699 /**
12700 * If merging Arrays, a merge strategy *must* be supplied. If not, it is
12701 * likely the caller's fault. If this function is ever called with anything
12702 * but `one` and `two` being `Array`s, it is the fault of the merge utilities.
12703 *
12704 * @param {*} one Array to merge into.
12705 * @param {*} two Array to merge from.
12706 */
12707 checkMergeArrayArgs: function(one, two) {
12708 invariant(
12709 Array.isArray(one) && Array.isArray(two),
12710 'Critical assumptions about the merge functions have been violated. ' +
12711 'This is the fault of the merge functions themselves, not necessarily ' +
12712 'the callers.'
12713 );
12714 },
12715
12716 /**
12717 * @param {*} one Object to merge into.
12718 * @param {*} two Object to merge from.
12719 */
12720 checkMergeObjectArgs: function(one, two) {
12721 mergeHelpers.checkMergeObjectArg(one);
12722 mergeHelpers.checkMergeObjectArg(two);
12723 },
12724
12725 /**
12726 * @param {*} arg
12727 */
12728 checkMergeObjectArg: function(arg) {
12729 invariant(
12730 !isTerminal(arg) && !Array.isArray(arg),
12731 'Critical assumptions about the merge functions have been violated. ' +
12732 'This is the fault of the merge functions themselves, not necessarily ' +
12733 'the callers.'
12734 );
12735 },
12736
12737 /**
12738 * Checks that a merge was not given a circular object or an object that had
12739 * too great of depth.
12740 *
12741 * @param {number} Level of recursion to validate against maximum.
12742 */
12743 checkMergeLevel: function(level) {
12744 invariant(
12745 level < MAX_MERGE_DEPTH,
12746 'Maximum deep merge depth exceeded. You may be attempting to merge ' +
12747 'circular structures in an unsupported way.'
12748 );
12749 },
12750
12751 /**
12752 * Checks that the supplied merge strategy is valid.
12753 *
12754 * @param {string} Array merge strategy.
12755 */
12756 checkArrayStrategy: function(strategy) {
12757 invariant(
12758 strategy === undefined || strategy in mergeHelpers.ArrayStrategies,
12759 'You must provide an array strategy to deep merge functions to ' +
12760 'instruct the deep merge how to resolve merging two arrays.'
12761 );
12762 },
12763
12764 /**
12765 * Set of possible behaviors of merge algorithms when encountering two Arrays
12766 * that must be merged together.
12767 * - `clobber`: The left `Array` is ignored.
12768 * - `indexByIndex`: The result is achieved by recursively deep merging at
12769 * each index. (not yet supported.)
12770 */
12771 ArrayStrategies: keyMirror({
12772 Clobber: true,
12773 IndexByIndex: true
12774 })
12775
12776};
12777
12778module.exports = mergeHelpers;
12779
12780},{"./invariant":89,"./keyMirror":92}],97:[function(require,module,exports){
12781/**
12782 * Copyright 2013 Facebook, Inc.
12783 *
12784 * Licensed under the Apache License, Version 2.0 (the "License");
12785 * you may not use this file except in compliance with the License.
12786 * You may obtain a copy of the License at
12787 *
12788 * http://www.apache.org/licenses/LICENSE-2.0
12789 *
12790 * Unless required by applicable law or agreed to in writing, software
12791 * distributed under the License is distributed on an "AS IS" BASIS,
12792 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12793 * See the License for the specific language governing permissions and
12794 * limitations under the License.
12795 *
12796 * @providesModule mergeInto
12797 * @typechecks static-only
12798 */
12799
12800"use strict";
12801
12802var mergeHelpers = require("./mergeHelpers");
12803
12804var checkMergeObjectArg = mergeHelpers.checkMergeObjectArg;
12805
12806/**
12807 * Shallow merges two structures by mutating the first parameter.
12808 *
12809 * @param {object} one Object to be merged into.
12810 * @param {?object} two Optional object with properties to merge from.
12811 */
12812function mergeInto(one, two) {
12813 checkMergeObjectArg(one);
12814 if (two != null) {
12815 checkMergeObjectArg(two);
12816 for (var key in two) {
12817 if (!two.hasOwnProperty(key)) {
12818 continue;
12819 }
12820 one[key] = two[key];
12821 }
12822 }
12823}
12824
12825module.exports = mergeInto;
12826
12827},{"./mergeHelpers":96}],98:[function(require,module,exports){
12828/**
12829 * Copyright 2013 Facebook, Inc.
12830 *
12831 * Licensed under the Apache License, Version 2.0 (the "License");
12832 * you may not use this file except in compliance with the License.
12833 * You may obtain a copy of the License at
12834 *
12835 * http://www.apache.org/licenses/LICENSE-2.0
12836 *
12837 * Unless required by applicable law or agreed to in writing, software
12838 * distributed under the License is distributed on an "AS IS" BASIS,
12839 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12840 * See the License for the specific language governing permissions and
12841 * limitations under the License.
12842 *
12843 * @providesModule mixInto
12844 */
12845
12846"use strict";
12847
12848/**
12849 * Simply copies properties to the prototype.
12850 */
12851var mixInto = function(constructor, methodBag) {
12852 var methodName;
12853 for (methodName in methodBag) {
12854 if (!methodBag.hasOwnProperty(methodName)) {
12855 continue;
12856 }
12857 constructor.prototype[methodName] = methodBag[methodName];
12858 }
12859};
12860
12861module.exports = mixInto;
12862
12863},{}],99:[function(require,module,exports){
12864/**
12865 * Copyright 2013 Facebook, Inc.
12866 *
12867 * Licensed under the Apache License, Version 2.0 (the "License");
12868 * you may not use this file except in compliance with the License.
12869 * You may obtain a copy of the License at
12870 *
12871 * http://www.apache.org/licenses/LICENSE-2.0
12872 *
12873 * Unless required by applicable law or agreed to in writing, software
12874 * distributed under the License is distributed on an "AS IS" BASIS,
12875 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12876 * See the License for the specific language governing permissions and
12877 * limitations under the License.
12878 *
12879 * @providesModule mutateHTMLNodeWithMarkup
12880 * @typechecks static-only
12881 */
12882
12883/*jslint evil: true */
12884
12885'use strict';
12886
12887var createNodesFromMarkup = require("./createNodesFromMarkup");
12888var filterAttributes = require("./filterAttributes");
12889var invariant = require("./invariant");
12890
12891/**
12892 * You can't set the innerHTML of a document. Unless you have
12893 * this function.
12894 *
12895 * @param {DOMElement} node with tagName == 'html'
12896 * @param {string} markup markup string including <html>.
12897 */
12898function mutateHTMLNodeWithMarkup(node, markup) {
12899 invariant(
12900 node.tagName.toLowerCase() === 'html',
12901 'mutateHTMLNodeWithMarkup(): node must have tagName of "html", got %s',
12902 node.tagName
12903 );
12904
12905 markup = markup.trim();
12906 invariant(
12907 markup.toLowerCase().indexOf('<html') === 0,
12908 'mutateHTMLNodeWithMarkup(): markup must start with <html'
12909 );
12910
12911 // First let's extract the various pieces of markup.
12912 var htmlOpenTagEnd = markup.indexOf('>') + 1;
12913 var htmlCloseTagStart = markup.lastIndexOf('<');
12914 var htmlOpenTag = markup.substring(0, htmlOpenTagEnd);
12915 var innerHTML = markup.substring(htmlOpenTagEnd, htmlCloseTagStart);
12916
12917 // Now for the fun stuff. Pass through both sets of attributes and
12918 // bring them up-to-date. We get the new set by creating a markup
12919 // fragment.
12920 var shouldExtractAttributes = htmlOpenTag.indexOf(' ') > -1;
12921 var attributeHolder = null;
12922
12923 if (shouldExtractAttributes) {
12924 // We extract the attributes by creating a <span> and evaluating
12925 // the node.
12926 attributeHolder = createNodesFromMarkup(
12927 htmlOpenTag.replace('html ', 'span ') + '</span>'
12928 )[0];
12929
12930 // Add all attributes present in attributeHolder
12931 var attributesToSet = filterAttributes(
12932 attributeHolder,
12933 function(attr) {
12934 return node.getAttributeNS(attr.namespaceURI, attr.name) !== attr.value;
12935 }
12936 );
12937 attributesToSet.forEach(function(attr) {
12938 node.setAttributeNS(attr.namespaceURI, attr.name, attr.value);
12939 });
12940 }
12941
12942 // Remove all attributes not present in attributeHolder
12943 var attributesToRemove = filterAttributes(
12944 node,
12945 function(attr) {
12946 // Remove all attributes if attributeHolder is null or if it does not have
12947 // the desired attribute.
12948 return !(
12949 attributeHolder &&
12950 attributeHolder.hasAttributeNS(attr.namespaceURI, attr.name)
12951 );
12952 }
12953 );
12954 attributesToRemove.forEach(function(attr) {
12955 node.removeAttributeNS(attr.namespaceURI, attr.name);
12956 });
12957
12958 // Finally, set the inner HTML. No tricks needed. Do this last to
12959 // minimize likelihood of triggering reflows.
12960 node.innerHTML = innerHTML;
12961}
12962
12963module.exports = mutateHTMLNodeWithMarkup;
12964
12965},{"./createNodesFromMarkup":74,"./filterAttributes":80,"./invariant":89}],100:[function(require,module,exports){
12966/**
12967 * Copyright 2013 Facebook, Inc.
12968 *
12969 * Licensed under the Apache License, Version 2.0 (the "License");
12970 * you may not use this file except in compliance with the License.
12971 * You may obtain a copy of the License at
12972 *
12973 * http://www.apache.org/licenses/LICENSE-2.0
12974 *
12975 * Unless required by applicable law or agreed to in writing, software
12976 * distributed under the License is distributed on an "AS IS" BASIS,
12977 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12978 * See the License for the specific language governing permissions and
12979 * limitations under the License.
12980 *
12981 * @providesModule objMap
12982 */
12983
12984"use strict";
12985
12986/**
12987 * For each key/value pair, invokes callback func and constructs a resulting
12988 * object which contains, for every key in obj, values that are the result of
12989 * of invoking the function:
12990 *
12991 * func(value, key, iteration)
12992 *
12993 * @param {?object} obj Object to map keys over
12994 * @param {function} func Invoked for each key/val pair.
12995 * @param {?*} context
12996 * @return {?object} Result of mapping or null if obj is falsey
12997 */
12998function objMap(obj, func, context) {
12999 if (!obj) {
13000 return null;
13001 }
13002 var i = 0;
13003 var ret = {};
13004 for (var key in obj) {
13005 if (obj.hasOwnProperty(key)) {
13006 ret[key] = func.call(context, obj[key], key, i++);
13007 }
13008 }
13009 return ret;
13010}
13011
13012module.exports = objMap;
13013
13014},{}],101:[function(require,module,exports){
13015/**
13016 * Copyright 2013 Facebook, Inc.
13017 *
13018 * Licensed under the Apache License, Version 2.0 (the "License");
13019 * you may not use this file except in compliance with the License.
13020 * You may obtain a copy of the License at
13021 *
13022 * http://www.apache.org/licenses/LICENSE-2.0
13023 *
13024 * Unless required by applicable law or agreed to in writing, software
13025 * distributed under the License is distributed on an "AS IS" BASIS,
13026 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13027 * See the License for the specific language governing permissions and
13028 * limitations under the License.
13029 *
13030 * @providesModule objMapKeyVal
13031 */
13032
13033"use strict";
13034
13035/**
13036 * Behaves the same as `objMap` but invokes func with the key first, and value
13037 * second. Use `objMap` unless you need this special case.
13038 * Invokes func as:
13039 *
13040 * func(key, value, iteration)
13041 *
13042 * @param {?object} obj Object to map keys over
13043 * @param {!function} func Invoked for each key/val pair.
13044 * @param {?*} context
13045 * @return {?object} Result of mapping or null if obj is falsey
13046 */
13047function objMapKeyVal(obj, func, context) {
13048 if (!obj) {
13049 return null;
13050 }
13051 var i = 0;
13052 var ret = {};
13053 for (var key in obj) {
13054 if (obj.hasOwnProperty(key)) {
13055 ret[key] = func.call(context, key, obj[key], i++);
13056 }
13057 }
13058 return ret;
13059}
13060
13061module.exports = objMapKeyVal;
13062
13063},{}],102:[function(require,module,exports){
13064/**
13065 * Copyright 2013 Facebook, Inc.
13066 *
13067 * Licensed under the Apache License, Version 2.0 (the "License");
13068 * you may not use this file except in compliance with the License.
13069 * You may obtain a copy of the License at
13070 *
13071 * http://www.apache.org/licenses/LICENSE-2.0
13072 *
13073 * Unless required by applicable law or agreed to in writing, software
13074 * distributed under the License is distributed on an "AS IS" BASIS,
13075 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13076 * See the License for the specific language governing permissions and
13077 * limitations under the License.
13078 *
13079 * @providesModule performanceNow
13080 * @typechecks static-only
13081 */
13082
13083"use strict";
13084
13085var ExecutionEnvironment = require("./ExecutionEnvironment");
13086
13087/**
13088 * Detect if we can use window.performance.now() and gracefully
13089 * fallback to Date.now() if it doesn't exist.
13090 * We need to support Firefox < 15 for now due to Facebook's webdriver
13091 * infrastructure.
13092 */
13093var performance = null;
13094
13095if (ExecutionEnvironment.canUseDOM) {
13096 performance = window.performance || window.webkitPerformance;
13097}
13098
13099if (!performance || !performance.now) {
13100 performance = Date;
13101}
13102
13103var performanceNow = performance.now.bind(performance);
13104
13105module.exports = performanceNow;
13106
13107},{"./ExecutionEnvironment":19}],103:[function(require,module,exports){
13108/**
13109 * Copyright 2013 Facebook, Inc.
13110 *
13111 * Licensed under the Apache License, Version 2.0 (the "License");
13112 * you may not use this file except in compliance with the License.
13113 * You may obtain a copy of the License at
13114 *
13115 * http://www.apache.org/licenses/LICENSE-2.0
13116 *
13117 * Unless required by applicable law or agreed to in writing, software
13118 * distributed under the License is distributed on an "AS IS" BASIS,
13119 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13120 * See the License for the specific language governing permissions and
13121 * limitations under the License.
13122 *
13123 * @providesModule traverseAllChildren
13124 */
13125
13126"use strict";
13127
13128var ReactComponent = require("./ReactComponent");
13129var ReactTextComponent = require("./ReactTextComponent");
13130
13131var invariant = require("./invariant");
13132
13133/**
13134 * TODO: Test that:
13135 * 1. `mapChildren` transforms strings and numbers into `ReactTextComponent`.
13136 * 2. it('should fail when supplied duplicate key', function() {
13137 * 3. That a single child and an array with one item have the same key pattern.
13138 * });
13139 */
13140
13141/**
13142 * @param {?*} children Children tree container.
13143 * @param {!string} nameSoFar Name of the key path so far.
13144 * @param {!number} indexSoFar Number of children encountered until this point.
13145 * @param {!function} callback Callback to invoke with each child found.
13146 * @param {?*} traverseContext Used to pass information throughout the traversal
13147 * process.
13148 * @return {!number} The number of children in this subtree.
13149 */
13150var traverseAllChildrenImpl =
13151 function(children, nameSoFar, indexSoFar, callback, traverseContext) {
13152 var subtreeCount = 0; // Count of children found in the current subtree.
13153 if (Array.isArray(children)) {
13154 for (var i = 0; i < children.length; i++) {
13155 var child = children[i];
13156 var nextName = nameSoFar + ReactComponent.getKey(child, i);
13157 var nextIndex = indexSoFar + subtreeCount;
13158 subtreeCount += traverseAllChildrenImpl(
13159 child,
13160 nextName,
13161 nextIndex,
13162 callback,
13163 traverseContext
13164 );
13165 }
13166 } else {
13167 var type = typeof children;
13168 var isOnlyChild = nameSoFar === '';
13169 // If it's the only child, treat the name as if it was wrapped in an array
13170 // so that it's consistent if the number of children grows
13171 var storageName = isOnlyChild ?
13172 ReactComponent.getKey(children, 0):
13173 nameSoFar;
13174 if (children === null || children === undefined || type === 'boolean') {
13175 // All of the above are perceived as null.
13176 callback(traverseContext, null, storageName, indexSoFar);
13177 subtreeCount = 1;
13178 } else if (children.mountComponentIntoNode) {
13179 callback(traverseContext, children, storageName, indexSoFar);
13180 subtreeCount = 1;
13181 } else {
13182 if (type === 'object') {
13183 invariant(
13184 !children || children.nodeType !== 1,
13185 'traverseAllChildren(...): Encountered an invalid child; DOM ' +
13186 'elements are not valid children of React components.'
13187 );
13188 for (var key in children) {
13189 if (children.hasOwnProperty(key)) {
13190 subtreeCount += traverseAllChildrenImpl(
13191 children[key],
13192 nameSoFar + '{' + key + '}',
13193 indexSoFar + subtreeCount,
13194 callback,
13195 traverseContext
13196 );
13197 }
13198 }
13199 } else if (type === 'string') {
13200 var normalizedText = new ReactTextComponent(children);
13201 callback(traverseContext, normalizedText, storageName, indexSoFar);
13202 subtreeCount += 1;
13203 } else if (type === 'number') {
13204 var normalizedNumber = new ReactTextComponent('' + children);
13205 callback(traverseContext, normalizedNumber, storageName, indexSoFar);
13206 subtreeCount += 1;
13207 }
13208 }
13209 }
13210 return subtreeCount;
13211 };
13212
13213/**
13214 * Traverses children that are typically specified as `props.children`, but
13215 * might also be specified through attributes:
13216 *
13217 * - `traverseAllChildren(this.props.children, ...)`
13218 * - `traverseAllChildren(this.props.leftPanelChildren, ...)`
13219 *
13220 * The `traverseContext` is an optional argument that is passed through the
13221 * entire traversal. It can be used to store accumulations or anything else that
13222 * the callback might find relevant.
13223 *
13224 * @param {?*} children Children tree object.
13225 * @param {!function} callback To invoke upon traversing each child.
13226 * @param {?*} traverseContext Context for traversal.
13227 */
13228function traverseAllChildren(children, callback, traverseContext) {
13229 if (children !== null && children !== undefined) {
13230 traverseAllChildrenImpl(children, '', 0, callback, traverseContext);
13231 }
13232}
13233
13234module.exports = traverseAllChildren;
13235
13236},{"./ReactComponent":23,"./ReactTextComponent":56,"./invariant":89}]},{},[22])
13237(22)
13238});
13239; \ No newline at end of file