summaryrefslogtreecommitdiff
path: root/frontend/delta/js/React/react-0.5.0-alpha.js
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2013-10-02 07:59:30 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2013-10-02 07:59:30 (UTC)
commit1180b7b195157aaeb4f0d5380e0c886bbd06c2e2 (patch) (unidiff)
tree709e33a09d9325d382aabaf0a0828e20ebdb96db /frontend/delta/js/React/react-0.5.0-alpha.js
parent20bea94ab6b91c85b171dcf86baba0a64169d508 (diff)
downloadclipperz-1180b7b195157aaeb4f0d5380e0c886bbd06c2e2.zip
clipperz-1180b7b195157aaeb4f0d5380e0c886bbd06c2e2.tar.gz
clipperz-1180b7b195157aaeb4f0d5380e0c886bbd06c2e2.tar.bz2
Updated /delta
Switched from less to scss. Still no build script to update the final CSS, though. Added preliminary support for storing account data on browser's local storage for offline viewing. No public backend currently support this feature.
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