github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/third_party/react/react-with-addons.js (about) 1 /** 2 * React (with addons) v0.10.0 3 */ 4 !function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.React=e()}}(function(){var define,module,exports;return (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(_dereq_,module,exports){ 5 /** 6 * Copyright 2013-2014 Facebook, Inc. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 * @providesModule AutoFocusMixin 21 * @typechecks static-only 22 */ 23 24 "use strict"; 25 26 var focusNode = _dereq_("./focusNode"); 27 28 var AutoFocusMixin = { 29 componentDidMount: function() { 30 if (this.props.autoFocus) { 31 focusNode(this.getDOMNode()); 32 } 33 } 34 }; 35 36 module.exports = AutoFocusMixin; 37 38 },{"./focusNode":113}],2:[function(_dereq_,module,exports){ 39 /** 40 * Copyright 2013-2014 Facebook, Inc. 41 * 42 * Licensed under the Apache License, Version 2.0 (the "License"); 43 * you may not use this file except in compliance with the License. 44 * You may obtain a copy of the License at 45 * 46 * http://www.apache.org/licenses/LICENSE-2.0 47 * 48 * Unless required by applicable law or agreed to in writing, software 49 * distributed under the License is distributed on an "AS IS" BASIS, 50 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 51 * See the License for the specific language governing permissions and 52 * limitations under the License. 53 * 54 * @providesModule CSSCore 55 * @typechecks 56 */ 57 58 var invariant = _dereq_("./invariant"); 59 60 /** 61 * The CSSCore module specifies the API (and implements most of the methods) 62 * that should be used when dealing with the display of elements (via their 63 * CSS classes and visibility on screen. It is an API focused on mutating the 64 * display and not reading it as no logical state should be encoded in the 65 * display of elements. 66 */ 67 68 var CSSCore = { 69 70 /** 71 * Adds the class passed in to the element if it doesn't already have it. 72 * 73 * @param {DOMElement} element the element to set the class on 74 * @param {string} className the CSS className 75 * @return {DOMElement} the element passed in 76 */ 77 addClass: function(element, className) { 78 ("production" !== "development" ? invariant( 79 !/\s/.test(className), 80 'CSSCore.addClass takes only a single class name. "%s" contains ' + 81 'multiple classes.', className 82 ) : invariant(!/\s/.test(className))); 83 84 if (className) { 85 if (element.classList) { 86 element.classList.add(className); 87 } else if (!CSSCore.hasClass(element, className)) { 88 element.className = element.className + ' ' + className; 89 } 90 } 91 return element; 92 }, 93 94 /** 95 * Removes the class passed in from the element 96 * 97 * @param {DOMElement} element the element to set the class on 98 * @param {string} className the CSS className 99 * @return {DOMElement} the element passed in 100 */ 101 removeClass: function(element, className) { 102 ("production" !== "development" ? invariant( 103 !/\s/.test(className), 104 'CSSCore.removeClass takes only a single class name. "%s" contains ' + 105 'multiple classes.', className 106 ) : invariant(!/\s/.test(className))); 107 108 if (className) { 109 if (element.classList) { 110 element.classList.remove(className); 111 } else if (CSSCore.hasClass(element, className)) { 112 element.className = element.className 113 .replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), '$1') 114 .replace(/\s+/g, ' ') // multiple spaces to one 115 .replace(/^\s*|\s*$/g, ''); // trim the ends 116 } 117 } 118 return element; 119 }, 120 121 /** 122 * Helper to add or remove a class from an element based on a condition. 123 * 124 * @param {DOMElement} element the element to set the class on 125 * @param {string} className the CSS className 126 * @param {*} bool condition to whether to add or remove the class 127 * @return {DOMElement} the element passed in 128 */ 129 conditionClass: function(element, className, bool) { 130 return (bool ? CSSCore.addClass : CSSCore.removeClass)(element, className); 131 }, 132 133 /** 134 * Tests whether the element has the class specified. 135 * 136 * @param {DOMNode|DOMWindow} element the element to set the class on 137 * @param {string} className the CSS className 138 * @returns {boolean} true if the element has the class, false if not 139 */ 140 hasClass: function(element, className) { 141 ("production" !== "development" ? invariant( 142 !/\s/.test(className), 143 'CSS.hasClass takes only a single class name.' 144 ) : invariant(!/\s/.test(className))); 145 if (element.classList) { 146 return !!className && element.classList.contains(className); 147 } 148 return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1; 149 } 150 151 }; 152 153 module.exports = CSSCore; 154 155 },{"./invariant":125}],3:[function(_dereq_,module,exports){ 156 /** 157 * Copyright 2013-2014 Facebook, Inc. 158 * 159 * Licensed under the Apache License, Version 2.0 (the "License"); 160 * you may not use this file except in compliance with the License. 161 * You may obtain a copy of the License at 162 * 163 * http://www.apache.org/licenses/LICENSE-2.0 164 * 165 * Unless required by applicable law or agreed to in writing, software 166 * distributed under the License is distributed on an "AS IS" BASIS, 167 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 168 * See the License for the specific language governing permissions and 169 * limitations under the License. 170 * 171 * @providesModule CSSProperty 172 */ 173 174 "use strict"; 175 176 /** 177 * CSS properties which accept numbers but are not in units of "px". 178 */ 179 var isUnitlessNumber = { 180 columnCount: true, 181 fillOpacity: true, 182 flex: true, 183 flexGrow: true, 184 flexShrink: true, 185 fontWeight: true, 186 lineClamp: true, 187 lineHeight: true, 188 opacity: true, 189 order: true, 190 orphans: true, 191 widows: true, 192 zIndex: true, 193 zoom: true 194 }; 195 196 /** 197 * @param {string} prefix vendor-specific prefix, eg: Webkit 198 * @param {string} key style name, eg: transitionDuration 199 * @return {string} style name prefixed with `prefix`, properly camelCased, eg: 200 * WebkitTransitionDuration 201 */ 202 function prefixKey(prefix, key) { 203 return prefix + key.charAt(0).toUpperCase() + key.substring(1); 204 } 205 206 /** 207 * Support style names that may come passed in prefixed by adding permutations 208 * of vendor prefixes. 209 */ 210 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; 211 212 // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an 213 // infinite loop, because it iterates over the newly added props too. 214 Object.keys(isUnitlessNumber).forEach(function(prop) { 215 prefixes.forEach(function(prefix) { 216 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; 217 }); 218 }); 219 220 /** 221 * Most style properties can be unset by doing .style[prop] = '' but IE8 222 * doesn't like doing that with shorthand properties so for the properties that 223 * IE8 breaks on, which are listed here, we instead unset each of the 224 * individual properties. See http://bugs.jquery.com/ticket/12385. 225 * The 4-value 'clock' properties like margin, padding, border-width seem to 226 * behave without any problems. Curiously, list-style works too without any 227 * special prodding. 228 */ 229 var shorthandPropertyExpansions = { 230 background: { 231 backgroundImage: true, 232 backgroundPosition: true, 233 backgroundRepeat: true, 234 backgroundColor: true 235 }, 236 border: { 237 borderWidth: true, 238 borderStyle: true, 239 borderColor: true 240 }, 241 borderBottom: { 242 borderBottomWidth: true, 243 borderBottomStyle: true, 244 borderBottomColor: true 245 }, 246 borderLeft: { 247 borderLeftWidth: true, 248 borderLeftStyle: true, 249 borderLeftColor: true 250 }, 251 borderRight: { 252 borderRightWidth: true, 253 borderRightStyle: true, 254 borderRightColor: true 255 }, 256 borderTop: { 257 borderTopWidth: true, 258 borderTopStyle: true, 259 borderTopColor: true 260 }, 261 font: { 262 fontStyle: true, 263 fontVariant: true, 264 fontWeight: true, 265 fontSize: true, 266 lineHeight: true, 267 fontFamily: true 268 } 269 }; 270 271 var CSSProperty = { 272 isUnitlessNumber: isUnitlessNumber, 273 shorthandPropertyExpansions: shorthandPropertyExpansions 274 }; 275 276 module.exports = CSSProperty; 277 278 },{}],4:[function(_dereq_,module,exports){ 279 /** 280 * Copyright 2013-2014 Facebook, Inc. 281 * 282 * Licensed under the Apache License, Version 2.0 (the "License"); 283 * you may not use this file except in compliance with the License. 284 * You may obtain a copy of the License at 285 * 286 * http://www.apache.org/licenses/LICENSE-2.0 287 * 288 * Unless required by applicable law or agreed to in writing, software 289 * distributed under the License is distributed on an "AS IS" BASIS, 290 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 291 * See the License for the specific language governing permissions and 292 * limitations under the License. 293 * 294 * @providesModule CSSPropertyOperations 295 * @typechecks static-only 296 */ 297 298 "use strict"; 299 300 var CSSProperty = _dereq_("./CSSProperty"); 301 302 var dangerousStyleValue = _dereq_("./dangerousStyleValue"); 303 var escapeTextForBrowser = _dereq_("./escapeTextForBrowser"); 304 var hyphenate = _dereq_("./hyphenate"); 305 var memoizeStringOnly = _dereq_("./memoizeStringOnly"); 306 307 var processStyleName = memoizeStringOnly(function(styleName) { 308 return escapeTextForBrowser(hyphenate(styleName)); 309 }); 310 311 /** 312 * Operations for dealing with CSS properties. 313 */ 314 var CSSPropertyOperations = { 315 316 /** 317 * Serializes a mapping of style properties for use as inline styles: 318 * 319 * > createMarkupForStyles({width: '200px', height: 0}) 320 * "width:200px;height:0;" 321 * 322 * Undefined values are ignored so that declarative programming is easier. 323 * 324 * @param {object} styles 325 * @return {?string} 326 */ 327 createMarkupForStyles: function(styles) { 328 var serialized = ''; 329 for (var styleName in styles) { 330 if (!styles.hasOwnProperty(styleName)) { 331 continue; 332 } 333 var styleValue = styles[styleName]; 334 if (styleValue != null) { 335 serialized += processStyleName(styleName) + ':'; 336 serialized += dangerousStyleValue(styleName, styleValue) + ';'; 337 } 338 } 339 return serialized || null; 340 }, 341 342 /** 343 * Sets the value for multiple styles on a node. If a value is specified as 344 * '' (empty string), the corresponding style property will be unset. 345 * 346 * @param {DOMElement} node 347 * @param {object} styles 348 */ 349 setValueForStyles: function(node, styles) { 350 var style = node.style; 351 for (var styleName in styles) { 352 if (!styles.hasOwnProperty(styleName)) { 353 continue; 354 } 355 var styleValue = dangerousStyleValue(styleName, styles[styleName]); 356 if (styleValue) { 357 style[styleName] = styleValue; 358 } else { 359 var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; 360 if (expansion) { 361 // Shorthand property that IE8 won't like unsetting, so unset each 362 // component to placate it 363 for (var individualStyleName in expansion) { 364 style[individualStyleName] = ''; 365 } 366 } else { 367 style[styleName] = ''; 368 } 369 } 370 } 371 } 372 373 }; 374 375 module.exports = CSSPropertyOperations; 376 377 },{"./CSSProperty":3,"./dangerousStyleValue":108,"./escapeTextForBrowser":111,"./hyphenate":123,"./memoizeStringOnly":133}],5:[function(_dereq_,module,exports){ 378 /** 379 * Copyright 2013-2014 Facebook, Inc. 380 * 381 * Licensed under the Apache License, Version 2.0 (the "License"); 382 * you may not use this file except in compliance with the License. 383 * You may obtain a copy of the License at 384 * 385 * http://www.apache.org/licenses/LICENSE-2.0 386 * 387 * Unless required by applicable law or agreed to in writing, software 388 * distributed under the License is distributed on an "AS IS" BASIS, 389 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 390 * See the License for the specific language governing permissions and 391 * limitations under the License. 392 * 393 * @providesModule ChangeEventPlugin 394 */ 395 396 "use strict"; 397 398 var EventConstants = _dereq_("./EventConstants"); 399 var EventPluginHub = _dereq_("./EventPluginHub"); 400 var EventPropagators = _dereq_("./EventPropagators"); 401 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 402 var ReactUpdates = _dereq_("./ReactUpdates"); 403 var SyntheticEvent = _dereq_("./SyntheticEvent"); 404 405 var isEventSupported = _dereq_("./isEventSupported"); 406 var isTextInputElement = _dereq_("./isTextInputElement"); 407 var keyOf = _dereq_("./keyOf"); 408 409 var topLevelTypes = EventConstants.topLevelTypes; 410 411 var eventTypes = { 412 change: { 413 phasedRegistrationNames: { 414 bubbled: keyOf({onChange: null}), 415 captured: keyOf({onChangeCapture: null}) 416 }, 417 dependencies: [ 418 topLevelTypes.topBlur, 419 topLevelTypes.topChange, 420 topLevelTypes.topClick, 421 topLevelTypes.topFocus, 422 topLevelTypes.topInput, 423 topLevelTypes.topKeyDown, 424 topLevelTypes.topKeyUp, 425 topLevelTypes.topSelectionChange 426 ] 427 } 428 }; 429 430 /** 431 * For IE shims 432 */ 433 var activeElement = null; 434 var activeElementID = null; 435 var activeElementValue = null; 436 var activeElementValueProp = null; 437 438 /** 439 * SECTION: handle `change` event 440 */ 441 function shouldUseChangeEvent(elem) { 442 return ( 443 elem.nodeName === 'SELECT' || 444 (elem.nodeName === 'INPUT' && elem.type === 'file') 445 ); 446 } 447 448 var doesChangeEventBubble = false; 449 if (ExecutionEnvironment.canUseDOM) { 450 // See `handleChange` comment below 451 doesChangeEventBubble = isEventSupported('change') && ( 452 !('documentMode' in document) || document.documentMode > 8 453 ); 454 } 455 456 function manualDispatchChangeEvent(nativeEvent) { 457 var event = SyntheticEvent.getPooled( 458 eventTypes.change, 459 activeElementID, 460 nativeEvent 461 ); 462 EventPropagators.accumulateTwoPhaseDispatches(event); 463 464 // If change and propertychange bubbled, we'd just bind to it like all the 465 // other events and have it go through ReactEventTopLevelCallback. Since it 466 // doesn't, we manually listen for the events and so we have to enqueue and 467 // process the abstract event manually. 468 // 469 // Batching is necessary here in order to ensure that all event handlers run 470 // before the next rerender (including event handlers attached to ancestor 471 // elements instead of directly on the input). Without this, controlled 472 // components don't work properly in conjunction with event bubbling because 473 // the component is rerendered and the value reverted before all the event 474 // handlers can run. See https://github.com/facebook/react/issues/708. 475 ReactUpdates.batchedUpdates(runEventInBatch, event); 476 } 477 478 function runEventInBatch(event) { 479 EventPluginHub.enqueueEvents(event); 480 EventPluginHub.processEventQueue(); 481 } 482 483 function startWatchingForChangeEventIE8(target, targetID) { 484 activeElement = target; 485 activeElementID = targetID; 486 activeElement.attachEvent('onchange', manualDispatchChangeEvent); 487 } 488 489 function stopWatchingForChangeEventIE8() { 490 if (!activeElement) { 491 return; 492 } 493 activeElement.detachEvent('onchange', manualDispatchChangeEvent); 494 activeElement = null; 495 activeElementID = null; 496 } 497 498 function getTargetIDForChangeEvent( 499 topLevelType, 500 topLevelTarget, 501 topLevelTargetID) { 502 if (topLevelType === topLevelTypes.topChange) { 503 return topLevelTargetID; 504 } 505 } 506 function handleEventsForChangeEventIE8( 507 topLevelType, 508 topLevelTarget, 509 topLevelTargetID) { 510 if (topLevelType === topLevelTypes.topFocus) { 511 // stopWatching() should be a noop here but we call it just in case we 512 // missed a blur event somehow. 513 stopWatchingForChangeEventIE8(); 514 startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); 515 } else if (topLevelType === topLevelTypes.topBlur) { 516 stopWatchingForChangeEventIE8(); 517 } 518 } 519 520 521 /** 522 * SECTION: handle `input` event 523 */ 524 var isInputEventSupported = false; 525 if (ExecutionEnvironment.canUseDOM) { 526 // IE9 claims to support the input event but fails to trigger it when 527 // deleting text, so we ignore its input events 528 isInputEventSupported = isEventSupported('input') && ( 529 !('documentMode' in document) || document.documentMode > 9 530 ); 531 } 532 533 /** 534 * (For old IE.) Replacement getter/setter for the `value` property that gets 535 * set on the active element. 536 */ 537 var newValueProp = { 538 get: function() { 539 return activeElementValueProp.get.call(this); 540 }, 541 set: function(val) { 542 // Cast to a string so we can do equality checks. 543 activeElementValue = '' + val; 544 activeElementValueProp.set.call(this, val); 545 } 546 }; 547 548 /** 549 * (For old IE.) Starts tracking propertychange events on the passed-in element 550 * and override the value property so that we can distinguish user events from 551 * value changes in JS. 552 */ 553 function startWatchingForValueChange(target, targetID) { 554 activeElement = target; 555 activeElementID = targetID; 556 activeElementValue = target.value; 557 activeElementValueProp = Object.getOwnPropertyDescriptor( 558 target.constructor.prototype, 559 'value' 560 ); 561 562 Object.defineProperty(activeElement, 'value', newValueProp); 563 activeElement.attachEvent('onpropertychange', handlePropertyChange); 564 } 565 566 /** 567 * (For old IE.) Removes the event listeners from the currently-tracked element, 568 * if any exists. 569 */ 570 function stopWatchingForValueChange() { 571 if (!activeElement) { 572 return; 573 } 574 575 // delete restores the original property definition 576 delete activeElement.value; 577 activeElement.detachEvent('onpropertychange', handlePropertyChange); 578 579 activeElement = null; 580 activeElementID = null; 581 activeElementValue = null; 582 activeElementValueProp = null; 583 } 584 585 /** 586 * (For old IE.) Handles a propertychange event, sending a `change` event if 587 * the value of the active element has changed. 588 */ 589 function handlePropertyChange(nativeEvent) { 590 if (nativeEvent.propertyName !== 'value') { 591 return; 592 } 593 var value = nativeEvent.srcElement.value; 594 if (value === activeElementValue) { 595 return; 596 } 597 activeElementValue = value; 598 599 manualDispatchChangeEvent(nativeEvent); 600 } 601 602 /** 603 * If a `change` event should be fired, returns the target's ID. 604 */ 605 function getTargetIDForInputEvent( 606 topLevelType, 607 topLevelTarget, 608 topLevelTargetID) { 609 if (topLevelType === topLevelTypes.topInput) { 610 // In modern browsers (i.e., not IE8 or IE9), the input event is exactly 611 // what we want so fall through here and trigger an abstract event 612 return topLevelTargetID; 613 } 614 } 615 616 // For IE8 and IE9. 617 function handleEventsForInputEventIE( 618 topLevelType, 619 topLevelTarget, 620 topLevelTargetID) { 621 if (topLevelType === topLevelTypes.topFocus) { 622 // In IE8, we can capture almost all .value changes by adding a 623 // propertychange handler and looking for events with propertyName 624 // equal to 'value' 625 // In IE9, propertychange fires for most input events but is buggy and 626 // doesn't fire when text is deleted, but conveniently, selectionchange 627 // appears to fire in all of the remaining cases so we catch those and 628 // forward the event if the value has changed 629 // In either case, we don't want to call the event handler if the value 630 // is changed from JS so we redefine a setter for `.value` that updates 631 // our activeElementValue variable, allowing us to ignore those changes 632 // 633 // stopWatching() should be a noop here but we call it just in case we 634 // missed a blur event somehow. 635 stopWatchingForValueChange(); 636 startWatchingForValueChange(topLevelTarget, topLevelTargetID); 637 } else if (topLevelType === topLevelTypes.topBlur) { 638 stopWatchingForValueChange(); 639 } 640 } 641 642 // For IE8 and IE9. 643 function getTargetIDForInputEventIE( 644 topLevelType, 645 topLevelTarget, 646 topLevelTargetID) { 647 if (topLevelType === topLevelTypes.topSelectionChange || 648 topLevelType === topLevelTypes.topKeyUp || 649 topLevelType === topLevelTypes.topKeyDown) { 650 // On the selectionchange event, the target is just document which isn't 651 // helpful for us so just check activeElement instead. 652 // 653 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire 654 // propertychange on the first input event after setting `value` from a 655 // script and fires only keydown, keypress, keyup. Catching keyup usually 656 // gets it and catching keydown lets us fire an event for the first 657 // keystroke if user does a key repeat (it'll be a little delayed: right 658 // before the second keystroke). Other input methods (e.g., paste) seem to 659 // fire selectionchange normally. 660 if (activeElement && activeElement.value !== activeElementValue) { 661 activeElementValue = activeElement.value; 662 return activeElementID; 663 } 664 } 665 } 666 667 668 /** 669 * SECTION: handle `click` event 670 */ 671 function shouldUseClickEvent(elem) { 672 // Use the `click` event to detect changes to checkbox and radio inputs. 673 // This approach works across all browsers, whereas `change` does not fire 674 // until `blur` in IE8. 675 return ( 676 elem.nodeName === 'INPUT' && 677 (elem.type === 'checkbox' || elem.type === 'radio') 678 ); 679 } 680 681 function getTargetIDForClickEvent( 682 topLevelType, 683 topLevelTarget, 684 topLevelTargetID) { 685 if (topLevelType === topLevelTypes.topClick) { 686 return topLevelTargetID; 687 } 688 } 689 690 /** 691 * This plugin creates an `onChange` event that normalizes change events 692 * across form elements. This event fires at a time when it's possible to 693 * change the element's value without seeing a flicker. 694 * 695 * Supported elements are: 696 * - input (see `isTextInputElement`) 697 * - textarea 698 * - select 699 */ 700 var ChangeEventPlugin = { 701 702 eventTypes: eventTypes, 703 704 /** 705 * @param {string} topLevelType Record from `EventConstants`. 706 * @param {DOMEventTarget} topLevelTarget The listening component root node. 707 * @param {string} topLevelTargetID ID of `topLevelTarget`. 708 * @param {object} nativeEvent Native browser event. 709 * @return {*} An accumulation of synthetic events. 710 * @see {EventPluginHub.extractEvents} 711 */ 712 extractEvents: function( 713 topLevelType, 714 topLevelTarget, 715 topLevelTargetID, 716 nativeEvent) { 717 718 var getTargetIDFunc, handleEventFunc; 719 if (shouldUseChangeEvent(topLevelTarget)) { 720 if (doesChangeEventBubble) { 721 getTargetIDFunc = getTargetIDForChangeEvent; 722 } else { 723 handleEventFunc = handleEventsForChangeEventIE8; 724 } 725 } else if (isTextInputElement(topLevelTarget)) { 726 if (isInputEventSupported) { 727 getTargetIDFunc = getTargetIDForInputEvent; 728 } else { 729 getTargetIDFunc = getTargetIDForInputEventIE; 730 handleEventFunc = handleEventsForInputEventIE; 731 } 732 } else if (shouldUseClickEvent(topLevelTarget)) { 733 getTargetIDFunc = getTargetIDForClickEvent; 734 } 735 736 if (getTargetIDFunc) { 737 var targetID = getTargetIDFunc( 738 topLevelType, 739 topLevelTarget, 740 topLevelTargetID 741 ); 742 if (targetID) { 743 var event = SyntheticEvent.getPooled( 744 eventTypes.change, 745 targetID, 746 nativeEvent 747 ); 748 EventPropagators.accumulateTwoPhaseDispatches(event); 749 return event; 750 } 751 } 752 753 if (handleEventFunc) { 754 handleEventFunc( 755 topLevelType, 756 topLevelTarget, 757 topLevelTargetID 758 ); 759 } 760 } 761 762 }; 763 764 module.exports = ChangeEventPlugin; 765 766 },{"./EventConstants":15,"./EventPluginHub":17,"./EventPropagators":20,"./ExecutionEnvironment":21,"./ReactUpdates":81,"./SyntheticEvent":89,"./isEventSupported":126,"./isTextInputElement":128,"./keyOf":132}],6:[function(_dereq_,module,exports){ 767 /** 768 * Copyright 2013-2014 Facebook, Inc. 769 * 770 * Licensed under the Apache License, Version 2.0 (the "License"); 771 * you may not use this file except in compliance with the License. 772 * You may obtain a copy of the License at 773 * 774 * http://www.apache.org/licenses/LICENSE-2.0 775 * 776 * Unless required by applicable law or agreed to in writing, software 777 * distributed under the License is distributed on an "AS IS" BASIS, 778 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 779 * See the License for the specific language governing permissions and 780 * limitations under the License. 781 * 782 * @providesModule ClientReactRootIndex 783 * @typechecks 784 */ 785 786 "use strict"; 787 788 var nextReactRootIndex = 0; 789 790 var ClientReactRootIndex = { 791 createReactRootIndex: function() { 792 return nextReactRootIndex++; 793 } 794 }; 795 796 module.exports = ClientReactRootIndex; 797 798 },{}],7:[function(_dereq_,module,exports){ 799 /** 800 * Copyright 2013-2014 Facebook, Inc. 801 * 802 * Licensed under the Apache License, Version 2.0 (the "License"); 803 * you may not use this file except in compliance with the License. 804 * You may obtain a copy of the License at 805 * 806 * http://www.apache.org/licenses/LICENSE-2.0 807 * 808 * Unless required by applicable law or agreed to in writing, software 809 * distributed under the License is distributed on an "AS IS" BASIS, 810 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 811 * See the License for the specific language governing permissions and 812 * limitations under the License. 813 * 814 * @providesModule CompositionEventPlugin 815 * @typechecks static-only 816 */ 817 818 "use strict"; 819 820 var EventConstants = _dereq_("./EventConstants"); 821 var EventPropagators = _dereq_("./EventPropagators"); 822 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 823 var ReactInputSelection = _dereq_("./ReactInputSelection"); 824 var SyntheticCompositionEvent = _dereq_("./SyntheticCompositionEvent"); 825 826 var getTextContentAccessor = _dereq_("./getTextContentAccessor"); 827 var keyOf = _dereq_("./keyOf"); 828 829 var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space 830 var START_KEYCODE = 229; 831 832 var useCompositionEvent = ( 833 ExecutionEnvironment.canUseDOM && 834 'CompositionEvent' in window 835 ); 836 837 // In IE9+, we have access to composition events, but the data supplied 838 // by the native compositionend event may be incorrect. In Korean, for example, 839 // the compositionend event contains only one character regardless of 840 // how many characters have been composed since compositionstart. 841 // We therefore use the fallback data while still using the native 842 // events as triggers. 843 var useFallbackData = ( 844 !useCompositionEvent || 845 'documentMode' in document && document.documentMode > 8 846 ); 847 848 var topLevelTypes = EventConstants.topLevelTypes; 849 var currentComposition = null; 850 851 // Events and their corresponding property names. 852 var eventTypes = { 853 compositionEnd: { 854 phasedRegistrationNames: { 855 bubbled: keyOf({onCompositionEnd: null}), 856 captured: keyOf({onCompositionEndCapture: null}) 857 }, 858 dependencies: [ 859 topLevelTypes.topBlur, 860 topLevelTypes.topCompositionEnd, 861 topLevelTypes.topKeyDown, 862 topLevelTypes.topKeyPress, 863 topLevelTypes.topKeyUp, 864 topLevelTypes.topMouseDown 865 ] 866 }, 867 compositionStart: { 868 phasedRegistrationNames: { 869 bubbled: keyOf({onCompositionStart: null}), 870 captured: keyOf({onCompositionStartCapture: null}) 871 }, 872 dependencies: [ 873 topLevelTypes.topBlur, 874 topLevelTypes.topCompositionStart, 875 topLevelTypes.topKeyDown, 876 topLevelTypes.topKeyPress, 877 topLevelTypes.topKeyUp, 878 topLevelTypes.topMouseDown 879 ] 880 }, 881 compositionUpdate: { 882 phasedRegistrationNames: { 883 bubbled: keyOf({onCompositionUpdate: null}), 884 captured: keyOf({onCompositionUpdateCapture: null}) 885 }, 886 dependencies: [ 887 topLevelTypes.topBlur, 888 topLevelTypes.topCompositionUpdate, 889 topLevelTypes.topKeyDown, 890 topLevelTypes.topKeyPress, 891 topLevelTypes.topKeyUp, 892 topLevelTypes.topMouseDown 893 ] 894 } 895 }; 896 897 /** 898 * Translate native top level events into event types. 899 * 900 * @param {string} topLevelType 901 * @return {object} 902 */ 903 function getCompositionEventType(topLevelType) { 904 switch (topLevelType) { 905 case topLevelTypes.topCompositionStart: 906 return eventTypes.compositionStart; 907 case topLevelTypes.topCompositionEnd: 908 return eventTypes.compositionEnd; 909 case topLevelTypes.topCompositionUpdate: 910 return eventTypes.compositionUpdate; 911 } 912 } 913 914 /** 915 * Does our fallback best-guess model think this event signifies that 916 * composition has begun? 917 * 918 * @param {string} topLevelType 919 * @param {object} nativeEvent 920 * @return {boolean} 921 */ 922 function isFallbackStart(topLevelType, nativeEvent) { 923 return ( 924 topLevelType === topLevelTypes.topKeyDown && 925 nativeEvent.keyCode === START_KEYCODE 926 ); 927 } 928 929 /** 930 * Does our fallback mode think that this event is the end of composition? 931 * 932 * @param {string} topLevelType 933 * @param {object} nativeEvent 934 * @return {boolean} 935 */ 936 function isFallbackEnd(topLevelType, nativeEvent) { 937 switch (topLevelType) { 938 case topLevelTypes.topKeyUp: 939 // Command keys insert or clear IME input. 940 return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); 941 case topLevelTypes.topKeyDown: 942 // Expect IME keyCode on each keydown. If we get any other 943 // code we must have exited earlier. 944 return (nativeEvent.keyCode !== START_KEYCODE); 945 case topLevelTypes.topKeyPress: 946 case topLevelTypes.topMouseDown: 947 case topLevelTypes.topBlur: 948 // Events are not possible without cancelling IME. 949 return true; 950 default: 951 return false; 952 } 953 } 954 955 /** 956 * Helper class stores information about selection and document state 957 * so we can figure out what changed at a later date. 958 * 959 * @param {DOMEventTarget} root 960 */ 961 function FallbackCompositionState(root) { 962 this.root = root; 963 this.startSelection = ReactInputSelection.getSelection(root); 964 this.startValue = this.getText(); 965 } 966 967 /** 968 * Get current text of input. 969 * 970 * @return {string} 971 */ 972 FallbackCompositionState.prototype.getText = function() { 973 return this.root.value || this.root[getTextContentAccessor()]; 974 }; 975 976 /** 977 * Text that has changed since the start of composition. 978 * 979 * @return {string} 980 */ 981 FallbackCompositionState.prototype.getData = function() { 982 var endValue = this.getText(); 983 var prefixLength = this.startSelection.start; 984 var suffixLength = this.startValue.length - this.startSelection.end; 985 986 return endValue.substr( 987 prefixLength, 988 endValue.length - suffixLength - prefixLength 989 ); 990 }; 991 992 /** 993 * This plugin creates `onCompositionStart`, `onCompositionUpdate` and 994 * `onCompositionEnd` events on inputs, textareas and contentEditable 995 * nodes. 996 */ 997 var CompositionEventPlugin = { 998 999 eventTypes: eventTypes, 1000 1001 /** 1002 * @param {string} topLevelType Record from `EventConstants`. 1003 * @param {DOMEventTarget} topLevelTarget The listening component root node. 1004 * @param {string} topLevelTargetID ID of `topLevelTarget`. 1005 * @param {object} nativeEvent Native browser event. 1006 * @return {*} An accumulation of synthetic events. 1007 * @see {EventPluginHub.extractEvents} 1008 */ 1009 extractEvents: function( 1010 topLevelType, 1011 topLevelTarget, 1012 topLevelTargetID, 1013 nativeEvent) { 1014 1015 var eventType; 1016 var data; 1017 1018 if (useCompositionEvent) { 1019 eventType = getCompositionEventType(topLevelType); 1020 } else if (!currentComposition) { 1021 if (isFallbackStart(topLevelType, nativeEvent)) { 1022 eventType = eventTypes.compositionStart; 1023 } 1024 } else if (isFallbackEnd(topLevelType, nativeEvent)) { 1025 eventType = eventTypes.compositionEnd; 1026 } 1027 1028 if (useFallbackData) { 1029 // The current composition is stored statically and must not be 1030 // overwritten while composition continues. 1031 if (!currentComposition && eventType === eventTypes.compositionStart) { 1032 currentComposition = new FallbackCompositionState(topLevelTarget); 1033 } else if (eventType === eventTypes.compositionEnd) { 1034 if (currentComposition) { 1035 data = currentComposition.getData(); 1036 currentComposition = null; 1037 } 1038 } 1039 } 1040 1041 if (eventType) { 1042 var event = SyntheticCompositionEvent.getPooled( 1043 eventType, 1044 topLevelTargetID, 1045 nativeEvent 1046 ); 1047 if (data) { 1048 // Inject data generated from fallback path into the synthetic event. 1049 // This matches the property of native CompositionEventInterface. 1050 event.data = data; 1051 } 1052 EventPropagators.accumulateTwoPhaseDispatches(event); 1053 return event; 1054 } 1055 } 1056 }; 1057 1058 module.exports = CompositionEventPlugin; 1059 1060 },{"./EventConstants":15,"./EventPropagators":20,"./ExecutionEnvironment":21,"./ReactInputSelection":56,"./SyntheticCompositionEvent":87,"./getTextContentAccessor":121,"./keyOf":132}],8:[function(_dereq_,module,exports){ 1061 /** 1062 * Copyright 2013-2014 Facebook, Inc. 1063 * 1064 * Licensed under the Apache License, Version 2.0 (the "License"); 1065 * you may not use this file except in compliance with the License. 1066 * You may obtain a copy of the License at 1067 * 1068 * http://www.apache.org/licenses/LICENSE-2.0 1069 * 1070 * Unless required by applicable law or agreed to in writing, software 1071 * distributed under the License is distributed on an "AS IS" BASIS, 1072 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1073 * See the License for the specific language governing permissions and 1074 * limitations under the License. 1075 * 1076 * @providesModule DOMChildrenOperations 1077 * @typechecks static-only 1078 */ 1079 1080 "use strict"; 1081 1082 var Danger = _dereq_("./Danger"); 1083 var ReactMultiChildUpdateTypes = _dereq_("./ReactMultiChildUpdateTypes"); 1084 1085 var getTextContentAccessor = _dereq_("./getTextContentAccessor"); 1086 1087 /** 1088 * The DOM property to use when setting text content. 1089 * 1090 * @type {string} 1091 * @private 1092 */ 1093 var textContentAccessor = getTextContentAccessor(); 1094 1095 /** 1096 * Inserts `childNode` as a child of `parentNode` at the `index`. 1097 * 1098 * @param {DOMElement} parentNode Parent node in which to insert. 1099 * @param {DOMElement} childNode Child node to insert. 1100 * @param {number} index Index at which to insert the child. 1101 * @internal 1102 */ 1103 function insertChildAt(parentNode, childNode, index) { 1104 var childNodes = parentNode.childNodes; 1105 if (childNodes[index] === childNode) { 1106 return; 1107 } 1108 // If `childNode` is already a child of `parentNode`, remove it so that 1109 // computing `childNodes[index]` takes into account the removal. 1110 if (childNode.parentNode === parentNode) { 1111 parentNode.removeChild(childNode); 1112 } 1113 if (index >= childNodes.length) { 1114 parentNode.appendChild(childNode); 1115 } else { 1116 parentNode.insertBefore(childNode, childNodes[index]); 1117 } 1118 } 1119 1120 var updateTextContent; 1121 if (textContentAccessor === 'textContent') { 1122 /** 1123 * Sets the text content of `node` to `text`. 1124 * 1125 * @param {DOMElement} node Node to change 1126 * @param {string} text New text content 1127 */ 1128 updateTextContent = function(node, text) { 1129 node.textContent = text; 1130 }; 1131 } else { 1132 /** 1133 * Sets the text content of `node` to `text`. 1134 * 1135 * @param {DOMElement} node Node to change 1136 * @param {string} text New text content 1137 */ 1138 updateTextContent = function(node, text) { 1139 // In order to preserve newlines correctly, we can't use .innerText to set 1140 // the contents (see #1080), so we empty the element then append a text node 1141 while (node.firstChild) { 1142 node.removeChild(node.firstChild); 1143 } 1144 if (text) { 1145 var doc = node.ownerDocument || document; 1146 node.appendChild(doc.createTextNode(text)); 1147 } 1148 }; 1149 } 1150 1151 /** 1152 * Operations for updating with DOM children. 1153 */ 1154 var DOMChildrenOperations = { 1155 1156 dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, 1157 1158 updateTextContent: updateTextContent, 1159 1160 /** 1161 * Updates a component's children by processing a series of updates. The 1162 * update configurations are each expected to have a `parentNode` property. 1163 * 1164 * @param {array<object>} updates List of update configurations. 1165 * @param {array<string>} markupList List of markup strings. 1166 * @internal 1167 */ 1168 processUpdates: function(updates, markupList) { 1169 var update; 1170 // Mapping from parent IDs to initial child orderings. 1171 var initialChildren = null; 1172 // List of children that will be moved or removed. 1173 var updatedChildren = null; 1174 1175 for (var i = 0; update = updates[i]; i++) { 1176 if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || 1177 update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { 1178 var updatedIndex = update.fromIndex; 1179 var updatedChild = update.parentNode.childNodes[updatedIndex]; 1180 var parentID = update.parentID; 1181 1182 initialChildren = initialChildren || {}; 1183 initialChildren[parentID] = initialChildren[parentID] || []; 1184 initialChildren[parentID][updatedIndex] = updatedChild; 1185 1186 updatedChildren = updatedChildren || []; 1187 updatedChildren.push(updatedChild); 1188 } 1189 } 1190 1191 var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); 1192 1193 // Remove updated children first so that `toIndex` is consistent. 1194 if (updatedChildren) { 1195 for (var j = 0; j < updatedChildren.length; j++) { 1196 updatedChildren[j].parentNode.removeChild(updatedChildren[j]); 1197 } 1198 } 1199 1200 for (var k = 0; update = updates[k]; k++) { 1201 switch (update.type) { 1202 case ReactMultiChildUpdateTypes.INSERT_MARKUP: 1203 insertChildAt( 1204 update.parentNode, 1205 renderedMarkup[update.markupIndex], 1206 update.toIndex 1207 ); 1208 break; 1209 case ReactMultiChildUpdateTypes.MOVE_EXISTING: 1210 insertChildAt( 1211 update.parentNode, 1212 initialChildren[update.parentID][update.fromIndex], 1213 update.toIndex 1214 ); 1215 break; 1216 case ReactMultiChildUpdateTypes.TEXT_CONTENT: 1217 updateTextContent( 1218 update.parentNode, 1219 update.textContent 1220 ); 1221 break; 1222 case ReactMultiChildUpdateTypes.REMOVE_NODE: 1223 // Already removed by the for-loop above. 1224 break; 1225 } 1226 } 1227 } 1228 1229 }; 1230 1231 module.exports = DOMChildrenOperations; 1232 1233 },{"./Danger":11,"./ReactMultiChildUpdateTypes":63,"./getTextContentAccessor":121}],9:[function(_dereq_,module,exports){ 1234 /** 1235 * Copyright 2013-2014 Facebook, Inc. 1236 * 1237 * Licensed under the Apache License, Version 2.0 (the "License"); 1238 * you may not use this file except in compliance with the License. 1239 * You may obtain a copy of the License at 1240 * 1241 * http://www.apache.org/licenses/LICENSE-2.0 1242 * 1243 * Unless required by applicable law or agreed to in writing, software 1244 * distributed under the License is distributed on an "AS IS" BASIS, 1245 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1246 * See the License for the specific language governing permissions and 1247 * limitations under the License. 1248 * 1249 * @providesModule DOMProperty 1250 * @typechecks static-only 1251 */ 1252 1253 /*jslint bitwise: true */ 1254 1255 "use strict"; 1256 1257 var invariant = _dereq_("./invariant"); 1258 1259 var DOMPropertyInjection = { 1260 /** 1261 * Mapping from normalized, camelcased property names to a configuration that 1262 * specifies how the associated DOM property should be accessed or rendered. 1263 */ 1264 MUST_USE_ATTRIBUTE: 0x1, 1265 MUST_USE_PROPERTY: 0x2, 1266 HAS_SIDE_EFFECTS: 0x4, 1267 HAS_BOOLEAN_VALUE: 0x8, 1268 HAS_POSITIVE_NUMERIC_VALUE: 0x10, 1269 1270 /** 1271 * Inject some specialized knowledge about the DOM. This takes a config object 1272 * with the following properties: 1273 * 1274 * isCustomAttribute: function that given an attribute name will return true 1275 * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* 1276 * attributes where it's impossible to enumerate all of the possible 1277 * attribute names, 1278 * 1279 * Properties: object mapping DOM property name to one of the 1280 * DOMPropertyInjection constants or null. If your attribute isn't in here, 1281 * it won't get written to the DOM. 1282 * 1283 * DOMAttributeNames: object mapping React attribute name to the DOM 1284 * attribute name. Attribute names not specified use the **lowercase** 1285 * normalized name. 1286 * 1287 * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. 1288 * Property names not specified use the normalized name. 1289 * 1290 * DOMMutationMethods: Properties that require special mutation methods. If 1291 * `value` is undefined, the mutation method should unset the property. 1292 * 1293 * @param {object} domPropertyConfig the config as described above. 1294 */ 1295 injectDOMPropertyConfig: function(domPropertyConfig) { 1296 var Properties = domPropertyConfig.Properties || {}; 1297 var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; 1298 var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; 1299 var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; 1300 1301 if (domPropertyConfig.isCustomAttribute) { 1302 DOMProperty._isCustomAttributeFunctions.push( 1303 domPropertyConfig.isCustomAttribute 1304 ); 1305 } 1306 1307 for (var propName in Properties) { 1308 ("production" !== "development" ? invariant( 1309 !DOMProperty.isStandardName[propName], 1310 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + 1311 '\'%s\' which has already been injected. You may be accidentally ' + 1312 'injecting the same DOM property config twice, or you may be ' + 1313 'injecting two configs that have conflicting property names.', 1314 propName 1315 ) : invariant(!DOMProperty.isStandardName[propName])); 1316 1317 DOMProperty.isStandardName[propName] = true; 1318 1319 var lowerCased = propName.toLowerCase(); 1320 DOMProperty.getPossibleStandardName[lowerCased] = propName; 1321 1322 var attributeName = DOMAttributeNames[propName]; 1323 if (attributeName) { 1324 DOMProperty.getPossibleStandardName[attributeName] = propName; 1325 } 1326 1327 DOMProperty.getAttributeName[propName] = attributeName || lowerCased; 1328 1329 DOMProperty.getPropertyName[propName] = 1330 DOMPropertyNames[propName] || propName; 1331 1332 var mutationMethod = DOMMutationMethods[propName]; 1333 if (mutationMethod) { 1334 DOMProperty.getMutationMethod[propName] = mutationMethod; 1335 } 1336 1337 var propConfig = Properties[propName]; 1338 DOMProperty.mustUseAttribute[propName] = 1339 propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE; 1340 DOMProperty.mustUseProperty[propName] = 1341 propConfig & DOMPropertyInjection.MUST_USE_PROPERTY; 1342 DOMProperty.hasSideEffects[propName] = 1343 propConfig & DOMPropertyInjection.HAS_SIDE_EFFECTS; 1344 DOMProperty.hasBooleanValue[propName] = 1345 propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE; 1346 DOMProperty.hasPositiveNumericValue[propName] = 1347 propConfig & DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE; 1348 1349 ("production" !== "development" ? invariant( 1350 !DOMProperty.mustUseAttribute[propName] || 1351 !DOMProperty.mustUseProperty[propName], 1352 'DOMProperty: Cannot require using both attribute and property: %s', 1353 propName 1354 ) : invariant(!DOMProperty.mustUseAttribute[propName] || 1355 !DOMProperty.mustUseProperty[propName])); 1356 ("production" !== "development" ? invariant( 1357 DOMProperty.mustUseProperty[propName] || 1358 !DOMProperty.hasSideEffects[propName], 1359 'DOMProperty: Properties that have side effects must use property: %s', 1360 propName 1361 ) : invariant(DOMProperty.mustUseProperty[propName] || 1362 !DOMProperty.hasSideEffects[propName])); 1363 ("production" !== "development" ? invariant( 1364 !DOMProperty.hasBooleanValue[propName] || 1365 !DOMProperty.hasPositiveNumericValue[propName], 1366 'DOMProperty: Cannot have both boolean and positive numeric value: %s', 1367 propName 1368 ) : invariant(!DOMProperty.hasBooleanValue[propName] || 1369 !DOMProperty.hasPositiveNumericValue[propName])); 1370 } 1371 } 1372 }; 1373 var defaultValueCache = {}; 1374 1375 /** 1376 * DOMProperty exports lookup objects that can be used like functions: 1377 * 1378 * > DOMProperty.isValid['id'] 1379 * true 1380 * > DOMProperty.isValid['foobar'] 1381 * undefined 1382 * 1383 * Although this may be confusing, it performs better in general. 1384 * 1385 * @see http://jsperf.com/key-exists 1386 * @see http://jsperf.com/key-missing 1387 */ 1388 var DOMProperty = { 1389 1390 ID_ATTRIBUTE_NAME: 'data-reactid', 1391 1392 /** 1393 * Checks whether a property name is a standard property. 1394 * @type {Object} 1395 */ 1396 isStandardName: {}, 1397 1398 /** 1399 * Mapping from lowercase property names to the properly cased version, used 1400 * to warn in the case of missing properties. 1401 * @type {Object} 1402 */ 1403 getPossibleStandardName: {}, 1404 1405 /** 1406 * Mapping from normalized names to attribute names that differ. Attribute 1407 * names are used when rendering markup or with `*Attribute()`. 1408 * @type {Object} 1409 */ 1410 getAttributeName: {}, 1411 1412 /** 1413 * Mapping from normalized names to properties on DOM node instances. 1414 * (This includes properties that mutate due to external factors.) 1415 * @type {Object} 1416 */ 1417 getPropertyName: {}, 1418 1419 /** 1420 * Mapping from normalized names to mutation methods. This will only exist if 1421 * mutation cannot be set simply by the property or `setAttribute()`. 1422 * @type {Object} 1423 */ 1424 getMutationMethod: {}, 1425 1426 /** 1427 * Whether the property must be accessed and mutated as an object property. 1428 * @type {Object} 1429 */ 1430 mustUseAttribute: {}, 1431 1432 /** 1433 * Whether the property must be accessed and mutated using `*Attribute()`. 1434 * (This includes anything that fails `<propName> in <element>`.) 1435 * @type {Object} 1436 */ 1437 mustUseProperty: {}, 1438 1439 /** 1440 * Whether or not setting a value causes side effects such as triggering 1441 * resources to be loaded or text selection changes. We must ensure that 1442 * the value is only set if it has changed. 1443 * @type {Object} 1444 */ 1445 hasSideEffects: {}, 1446 1447 /** 1448 * Whether the property should be removed when set to a falsey value. 1449 * @type {Object} 1450 */ 1451 hasBooleanValue: {}, 1452 1453 /** 1454 * Whether the property must be positive numeric or parse as a positive 1455 * numeric and should be removed when set to a falsey value. 1456 * @type {Object} 1457 */ 1458 hasPositiveNumericValue: {}, 1459 1460 /** 1461 * All of the isCustomAttribute() functions that have been injected. 1462 */ 1463 _isCustomAttributeFunctions: [], 1464 1465 /** 1466 * Checks whether a property name is a custom attribute. 1467 * @method 1468 */ 1469 isCustomAttribute: function(attributeName) { 1470 for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { 1471 var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; 1472 if (isCustomAttributeFn(attributeName)) { 1473 return true; 1474 } 1475 } 1476 return false; 1477 }, 1478 1479 /** 1480 * Returns the default property value for a DOM property (i.e., not an 1481 * attribute). Most default values are '' or false, but not all. Worse yet, 1482 * some (in particular, `type`) vary depending on the type of element. 1483 * 1484 * TODO: Is it better to grab all the possible properties when creating an 1485 * element to avoid having to create the same element twice? 1486 */ 1487 getDefaultValueForProperty: function(nodeName, prop) { 1488 var nodeDefaults = defaultValueCache[nodeName]; 1489 var testElement; 1490 if (!nodeDefaults) { 1491 defaultValueCache[nodeName] = nodeDefaults = {}; 1492 } 1493 if (!(prop in nodeDefaults)) { 1494 testElement = document.createElement(nodeName); 1495 nodeDefaults[prop] = testElement[prop]; 1496 } 1497 return nodeDefaults[prop]; 1498 }, 1499 1500 injection: DOMPropertyInjection 1501 }; 1502 1503 module.exports = DOMProperty; 1504 1505 },{"./invariant":125}],10:[function(_dereq_,module,exports){ 1506 /** 1507 * Copyright 2013-2014 Facebook, Inc. 1508 * 1509 * Licensed under the Apache License, Version 2.0 (the "License"); 1510 * you may not use this file except in compliance with the License. 1511 * You may obtain a copy of the License at 1512 * 1513 * http://www.apache.org/licenses/LICENSE-2.0 1514 * 1515 * Unless required by applicable law or agreed to in writing, software 1516 * distributed under the License is distributed on an "AS IS" BASIS, 1517 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1518 * See the License for the specific language governing permissions and 1519 * limitations under the License. 1520 * 1521 * @providesModule DOMPropertyOperations 1522 * @typechecks static-only 1523 */ 1524 1525 "use strict"; 1526 1527 var DOMProperty = _dereq_("./DOMProperty"); 1528 1529 var escapeTextForBrowser = _dereq_("./escapeTextForBrowser"); 1530 var memoizeStringOnly = _dereq_("./memoizeStringOnly"); 1531 var warning = _dereq_("./warning"); 1532 1533 function shouldIgnoreValue(name, value) { 1534 return value == null || 1535 DOMProperty.hasBooleanValue[name] && !value || 1536 DOMProperty.hasPositiveNumericValue[name] && (isNaN(value) || value < 1); 1537 } 1538 1539 var processAttributeNameAndPrefix = memoizeStringOnly(function(name) { 1540 return escapeTextForBrowser(name) + '="'; 1541 }); 1542 1543 if ("production" !== "development") { 1544 var reactProps = { 1545 children: true, 1546 dangerouslySetInnerHTML: true, 1547 key: true, 1548 ref: true 1549 }; 1550 var warnedProperties = {}; 1551 1552 var warnUnknownProperty = function(name) { 1553 if (reactProps[name] || warnedProperties[name]) { 1554 return; 1555 } 1556 1557 warnedProperties[name] = true; 1558 var lowerCasedName = name.toLowerCase(); 1559 1560 // data-* attributes should be lowercase; suggest the lowercase version 1561 var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? 1562 lowerCasedName : DOMProperty.getPossibleStandardName[lowerCasedName]; 1563 1564 // For now, only warn when we have a suggested correction. This prevents 1565 // logging too much when using transferPropsTo. 1566 ("production" !== "development" ? warning( 1567 standardName == null, 1568 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?' 1569 ) : null); 1570 1571 }; 1572 } 1573 1574 /** 1575 * Operations for dealing with DOM properties. 1576 */ 1577 var DOMPropertyOperations = { 1578 1579 /** 1580 * Creates markup for the ID property. 1581 * 1582 * @param {string} id Unescaped ID. 1583 * @return {string} Markup string. 1584 */ 1585 createMarkupForID: function(id) { 1586 return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) + 1587 escapeTextForBrowser(id) + '"'; 1588 }, 1589 1590 /** 1591 * Creates markup for a property. 1592 * 1593 * @param {string} name 1594 * @param {*} value 1595 * @return {?string} Markup string, or null if the property was invalid. 1596 */ 1597 createMarkupForProperty: function(name, value) { 1598 if (DOMProperty.isStandardName[name]) { 1599 if (shouldIgnoreValue(name, value)) { 1600 return ''; 1601 } 1602 var attributeName = DOMProperty.getAttributeName[name]; 1603 if (DOMProperty.hasBooleanValue[name]) { 1604 return escapeTextForBrowser(attributeName); 1605 } 1606 return processAttributeNameAndPrefix(attributeName) + 1607 escapeTextForBrowser(value) + '"'; 1608 } else if (DOMProperty.isCustomAttribute(name)) { 1609 if (value == null) { 1610 return ''; 1611 } 1612 return processAttributeNameAndPrefix(name) + 1613 escapeTextForBrowser(value) + '"'; 1614 } else if ("production" !== "development") { 1615 warnUnknownProperty(name); 1616 } 1617 return null; 1618 }, 1619 1620 /** 1621 * Sets the value for a property on a node. 1622 * 1623 * @param {DOMElement} node 1624 * @param {string} name 1625 * @param {*} value 1626 */ 1627 setValueForProperty: function(node, name, value) { 1628 if (DOMProperty.isStandardName[name]) { 1629 var mutationMethod = DOMProperty.getMutationMethod[name]; 1630 if (mutationMethod) { 1631 mutationMethod(node, value); 1632 } else if (shouldIgnoreValue(name, value)) { 1633 this.deleteValueForProperty(node, name); 1634 } else if (DOMProperty.mustUseAttribute[name]) { 1635 node.setAttribute(DOMProperty.getAttributeName[name], '' + value); 1636 } else { 1637 var propName = DOMProperty.getPropertyName[name]; 1638 if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) { 1639 node[propName] = value; 1640 } 1641 } 1642 } else if (DOMProperty.isCustomAttribute(name)) { 1643 if (value == null) { 1644 node.removeAttribute(DOMProperty.getAttributeName[name]); 1645 } else { 1646 node.setAttribute(name, '' + value); 1647 } 1648 } else if ("production" !== "development") { 1649 warnUnknownProperty(name); 1650 } 1651 }, 1652 1653 /** 1654 * Deletes the value for a property on a node. 1655 * 1656 * @param {DOMElement} node 1657 * @param {string} name 1658 */ 1659 deleteValueForProperty: function(node, name) { 1660 if (DOMProperty.isStandardName[name]) { 1661 var mutationMethod = DOMProperty.getMutationMethod[name]; 1662 if (mutationMethod) { 1663 mutationMethod(node, undefined); 1664 } else if (DOMProperty.mustUseAttribute[name]) { 1665 node.removeAttribute(DOMProperty.getAttributeName[name]); 1666 } else { 1667 var propName = DOMProperty.getPropertyName[name]; 1668 var defaultValue = DOMProperty.getDefaultValueForProperty( 1669 node.nodeName, 1670 propName 1671 ); 1672 if (!DOMProperty.hasSideEffects[name] || 1673 node[propName] !== defaultValue) { 1674 node[propName] = defaultValue; 1675 } 1676 } 1677 } else if (DOMProperty.isCustomAttribute(name)) { 1678 node.removeAttribute(name); 1679 } else if ("production" !== "development") { 1680 warnUnknownProperty(name); 1681 } 1682 } 1683 1684 }; 1685 1686 module.exports = DOMPropertyOperations; 1687 1688 },{"./DOMProperty":9,"./escapeTextForBrowser":111,"./memoizeStringOnly":133,"./warning":148}],11:[function(_dereq_,module,exports){ 1689 /** 1690 * Copyright 2013-2014 Facebook, Inc. 1691 * 1692 * Licensed under the Apache License, Version 2.0 (the "License"); 1693 * you may not use this file except in compliance with the License. 1694 * You may obtain a copy of the License at 1695 * 1696 * http://www.apache.org/licenses/LICENSE-2.0 1697 * 1698 * Unless required by applicable law or agreed to in writing, software 1699 * distributed under the License is distributed on an "AS IS" BASIS, 1700 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1701 * See the License for the specific language governing permissions and 1702 * limitations under the License. 1703 * 1704 * @providesModule Danger 1705 * @typechecks static-only 1706 */ 1707 1708 /*jslint evil: true, sub: true */ 1709 1710 "use strict"; 1711 1712 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 1713 1714 var createNodesFromMarkup = _dereq_("./createNodesFromMarkup"); 1715 var emptyFunction = _dereq_("./emptyFunction"); 1716 var getMarkupWrap = _dereq_("./getMarkupWrap"); 1717 var invariant = _dereq_("./invariant"); 1718 1719 var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; 1720 var RESULT_INDEX_ATTR = 'data-danger-index'; 1721 1722 /** 1723 * Extracts the `nodeName` from a string of markup. 1724 * 1725 * NOTE: Extracting the `nodeName` does not require a regular expression match 1726 * because we make assumptions about React-generated markup (i.e. there are no 1727 * spaces surrounding the opening tag and there is at least one attribute). 1728 * 1729 * @param {string} markup String of markup. 1730 * @return {string} Node name of the supplied markup. 1731 * @see http://jsperf.com/extract-nodename 1732 */ 1733 function getNodeName(markup) { 1734 return markup.substring(1, markup.indexOf(' ')); 1735 } 1736 1737 var Danger = { 1738 1739 /** 1740 * Renders markup into an array of nodes. The markup is expected to render 1741 * into a list of root nodes. Also, the length of `resultList` and 1742 * `markupList` should be the same. 1743 * 1744 * @param {array<string>} markupList List of markup strings to render. 1745 * @return {array<DOMElement>} List of rendered nodes. 1746 * @internal 1747 */ 1748 dangerouslyRenderMarkup: function(markupList) { 1749 ("production" !== "development" ? invariant( 1750 ExecutionEnvironment.canUseDOM, 1751 'dangerouslyRenderMarkup(...): Cannot render markup in a Worker ' + 1752 'thread. This is likely a bug in the framework. Please report ' + 1753 'immediately.' 1754 ) : invariant(ExecutionEnvironment.canUseDOM)); 1755 var nodeName; 1756 var markupByNodeName = {}; 1757 // Group markup by `nodeName` if a wrap is necessary, else by '*'. 1758 for (var i = 0; i < markupList.length; i++) { 1759 ("production" !== "development" ? invariant( 1760 markupList[i], 1761 'dangerouslyRenderMarkup(...): Missing markup.' 1762 ) : invariant(markupList[i])); 1763 nodeName = getNodeName(markupList[i]); 1764 nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; 1765 markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; 1766 markupByNodeName[nodeName][i] = markupList[i]; 1767 } 1768 var resultList = []; 1769 var resultListAssignmentCount = 0; 1770 for (nodeName in markupByNodeName) { 1771 if (!markupByNodeName.hasOwnProperty(nodeName)) { 1772 continue; 1773 } 1774 var markupListByNodeName = markupByNodeName[nodeName]; 1775 1776 // This for-in loop skips the holes of the sparse array. The order of 1777 // iteration should follow the order of assignment, which happens to match 1778 // numerical index order, but we don't rely on that. 1779 for (var resultIndex in markupListByNodeName) { 1780 if (markupListByNodeName.hasOwnProperty(resultIndex)) { 1781 var markup = markupListByNodeName[resultIndex]; 1782 1783 // Push the requested markup with an additional RESULT_INDEX_ATTR 1784 // attribute. If the markup does not start with a < character, it 1785 // will be discarded below (with an appropriate console.error). 1786 markupListByNodeName[resultIndex] = markup.replace( 1787 OPEN_TAG_NAME_EXP, 1788 // This index will be parsed back out below. 1789 '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' 1790 ); 1791 } 1792 } 1793 1794 // Render each group of markup with similar wrapping `nodeName`. 1795 var renderNodes = createNodesFromMarkup( 1796 markupListByNodeName.join(''), 1797 emptyFunction // Do nothing special with <script> tags. 1798 ); 1799 1800 for (i = 0; i < renderNodes.length; ++i) { 1801 var renderNode = renderNodes[i]; 1802 if (renderNode.hasAttribute && 1803 renderNode.hasAttribute(RESULT_INDEX_ATTR)) { 1804 1805 resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR); 1806 renderNode.removeAttribute(RESULT_INDEX_ATTR); 1807 1808 ("production" !== "development" ? invariant( 1809 !resultList.hasOwnProperty(resultIndex), 1810 'Danger: Assigning to an already-occupied result index.' 1811 ) : invariant(!resultList.hasOwnProperty(resultIndex))); 1812 1813 resultList[resultIndex] = renderNode; 1814 1815 // This should match resultList.length and markupList.length when 1816 // we're done. 1817 resultListAssignmentCount += 1; 1818 1819 } else if ("production" !== "development") { 1820 console.error( 1821 "Danger: Discarding unexpected node:", 1822 renderNode 1823 ); 1824 } 1825 } 1826 } 1827 1828 // Although resultList was populated out of order, it should now be a dense 1829 // array. 1830 ("production" !== "development" ? invariant( 1831 resultListAssignmentCount === resultList.length, 1832 'Danger: Did not assign to every index of resultList.' 1833 ) : invariant(resultListAssignmentCount === resultList.length)); 1834 1835 ("production" !== "development" ? invariant( 1836 resultList.length === markupList.length, 1837 'Danger: Expected markup to render %s nodes, but rendered %s.', 1838 markupList.length, 1839 resultList.length 1840 ) : invariant(resultList.length === markupList.length)); 1841 1842 return resultList; 1843 }, 1844 1845 /** 1846 * Replaces a node with a string of markup at its current position within its 1847 * parent. The markup must render into a single root node. 1848 * 1849 * @param {DOMElement} oldChild Child node to replace. 1850 * @param {string} markup Markup to render in place of the child node. 1851 * @internal 1852 */ 1853 dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) { 1854 ("production" !== "development" ? invariant( 1855 ExecutionEnvironment.canUseDOM, 1856 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + 1857 'worker thread. This is likely a bug in the framework. Please report ' + 1858 'immediately.' 1859 ) : invariant(ExecutionEnvironment.canUseDOM)); 1860 ("production" !== "development" ? invariant(markup, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(markup)); 1861 ("production" !== "development" ? invariant( 1862 oldChild.tagName.toLowerCase() !== 'html', 1863 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + 1864 '<html> node. This is because browser quirks make this unreliable ' + 1865 'and/or slow. If you want to render to the root you must use ' + 1866 'server rendering. See renderComponentToString().' 1867 ) : invariant(oldChild.tagName.toLowerCase() !== 'html')); 1868 1869 var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; 1870 oldChild.parentNode.replaceChild(newChild, oldChild); 1871 } 1872 1873 }; 1874 1875 module.exports = Danger; 1876 1877 },{"./ExecutionEnvironment":21,"./createNodesFromMarkup":105,"./emptyFunction":109,"./getMarkupWrap":118,"./invariant":125}],12:[function(_dereq_,module,exports){ 1878 /** 1879 * Copyright 2013-2014 Facebook, Inc. 1880 * 1881 * Licensed under the Apache License, Version 2.0 (the "License"); 1882 * you may not use this file except in compliance with the License. 1883 * You may obtain a copy of the License at 1884 * 1885 * http://www.apache.org/licenses/LICENSE-2.0 1886 * 1887 * Unless required by applicable law or agreed to in writing, software 1888 * distributed under the License is distributed on an "AS IS" BASIS, 1889 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1890 * See the License for the specific language governing permissions and 1891 * limitations under the License. 1892 * 1893 * @providesModule DefaultDOMPropertyConfig 1894 */ 1895 1896 /*jslint bitwise: true*/ 1897 1898 "use strict"; 1899 1900 var DOMProperty = _dereq_("./DOMProperty"); 1901 1902 var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE; 1903 var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; 1904 var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; 1905 var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS; 1906 var HAS_POSITIVE_NUMERIC_VALUE = 1907 DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; 1908 1909 var DefaultDOMPropertyConfig = { 1910 isCustomAttribute: RegExp.prototype.test.bind( 1911 /^(data|aria)-[a-z_][a-z\d_.\-]*$/ 1912 ), 1913 Properties: { 1914 /** 1915 * Standard Properties 1916 */ 1917 accept: null, 1918 accessKey: null, 1919 action: null, 1920 allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, 1921 allowTransparency: MUST_USE_ATTRIBUTE, 1922 alt: null, 1923 async: HAS_BOOLEAN_VALUE, 1924 autoComplete: null, 1925 // autoFocus is polyfilled/normalized by AutoFocusMixin 1926 // autoFocus: HAS_BOOLEAN_VALUE, 1927 autoPlay: HAS_BOOLEAN_VALUE, 1928 cellPadding: null, 1929 cellSpacing: null, 1930 charSet: MUST_USE_ATTRIBUTE, 1931 checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, 1932 className: MUST_USE_PROPERTY, 1933 cols: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, 1934 colSpan: null, 1935 content: null, 1936 contentEditable: null, 1937 contextMenu: MUST_USE_ATTRIBUTE, 1938 controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, 1939 crossOrigin: null, 1940 data: null, // For `<object />` acts as `src`. 1941 dateTime: MUST_USE_ATTRIBUTE, 1942 defer: HAS_BOOLEAN_VALUE, 1943 dir: null, 1944 disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, 1945 download: null, 1946 draggable: null, 1947 encType: null, 1948 form: MUST_USE_ATTRIBUTE, 1949 formNoValidate: HAS_BOOLEAN_VALUE, 1950 frameBorder: MUST_USE_ATTRIBUTE, 1951 height: MUST_USE_ATTRIBUTE, 1952 hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, 1953 href: null, 1954 hrefLang: null, 1955 htmlFor: null, 1956 httpEquiv: null, 1957 icon: null, 1958 id: MUST_USE_PROPERTY, 1959 label: null, 1960 lang: null, 1961 list: null, 1962 loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, 1963 max: null, 1964 maxLength: MUST_USE_ATTRIBUTE, 1965 mediaGroup: null, 1966 method: null, 1967 min: null, 1968 multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, 1969 muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, 1970 name: null, 1971 noValidate: HAS_BOOLEAN_VALUE, 1972 pattern: null, 1973 placeholder: null, 1974 poster: null, 1975 preload: null, 1976 radioGroup: null, 1977 readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, 1978 rel: null, 1979 required: HAS_BOOLEAN_VALUE, 1980 role: MUST_USE_ATTRIBUTE, 1981 rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, 1982 rowSpan: null, 1983 sandbox: null, 1984 scope: null, 1985 scrollLeft: MUST_USE_PROPERTY, 1986 scrollTop: MUST_USE_PROPERTY, 1987 seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, 1988 selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, 1989 size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, 1990 span: HAS_POSITIVE_NUMERIC_VALUE, 1991 spellCheck: null, 1992 src: null, 1993 srcDoc: MUST_USE_PROPERTY, 1994 srcSet: null, 1995 step: null, 1996 style: null, 1997 tabIndex: null, 1998 target: null, 1999 title: null, 2000 type: null, 2001 value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS, 2002 width: MUST_USE_ATTRIBUTE, 2003 wmode: MUST_USE_ATTRIBUTE, 2004 2005 /** 2006 * Non-standard Properties 2007 */ 2008 autoCapitalize: null, // Supported in Mobile Safari for keyboard hints 2009 autoCorrect: null, // Supported in Mobile Safari for keyboard hints 2010 property: null, // Supports OG in meta tags 2011 2012 /** 2013 * SVG Properties 2014 */ 2015 cx: MUST_USE_ATTRIBUTE, 2016 cy: MUST_USE_ATTRIBUTE, 2017 d: MUST_USE_ATTRIBUTE, 2018 fill: MUST_USE_ATTRIBUTE, 2019 fx: MUST_USE_ATTRIBUTE, 2020 fy: MUST_USE_ATTRIBUTE, 2021 gradientTransform: MUST_USE_ATTRIBUTE, 2022 gradientUnits: MUST_USE_ATTRIBUTE, 2023 offset: MUST_USE_ATTRIBUTE, 2024 points: MUST_USE_ATTRIBUTE, 2025 r: MUST_USE_ATTRIBUTE, 2026 rx: MUST_USE_ATTRIBUTE, 2027 ry: MUST_USE_ATTRIBUTE, 2028 spreadMethod: MUST_USE_ATTRIBUTE, 2029 stopColor: MUST_USE_ATTRIBUTE, 2030 stopOpacity: MUST_USE_ATTRIBUTE, 2031 stroke: MUST_USE_ATTRIBUTE, 2032 strokeLinecap: MUST_USE_ATTRIBUTE, 2033 strokeWidth: MUST_USE_ATTRIBUTE, 2034 textAnchor: MUST_USE_ATTRIBUTE, 2035 transform: MUST_USE_ATTRIBUTE, 2036 version: MUST_USE_ATTRIBUTE, 2037 viewBox: MUST_USE_ATTRIBUTE, 2038 x1: MUST_USE_ATTRIBUTE, 2039 x2: MUST_USE_ATTRIBUTE, 2040 x: MUST_USE_ATTRIBUTE, 2041 y1: MUST_USE_ATTRIBUTE, 2042 y2: MUST_USE_ATTRIBUTE, 2043 y: MUST_USE_ATTRIBUTE 2044 }, 2045 DOMAttributeNames: { 2046 className: 'class', 2047 gradientTransform: 'gradientTransform', 2048 gradientUnits: 'gradientUnits', 2049 htmlFor: 'for', 2050 spreadMethod: 'spreadMethod', 2051 stopColor: 'stop-color', 2052 stopOpacity: 'stop-opacity', 2053 strokeLinecap: 'stroke-linecap', 2054 strokeWidth: 'stroke-width', 2055 textAnchor: 'text-anchor', 2056 viewBox: 'viewBox' 2057 }, 2058 DOMPropertyNames: { 2059 autoCapitalize: 'autocapitalize', 2060 autoComplete: 'autocomplete', 2061 autoCorrect: 'autocorrect', 2062 autoFocus: 'autofocus', 2063 autoPlay: 'autoplay', 2064 encType: 'enctype', 2065 hrefLang: 'hreflang', 2066 radioGroup: 'radiogroup', 2067 spellCheck: 'spellcheck', 2068 srcDoc: 'srcdoc', 2069 srcSet: 'srcset' 2070 } 2071 }; 2072 2073 module.exports = DefaultDOMPropertyConfig; 2074 2075 },{"./DOMProperty":9}],13:[function(_dereq_,module,exports){ 2076 /** 2077 * Copyright 2013-2014 Facebook, Inc. 2078 * 2079 * Licensed under the Apache License, Version 2.0 (the "License"); 2080 * you may not use this file except in compliance with the License. 2081 * You may obtain a copy of the License at 2082 * 2083 * http://www.apache.org/licenses/LICENSE-2.0 2084 * 2085 * Unless required by applicable law or agreed to in writing, software 2086 * distributed under the License is distributed on an "AS IS" BASIS, 2087 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2088 * See the License for the specific language governing permissions and 2089 * limitations under the License. 2090 * 2091 * @providesModule DefaultEventPluginOrder 2092 */ 2093 2094 "use strict"; 2095 2096 var keyOf = _dereq_("./keyOf"); 2097 2098 /** 2099 * Module that is injectable into `EventPluginHub`, that specifies a 2100 * deterministic ordering of `EventPlugin`s. A convenient way to reason about 2101 * plugins, without having to package every one of them. This is better than 2102 * having plugins be ordered in the same order that they are injected because 2103 * that ordering would be influenced by the packaging order. 2104 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that 2105 * preventing default on events is convenient in `SimpleEventPlugin` handlers. 2106 */ 2107 var DefaultEventPluginOrder = [ 2108 keyOf({ResponderEventPlugin: null}), 2109 keyOf({SimpleEventPlugin: null}), 2110 keyOf({TapEventPlugin: null}), 2111 keyOf({EnterLeaveEventPlugin: null}), 2112 keyOf({ChangeEventPlugin: null}), 2113 keyOf({SelectEventPlugin: null}), 2114 keyOf({CompositionEventPlugin: null}), 2115 keyOf({AnalyticsEventPlugin: null}), 2116 keyOf({MobileSafariClickEventPlugin: null}) 2117 ]; 2118 2119 module.exports = DefaultEventPluginOrder; 2120 2121 },{"./keyOf":132}],14:[function(_dereq_,module,exports){ 2122 /** 2123 * Copyright 2013-2014 Facebook, Inc. 2124 * 2125 * Licensed under the Apache License, Version 2.0 (the "License"); 2126 * you may not use this file except in compliance with the License. 2127 * You may obtain a copy of the License at 2128 * 2129 * http://www.apache.org/licenses/LICENSE-2.0 2130 * 2131 * Unless required by applicable law or agreed to in writing, software 2132 * distributed under the License is distributed on an "AS IS" BASIS, 2133 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2134 * See the License for the specific language governing permissions and 2135 * limitations under the License. 2136 * 2137 * @providesModule EnterLeaveEventPlugin 2138 * @typechecks static-only 2139 */ 2140 2141 "use strict"; 2142 2143 var EventConstants = _dereq_("./EventConstants"); 2144 var EventPropagators = _dereq_("./EventPropagators"); 2145 var SyntheticMouseEvent = _dereq_("./SyntheticMouseEvent"); 2146 2147 var ReactMount = _dereq_("./ReactMount"); 2148 var keyOf = _dereq_("./keyOf"); 2149 2150 var topLevelTypes = EventConstants.topLevelTypes; 2151 var getFirstReactDOM = ReactMount.getFirstReactDOM; 2152 2153 var eventTypes = { 2154 mouseEnter: { 2155 registrationName: keyOf({onMouseEnter: null}), 2156 dependencies: [ 2157 topLevelTypes.topMouseOut, 2158 topLevelTypes.topMouseOver 2159 ] 2160 }, 2161 mouseLeave: { 2162 registrationName: keyOf({onMouseLeave: null}), 2163 dependencies: [ 2164 topLevelTypes.topMouseOut, 2165 topLevelTypes.topMouseOver 2166 ] 2167 } 2168 }; 2169 2170 var extractedEvents = [null, null]; 2171 2172 var EnterLeaveEventPlugin = { 2173 2174 eventTypes: eventTypes, 2175 2176 /** 2177 * For almost every interaction we care about, there will be both a top-level 2178 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that 2179 * we do not extract duplicate events. However, moving the mouse into the 2180 * browser from outside will not fire a `mouseout` event. In this case, we use 2181 * the `mouseover` top-level event. 2182 * 2183 * @param {string} topLevelType Record from `EventConstants`. 2184 * @param {DOMEventTarget} topLevelTarget The listening component root node. 2185 * @param {string} topLevelTargetID ID of `topLevelTarget`. 2186 * @param {object} nativeEvent Native browser event. 2187 * @return {*} An accumulation of synthetic events. 2188 * @see {EventPluginHub.extractEvents} 2189 */ 2190 extractEvents: function( 2191 topLevelType, 2192 topLevelTarget, 2193 topLevelTargetID, 2194 nativeEvent) { 2195 if (topLevelType === topLevelTypes.topMouseOver && 2196 (nativeEvent.relatedTarget || nativeEvent.fromElement)) { 2197 return null; 2198 } 2199 if (topLevelType !== topLevelTypes.topMouseOut && 2200 topLevelType !== topLevelTypes.topMouseOver) { 2201 // Must not be a mouse in or mouse out - ignoring. 2202 return null; 2203 } 2204 2205 var win; 2206 if (topLevelTarget.window === topLevelTarget) { 2207 // `topLevelTarget` is probably a window object. 2208 win = topLevelTarget; 2209 } else { 2210 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. 2211 var doc = topLevelTarget.ownerDocument; 2212 if (doc) { 2213 win = doc.defaultView || doc.parentWindow; 2214 } else { 2215 win = window; 2216 } 2217 } 2218 2219 var from, to; 2220 if (topLevelType === topLevelTypes.topMouseOut) { 2221 from = topLevelTarget; 2222 to = 2223 getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) || 2224 win; 2225 } else { 2226 from = win; 2227 to = topLevelTarget; 2228 } 2229 2230 if (from === to) { 2231 // Nothing pertains to our managed components. 2232 return null; 2233 } 2234 2235 var fromID = from ? ReactMount.getID(from) : ''; 2236 var toID = to ? ReactMount.getID(to) : ''; 2237 2238 var leave = SyntheticMouseEvent.getPooled( 2239 eventTypes.mouseLeave, 2240 fromID, 2241 nativeEvent 2242 ); 2243 leave.type = 'mouseleave'; 2244 leave.target = from; 2245 leave.relatedTarget = to; 2246 2247 var enter = SyntheticMouseEvent.getPooled( 2248 eventTypes.mouseEnter, 2249 toID, 2250 nativeEvent 2251 ); 2252 enter.type = 'mouseenter'; 2253 enter.target = to; 2254 enter.relatedTarget = from; 2255 2256 EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID); 2257 2258 extractedEvents[0] = leave; 2259 extractedEvents[1] = enter; 2260 2261 return extractedEvents; 2262 } 2263 2264 }; 2265 2266 module.exports = EnterLeaveEventPlugin; 2267 2268 },{"./EventConstants":15,"./EventPropagators":20,"./ReactMount":60,"./SyntheticMouseEvent":92,"./keyOf":132}],15:[function(_dereq_,module,exports){ 2269 /** 2270 * Copyright 2013-2014 Facebook, Inc. 2271 * 2272 * Licensed under the Apache License, Version 2.0 (the "License"); 2273 * you may not use this file except in compliance with the License. 2274 * You may obtain a copy of the License at 2275 * 2276 * http://www.apache.org/licenses/LICENSE-2.0 2277 * 2278 * Unless required by applicable law or agreed to in writing, software 2279 * distributed under the License is distributed on an "AS IS" BASIS, 2280 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2281 * See the License for the specific language governing permissions and 2282 * limitations under the License. 2283 * 2284 * @providesModule EventConstants 2285 */ 2286 2287 "use strict"; 2288 2289 var keyMirror = _dereq_("./keyMirror"); 2290 2291 var PropagationPhases = keyMirror({bubbled: null, captured: null}); 2292 2293 /** 2294 * Types of raw signals from the browser caught at the top level. 2295 */ 2296 var topLevelTypes = keyMirror({ 2297 topBlur: null, 2298 topChange: null, 2299 topClick: null, 2300 topCompositionEnd: null, 2301 topCompositionStart: null, 2302 topCompositionUpdate: null, 2303 topContextMenu: null, 2304 topCopy: null, 2305 topCut: null, 2306 topDoubleClick: null, 2307 topDrag: null, 2308 topDragEnd: null, 2309 topDragEnter: null, 2310 topDragExit: null, 2311 topDragLeave: null, 2312 topDragOver: null, 2313 topDragStart: null, 2314 topDrop: null, 2315 topError: null, 2316 topFocus: null, 2317 topInput: null, 2318 topKeyDown: null, 2319 topKeyPress: null, 2320 topKeyUp: null, 2321 topLoad: null, 2322 topMouseDown: null, 2323 topMouseMove: null, 2324 topMouseOut: null, 2325 topMouseOver: null, 2326 topMouseUp: null, 2327 topPaste: null, 2328 topReset: null, 2329 topScroll: null, 2330 topSelectionChange: null, 2331 topSubmit: null, 2332 topTouchCancel: null, 2333 topTouchEnd: null, 2334 topTouchMove: null, 2335 topTouchStart: null, 2336 topWheel: null 2337 }); 2338 2339 var EventConstants = { 2340 topLevelTypes: topLevelTypes, 2341 PropagationPhases: PropagationPhases 2342 }; 2343 2344 module.exports = EventConstants; 2345 2346 },{"./keyMirror":131}],16:[function(_dereq_,module,exports){ 2347 /** 2348 * @providesModule EventListener 2349 */ 2350 2351 var emptyFunction = _dereq_("./emptyFunction"); 2352 2353 /** 2354 * Upstream version of event listener. Does not take into account specific 2355 * nature of platform. 2356 */ 2357 var EventListener = { 2358 /** 2359 * Listen to DOM events during the bubble phase. 2360 * 2361 * @param {DOMEventTarget} target DOM element to register listener on. 2362 * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. 2363 * @param {function} callback Callback function. 2364 * @return {object} Object with a `remove` method. 2365 */ 2366 listen: function(target, eventType, callback) { 2367 if (target.addEventListener) { 2368 target.addEventListener(eventType, callback, false); 2369 return { 2370 remove: function() { 2371 target.removeEventListener(eventType, callback, false); 2372 } 2373 }; 2374 } else if (target.attachEvent) { 2375 target.attachEvent('on' + eventType, callback); 2376 return { 2377 remove: function() { 2378 target.detachEvent(eventType, callback); 2379 } 2380 }; 2381 } 2382 }, 2383 2384 /** 2385 * Listen to DOM events during the capture phase. 2386 * 2387 * @param {DOMEventTarget} target DOM element to register listener on. 2388 * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. 2389 * @param {function} callback Callback function. 2390 * @return {object} Object with a `remove` method. 2391 */ 2392 capture: function(target, eventType, callback) { 2393 if (!target.addEventListener) { 2394 if ("production" !== "development") { 2395 console.error( 2396 'Attempted to listen to events during the capture phase on a ' + 2397 'browser that does not support the capture phase. Your application ' + 2398 'will not receive some events.' 2399 ); 2400 } 2401 return { 2402 remove: emptyFunction 2403 }; 2404 } else { 2405 target.addEventListener(eventType, callback, true); 2406 return { 2407 remove: function() { 2408 target.removeEventListener(eventType, callback, true); 2409 } 2410 }; 2411 } 2412 } 2413 }; 2414 2415 module.exports = EventListener; 2416 2417 },{"./emptyFunction":109}],17:[function(_dereq_,module,exports){ 2418 /** 2419 * Copyright 2013-2014 Facebook, Inc. 2420 * 2421 * Licensed under the Apache License, Version 2.0 (the "License"); 2422 * you may not use this file except in compliance with the License. 2423 * You may obtain a copy of the License at 2424 * 2425 * http://www.apache.org/licenses/LICENSE-2.0 2426 * 2427 * Unless required by applicable law or agreed to in writing, software 2428 * distributed under the License is distributed on an "AS IS" BASIS, 2429 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2430 * See the License for the specific language governing permissions and 2431 * limitations under the License. 2432 * 2433 * @providesModule EventPluginHub 2434 */ 2435 2436 "use strict"; 2437 2438 var EventPluginRegistry = _dereq_("./EventPluginRegistry"); 2439 var EventPluginUtils = _dereq_("./EventPluginUtils"); 2440 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 2441 2442 var accumulate = _dereq_("./accumulate"); 2443 var forEachAccumulated = _dereq_("./forEachAccumulated"); 2444 var invariant = _dereq_("./invariant"); 2445 var isEventSupported = _dereq_("./isEventSupported"); 2446 var monitorCodeUse = _dereq_("./monitorCodeUse"); 2447 2448 /** 2449 * Internal store for event listeners 2450 */ 2451 var listenerBank = {}; 2452 2453 /** 2454 * Internal queue of events that have accumulated their dispatches and are 2455 * waiting to have their dispatches executed. 2456 */ 2457 var eventQueue = null; 2458 2459 /** 2460 * Dispatches an event and releases it back into the pool, unless persistent. 2461 * 2462 * @param {?object} event Synthetic event to be dispatched. 2463 * @private 2464 */ 2465 var executeDispatchesAndRelease = function(event) { 2466 if (event) { 2467 var executeDispatch = EventPluginUtils.executeDispatch; 2468 // Plugins can provide custom behavior when dispatching events. 2469 var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event); 2470 if (PluginModule && PluginModule.executeDispatch) { 2471 executeDispatch = PluginModule.executeDispatch; 2472 } 2473 EventPluginUtils.executeDispatchesInOrder(event, executeDispatch); 2474 2475 if (!event.isPersistent()) { 2476 event.constructor.release(event); 2477 } 2478 } 2479 }; 2480 2481 /** 2482 * - `InstanceHandle`: [required] Module that performs logical traversals of DOM 2483 * hierarchy given ids of the logical DOM elements involved. 2484 */ 2485 var InstanceHandle = null; 2486 2487 function validateInstanceHandle() { 2488 var invalid = !InstanceHandle|| 2489 !InstanceHandle.traverseTwoPhase || 2490 !InstanceHandle.traverseEnterLeave; 2491 if (invalid) { 2492 throw new Error('InstanceHandle not injected before use!'); 2493 } 2494 } 2495 2496 /** 2497 * This is a unified interface for event plugins to be installed and configured. 2498 * 2499 * Event plugins can implement the following properties: 2500 * 2501 * `extractEvents` {function(string, DOMEventTarget, string, object): *} 2502 * Required. When a top-level event is fired, this method is expected to 2503 * extract synthetic events that will in turn be queued and dispatched. 2504 * 2505 * `eventTypes` {object} 2506 * Optional, plugins that fire events must publish a mapping of registration 2507 * names that are used to register listeners. Values of this mapping must 2508 * be objects that contain `registrationName` or `phasedRegistrationNames`. 2509 * 2510 * `executeDispatch` {function(object, function, string)} 2511 * Optional, allows plugins to override how an event gets dispatched. By 2512 * default, the listener is simply invoked. 2513 * 2514 * Each plugin that is injected into `EventsPluginHub` is immediately operable. 2515 * 2516 * @public 2517 */ 2518 var EventPluginHub = { 2519 2520 /** 2521 * Methods for injecting dependencies. 2522 */ 2523 injection: { 2524 2525 /** 2526 * @param {object} InjectedMount 2527 * @public 2528 */ 2529 injectMount: EventPluginUtils.injection.injectMount, 2530 2531 /** 2532 * @param {object} InjectedInstanceHandle 2533 * @public 2534 */ 2535 injectInstanceHandle: function(InjectedInstanceHandle) { 2536 InstanceHandle = InjectedInstanceHandle; 2537 if ("production" !== "development") { 2538 validateInstanceHandle(); 2539 } 2540 }, 2541 2542 getInstanceHandle: function() { 2543 if ("production" !== "development") { 2544 validateInstanceHandle(); 2545 } 2546 return InstanceHandle; 2547 }, 2548 2549 /** 2550 * @param {array} InjectedEventPluginOrder 2551 * @public 2552 */ 2553 injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, 2554 2555 /** 2556 * @param {object} injectedNamesToPlugins Map from names to plugin modules. 2557 */ 2558 injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName 2559 2560 }, 2561 2562 eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs, 2563 2564 registrationNameModules: EventPluginRegistry.registrationNameModules, 2565 2566 /** 2567 * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent. 2568 * 2569 * @param {string} id ID of the DOM element. 2570 * @param {string} registrationName Name of listener (e.g. `onClick`). 2571 * @param {?function} listener The callback to store. 2572 */ 2573 putListener: function(id, registrationName, listener) { 2574 ("production" !== "development" ? invariant( 2575 ExecutionEnvironment.canUseDOM, 2576 'Cannot call putListener() in a non-DOM environment.' 2577 ) : invariant(ExecutionEnvironment.canUseDOM)); 2578 ("production" !== "development" ? invariant( 2579 !listener || typeof listener === 'function', 2580 'Expected %s listener to be a function, instead got type %s', 2581 registrationName, typeof listener 2582 ) : invariant(!listener || typeof listener === 'function')); 2583 2584 if ("production" !== "development") { 2585 // IE8 has no API for event capturing and the `onScroll` event doesn't 2586 // bubble. 2587 if (registrationName === 'onScroll' && 2588 !isEventSupported('scroll', true)) { 2589 monitorCodeUse('react_no_scroll_event'); 2590 console.warn('This browser doesn\'t support the `onScroll` event'); 2591 } 2592 } 2593 var bankForRegistrationName = 2594 listenerBank[registrationName] || (listenerBank[registrationName] = {}); 2595 bankForRegistrationName[id] = listener; 2596 }, 2597 2598 /** 2599 * @param {string} id ID of the DOM element. 2600 * @param {string} registrationName Name of listener (e.g. `onClick`). 2601 * @return {?function} The stored callback. 2602 */ 2603 getListener: function(id, registrationName) { 2604 var bankForRegistrationName = listenerBank[registrationName]; 2605 return bankForRegistrationName && bankForRegistrationName[id]; 2606 }, 2607 2608 /** 2609 * Deletes a listener from the registration bank. 2610 * 2611 * @param {string} id ID of the DOM element. 2612 * @param {string} registrationName Name of listener (e.g. `onClick`). 2613 */ 2614 deleteListener: function(id, registrationName) { 2615 var bankForRegistrationName = listenerBank[registrationName]; 2616 if (bankForRegistrationName) { 2617 delete bankForRegistrationName[id]; 2618 } 2619 }, 2620 2621 /** 2622 * Deletes all listeners for the DOM element with the supplied ID. 2623 * 2624 * @param {string} id ID of the DOM element. 2625 */ 2626 deleteAllListeners: function(id) { 2627 for (var registrationName in listenerBank) { 2628 delete listenerBank[registrationName][id]; 2629 } 2630 }, 2631 2632 /** 2633 * Allows registered plugins an opportunity to extract events from top-level 2634 * native browser events. 2635 * 2636 * @param {string} topLevelType Record from `EventConstants`. 2637 * @param {DOMEventTarget} topLevelTarget The listening component root node. 2638 * @param {string} topLevelTargetID ID of `topLevelTarget`. 2639 * @param {object} nativeEvent Native browser event. 2640 * @return {*} An accumulation of synthetic events. 2641 * @internal 2642 */ 2643 extractEvents: function( 2644 topLevelType, 2645 topLevelTarget, 2646 topLevelTargetID, 2647 nativeEvent) { 2648 var events; 2649 var plugins = EventPluginRegistry.plugins; 2650 for (var i = 0, l = plugins.length; i < l; i++) { 2651 // Not every plugin in the ordering may be loaded at runtime. 2652 var possiblePlugin = plugins[i]; 2653 if (possiblePlugin) { 2654 var extractedEvents = possiblePlugin.extractEvents( 2655 topLevelType, 2656 topLevelTarget, 2657 topLevelTargetID, 2658 nativeEvent 2659 ); 2660 if (extractedEvents) { 2661 events = accumulate(events, extractedEvents); 2662 } 2663 } 2664 } 2665 return events; 2666 }, 2667 2668 /** 2669 * Enqueues a synthetic event that should be dispatched when 2670 * `processEventQueue` is invoked. 2671 * 2672 * @param {*} events An accumulation of synthetic events. 2673 * @internal 2674 */ 2675 enqueueEvents: function(events) { 2676 if (events) { 2677 eventQueue = accumulate(eventQueue, events); 2678 } 2679 }, 2680 2681 /** 2682 * Dispatches all synthetic events on the event queue. 2683 * 2684 * @internal 2685 */ 2686 processEventQueue: function() { 2687 // Set `eventQueue` to null before processing it so that we can tell if more 2688 // events get enqueued while processing. 2689 var processingEventQueue = eventQueue; 2690 eventQueue = null; 2691 forEachAccumulated(processingEventQueue, executeDispatchesAndRelease); 2692 ("production" !== "development" ? invariant( 2693 !eventQueue, 2694 'processEventQueue(): Additional events were enqueued while processing ' + 2695 'an event queue. Support for this has not yet been implemented.' 2696 ) : invariant(!eventQueue)); 2697 }, 2698 2699 /** 2700 * These are needed for tests only. Do not use! 2701 */ 2702 __purge: function() { 2703 listenerBank = {}; 2704 }, 2705 2706 __getListenerBank: function() { 2707 return listenerBank; 2708 } 2709 2710 }; 2711 2712 module.exports = EventPluginHub; 2713 2714 },{"./EventPluginRegistry":18,"./EventPluginUtils":19,"./ExecutionEnvironment":21,"./accumulate":98,"./forEachAccumulated":114,"./invariant":125,"./isEventSupported":126,"./monitorCodeUse":138}],18:[function(_dereq_,module,exports){ 2715 /** 2716 * Copyright 2013-2014 Facebook, Inc. 2717 * 2718 * Licensed under the Apache License, Version 2.0 (the "License"); 2719 * you may not use this file except in compliance with the License. 2720 * You may obtain a copy of the License at 2721 * 2722 * http://www.apache.org/licenses/LICENSE-2.0 2723 * 2724 * Unless required by applicable law or agreed to in writing, software 2725 * distributed under the License is distributed on an "AS IS" BASIS, 2726 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2727 * See the License for the specific language governing permissions and 2728 * limitations under the License. 2729 * 2730 * @providesModule EventPluginRegistry 2731 * @typechecks static-only 2732 */ 2733 2734 "use strict"; 2735 2736 var invariant = _dereq_("./invariant"); 2737 2738 /** 2739 * Injectable ordering of event plugins. 2740 */ 2741 var EventPluginOrder = null; 2742 2743 /** 2744 * Injectable mapping from names to event plugin modules. 2745 */ 2746 var namesToPlugins = {}; 2747 2748 /** 2749 * Recomputes the plugin list using the injected plugins and plugin ordering. 2750 * 2751 * @private 2752 */ 2753 function recomputePluginOrdering() { 2754 if (!EventPluginOrder) { 2755 // Wait until an `EventPluginOrder` is injected. 2756 return; 2757 } 2758 for (var pluginName in namesToPlugins) { 2759 var PluginModule = namesToPlugins[pluginName]; 2760 var pluginIndex = EventPluginOrder.indexOf(pluginName); 2761 ("production" !== "development" ? invariant( 2762 pluginIndex > -1, 2763 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + 2764 'the plugin ordering, `%s`.', 2765 pluginName 2766 ) : invariant(pluginIndex > -1)); 2767 if (EventPluginRegistry.plugins[pluginIndex]) { 2768 continue; 2769 } 2770 ("production" !== "development" ? invariant( 2771 PluginModule.extractEvents, 2772 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + 2773 'method, but `%s` does not.', 2774 pluginName 2775 ) : invariant(PluginModule.extractEvents)); 2776 EventPluginRegistry.plugins[pluginIndex] = PluginModule; 2777 var publishedEvents = PluginModule.eventTypes; 2778 for (var eventName in publishedEvents) { 2779 ("production" !== "development" ? invariant( 2780 publishEventForPlugin( 2781 publishedEvents[eventName], 2782 PluginModule, 2783 eventName 2784 ), 2785 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', 2786 eventName, 2787 pluginName 2788 ) : invariant(publishEventForPlugin( 2789 publishedEvents[eventName], 2790 PluginModule, 2791 eventName 2792 ))); 2793 } 2794 } 2795 } 2796 2797 /** 2798 * Publishes an event so that it can be dispatched by the supplied plugin. 2799 * 2800 * @param {object} dispatchConfig Dispatch configuration for the event. 2801 * @param {object} PluginModule Plugin publishing the event. 2802 * @return {boolean} True if the event was successfully published. 2803 * @private 2804 */ 2805 function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { 2806 ("production" !== "development" ? invariant( 2807 !EventPluginRegistry.eventNameDispatchConfigs[eventName], 2808 'EventPluginHub: More than one plugin attempted to publish the same ' + 2809 'event name, `%s`.', 2810 eventName 2811 ) : invariant(!EventPluginRegistry.eventNameDispatchConfigs[eventName])); 2812 EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; 2813 2814 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; 2815 if (phasedRegistrationNames) { 2816 for (var phaseName in phasedRegistrationNames) { 2817 if (phasedRegistrationNames.hasOwnProperty(phaseName)) { 2818 var phasedRegistrationName = phasedRegistrationNames[phaseName]; 2819 publishRegistrationName( 2820 phasedRegistrationName, 2821 PluginModule, 2822 eventName 2823 ); 2824 } 2825 } 2826 return true; 2827 } else if (dispatchConfig.registrationName) { 2828 publishRegistrationName( 2829 dispatchConfig.registrationName, 2830 PluginModule, 2831 eventName 2832 ); 2833 return true; 2834 } 2835 return false; 2836 } 2837 2838 /** 2839 * Publishes a registration name that is used to identify dispatched events and 2840 * can be used with `EventPluginHub.putListener` to register listeners. 2841 * 2842 * @param {string} registrationName Registration name to add. 2843 * @param {object} PluginModule Plugin publishing the event. 2844 * @private 2845 */ 2846 function publishRegistrationName(registrationName, PluginModule, eventName) { 2847 ("production" !== "development" ? invariant( 2848 !EventPluginRegistry.registrationNameModules[registrationName], 2849 'EventPluginHub: More than one plugin attempted to publish the same ' + 2850 'registration name, `%s`.', 2851 registrationName 2852 ) : invariant(!EventPluginRegistry.registrationNameModules[registrationName])); 2853 EventPluginRegistry.registrationNameModules[registrationName] = PluginModule; 2854 EventPluginRegistry.registrationNameDependencies[registrationName] = 2855 PluginModule.eventTypes[eventName].dependencies; 2856 } 2857 2858 /** 2859 * Registers plugins so that they can extract and dispatch events. 2860 * 2861 * @see {EventPluginHub} 2862 */ 2863 var EventPluginRegistry = { 2864 2865 /** 2866 * Ordered list of injected plugins. 2867 */ 2868 plugins: [], 2869 2870 /** 2871 * Mapping from event name to dispatch config 2872 */ 2873 eventNameDispatchConfigs: {}, 2874 2875 /** 2876 * Mapping from registration name to plugin module 2877 */ 2878 registrationNameModules: {}, 2879 2880 /** 2881 * Mapping from registration name to event name 2882 */ 2883 registrationNameDependencies: {}, 2884 2885 /** 2886 * Injects an ordering of plugins (by plugin name). This allows the ordering 2887 * to be decoupled from injection of the actual plugins so that ordering is 2888 * always deterministic regardless of packaging, on-the-fly injection, etc. 2889 * 2890 * @param {array} InjectedEventPluginOrder 2891 * @internal 2892 * @see {EventPluginHub.injection.injectEventPluginOrder} 2893 */ 2894 injectEventPluginOrder: function(InjectedEventPluginOrder) { 2895 ("production" !== "development" ? invariant( 2896 !EventPluginOrder, 2897 'EventPluginRegistry: Cannot inject event plugin ordering more than once.' 2898 ) : invariant(!EventPluginOrder)); 2899 // Clone the ordering so it cannot be dynamically mutated. 2900 EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder); 2901 recomputePluginOrdering(); 2902 }, 2903 2904 /** 2905 * Injects plugins to be used by `EventPluginHub`. The plugin names must be 2906 * in the ordering injected by `injectEventPluginOrder`. 2907 * 2908 * Plugins can be injected as part of page initialization or on-the-fly. 2909 * 2910 * @param {object} injectedNamesToPlugins Map from names to plugin modules. 2911 * @internal 2912 * @see {EventPluginHub.injection.injectEventPluginsByName} 2913 */ 2914 injectEventPluginsByName: function(injectedNamesToPlugins) { 2915 var isOrderingDirty = false; 2916 for (var pluginName in injectedNamesToPlugins) { 2917 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { 2918 continue; 2919 } 2920 var PluginModule = injectedNamesToPlugins[pluginName]; 2921 if (namesToPlugins[pluginName] !== PluginModule) { 2922 ("production" !== "development" ? invariant( 2923 !namesToPlugins[pluginName], 2924 'EventPluginRegistry: Cannot inject two different event plugins ' + 2925 'using the same name, `%s`.', 2926 pluginName 2927 ) : invariant(!namesToPlugins[pluginName])); 2928 namesToPlugins[pluginName] = PluginModule; 2929 isOrderingDirty = true; 2930 } 2931 } 2932 if (isOrderingDirty) { 2933 recomputePluginOrdering(); 2934 } 2935 }, 2936 2937 /** 2938 * Looks up the plugin for the supplied event. 2939 * 2940 * @param {object} event A synthetic event. 2941 * @return {?object} The plugin that created the supplied event. 2942 * @internal 2943 */ 2944 getPluginModuleForEvent: function(event) { 2945 var dispatchConfig = event.dispatchConfig; 2946 if (dispatchConfig.registrationName) { 2947 return EventPluginRegistry.registrationNameModules[ 2948 dispatchConfig.registrationName 2949 ] || null; 2950 } 2951 for (var phase in dispatchConfig.phasedRegistrationNames) { 2952 if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) { 2953 continue; 2954 } 2955 var PluginModule = EventPluginRegistry.registrationNameModules[ 2956 dispatchConfig.phasedRegistrationNames[phase] 2957 ]; 2958 if (PluginModule) { 2959 return PluginModule; 2960 } 2961 } 2962 return null; 2963 }, 2964 2965 /** 2966 * Exposed for unit testing. 2967 * @private 2968 */ 2969 _resetEventPlugins: function() { 2970 EventPluginOrder = null; 2971 for (var pluginName in namesToPlugins) { 2972 if (namesToPlugins.hasOwnProperty(pluginName)) { 2973 delete namesToPlugins[pluginName]; 2974 } 2975 } 2976 EventPluginRegistry.plugins.length = 0; 2977 2978 var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs; 2979 for (var eventName in eventNameDispatchConfigs) { 2980 if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { 2981 delete eventNameDispatchConfigs[eventName]; 2982 } 2983 } 2984 2985 var registrationNameModules = EventPluginRegistry.registrationNameModules; 2986 for (var registrationName in registrationNameModules) { 2987 if (registrationNameModules.hasOwnProperty(registrationName)) { 2988 delete registrationNameModules[registrationName]; 2989 } 2990 } 2991 } 2992 2993 }; 2994 2995 module.exports = EventPluginRegistry; 2996 2997 },{"./invariant":125}],19:[function(_dereq_,module,exports){ 2998 /** 2999 * Copyright 2013-2014 Facebook, Inc. 3000 * 3001 * Licensed under the Apache License, Version 2.0 (the "License"); 3002 * you may not use this file except in compliance with the License. 3003 * You may obtain a copy of the License at 3004 * 3005 * http://www.apache.org/licenses/LICENSE-2.0 3006 * 3007 * Unless required by applicable law or agreed to in writing, software 3008 * distributed under the License is distributed on an "AS IS" BASIS, 3009 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3010 * See the License for the specific language governing permissions and 3011 * limitations under the License. 3012 * 3013 * @providesModule EventPluginUtils 3014 */ 3015 3016 "use strict"; 3017 3018 var EventConstants = _dereq_("./EventConstants"); 3019 3020 var invariant = _dereq_("./invariant"); 3021 3022 /** 3023 * Injected dependencies: 3024 */ 3025 3026 /** 3027 * - `Mount`: [required] Module that can convert between React dom IDs and 3028 * actual node references. 3029 */ 3030 var injection = { 3031 Mount: null, 3032 injectMount: function(InjectedMount) { 3033 injection.Mount = InjectedMount; 3034 if ("production" !== "development") { 3035 ("production" !== "development" ? invariant( 3036 InjectedMount && InjectedMount.getNode, 3037 'EventPluginUtils.injection.injectMount(...): Injected Mount module ' + 3038 'is missing getNode.' 3039 ) : invariant(InjectedMount && InjectedMount.getNode)); 3040 } 3041 } 3042 }; 3043 3044 var topLevelTypes = EventConstants.topLevelTypes; 3045 3046 function isEndish(topLevelType) { 3047 return topLevelType === topLevelTypes.topMouseUp || 3048 topLevelType === topLevelTypes.topTouchEnd || 3049 topLevelType === topLevelTypes.topTouchCancel; 3050 } 3051 3052 function isMoveish(topLevelType) { 3053 return topLevelType === topLevelTypes.topMouseMove || 3054 topLevelType === topLevelTypes.topTouchMove; 3055 } 3056 function isStartish(topLevelType) { 3057 return topLevelType === topLevelTypes.topMouseDown || 3058 topLevelType === topLevelTypes.topTouchStart; 3059 } 3060 3061 3062 var validateEventDispatches; 3063 if ("production" !== "development") { 3064 validateEventDispatches = function(event) { 3065 var dispatchListeners = event._dispatchListeners; 3066 var dispatchIDs = event._dispatchIDs; 3067 3068 var listenersIsArr = Array.isArray(dispatchListeners); 3069 var idsIsArr = Array.isArray(dispatchIDs); 3070 var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0; 3071 var listenersLen = listenersIsArr ? 3072 dispatchListeners.length : 3073 dispatchListeners ? 1 : 0; 3074 3075 ("production" !== "development" ? invariant( 3076 idsIsArr === listenersIsArr && IDsLen === listenersLen, 3077 'EventPluginUtils: Invalid `event`.' 3078 ) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen)); 3079 }; 3080 } 3081 3082 /** 3083 * Invokes `cb(event, listener, id)`. Avoids using call if no scope is 3084 * provided. The `(listener,id)` pair effectively forms the "dispatch" but are 3085 * kept separate to conserve memory. 3086 */ 3087 function forEachEventDispatch(event, cb) { 3088 var dispatchListeners = event._dispatchListeners; 3089 var dispatchIDs = event._dispatchIDs; 3090 if ("production" !== "development") { 3091 validateEventDispatches(event); 3092 } 3093 if (Array.isArray(dispatchListeners)) { 3094 for (var i = 0; i < dispatchListeners.length; i++) { 3095 if (event.isPropagationStopped()) { 3096 break; 3097 } 3098 // Listeners and IDs are two parallel arrays that are always in sync. 3099 cb(event, dispatchListeners[i], dispatchIDs[i]); 3100 } 3101 } else if (dispatchListeners) { 3102 cb(event, dispatchListeners, dispatchIDs); 3103 } 3104 } 3105 3106 /** 3107 * Default implementation of PluginModule.executeDispatch(). 3108 * @param {SyntheticEvent} SyntheticEvent to handle 3109 * @param {function} Application-level callback 3110 * @param {string} domID DOM id to pass to the callback. 3111 */ 3112 function executeDispatch(event, listener, domID) { 3113 event.currentTarget = injection.Mount.getNode(domID); 3114 var returnValue = listener(event, domID); 3115 event.currentTarget = null; 3116 return returnValue; 3117 } 3118 3119 /** 3120 * Standard/simple iteration through an event's collected dispatches. 3121 */ 3122 function executeDispatchesInOrder(event, executeDispatch) { 3123 forEachEventDispatch(event, executeDispatch); 3124 event._dispatchListeners = null; 3125 event._dispatchIDs = null; 3126 } 3127 3128 /** 3129 * Standard/simple iteration through an event's collected dispatches, but stops 3130 * at the first dispatch execution returning true, and returns that id. 3131 * 3132 * @return id of the first dispatch execution who's listener returns true, or 3133 * null if no listener returned true. 3134 */ 3135 function executeDispatchesInOrderStopAtTrue(event) { 3136 var dispatchListeners = event._dispatchListeners; 3137 var dispatchIDs = event._dispatchIDs; 3138 if ("production" !== "development") { 3139 validateEventDispatches(event); 3140 } 3141 if (Array.isArray(dispatchListeners)) { 3142 for (var i = 0; i < dispatchListeners.length; i++) { 3143 if (event.isPropagationStopped()) { 3144 break; 3145 } 3146 // Listeners and IDs are two parallel arrays that are always in sync. 3147 if (dispatchListeners[i](event, dispatchIDs[i])) { 3148 return dispatchIDs[i]; 3149 } 3150 } 3151 } else if (dispatchListeners) { 3152 if (dispatchListeners(event, dispatchIDs)) { 3153 return dispatchIDs; 3154 } 3155 } 3156 return null; 3157 } 3158 3159 /** 3160 * Execution of a "direct" dispatch - there must be at most one dispatch 3161 * accumulated on the event or it is considered an error. It doesn't really make 3162 * sense for an event with multiple dispatches (bubbled) to keep track of the 3163 * return values at each dispatch execution, but it does tend to make sense when 3164 * dealing with "direct" dispatches. 3165 * 3166 * @return The return value of executing the single dispatch. 3167 */ 3168 function executeDirectDispatch(event) { 3169 if ("production" !== "development") { 3170 validateEventDispatches(event); 3171 } 3172 var dispatchListener = event._dispatchListeners; 3173 var dispatchID = event._dispatchIDs; 3174 ("production" !== "development" ? invariant( 3175 !Array.isArray(dispatchListener), 3176 'executeDirectDispatch(...): Invalid `event`.' 3177 ) : invariant(!Array.isArray(dispatchListener))); 3178 var res = dispatchListener ? 3179 dispatchListener(event, dispatchID) : 3180 null; 3181 event._dispatchListeners = null; 3182 event._dispatchIDs = null; 3183 return res; 3184 } 3185 3186 /** 3187 * @param {SyntheticEvent} event 3188 * @return {bool} True iff number of dispatches accumulated is greater than 0. 3189 */ 3190 function hasDispatches(event) { 3191 return !!event._dispatchListeners; 3192 } 3193 3194 /** 3195 * General utilities that are useful in creating custom Event Plugins. 3196 */ 3197 var EventPluginUtils = { 3198 isEndish: isEndish, 3199 isMoveish: isMoveish, 3200 isStartish: isStartish, 3201 3202 executeDirectDispatch: executeDirectDispatch, 3203 executeDispatch: executeDispatch, 3204 executeDispatchesInOrder: executeDispatchesInOrder, 3205 executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, 3206 hasDispatches: hasDispatches, 3207 injection: injection, 3208 useTouchEvents: false 3209 }; 3210 3211 module.exports = EventPluginUtils; 3212 3213 },{"./EventConstants":15,"./invariant":125}],20:[function(_dereq_,module,exports){ 3214 /** 3215 * Copyright 2013-2014 Facebook, Inc. 3216 * 3217 * Licensed under the Apache License, Version 2.0 (the "License"); 3218 * you may not use this file except in compliance with the License. 3219 * You may obtain a copy of the License at 3220 * 3221 * http://www.apache.org/licenses/LICENSE-2.0 3222 * 3223 * Unless required by applicable law or agreed to in writing, software 3224 * distributed under the License is distributed on an "AS IS" BASIS, 3225 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3226 * See the License for the specific language governing permissions and 3227 * limitations under the License. 3228 * 3229 * @providesModule EventPropagators 3230 */ 3231 3232 "use strict"; 3233 3234 var EventConstants = _dereq_("./EventConstants"); 3235 var EventPluginHub = _dereq_("./EventPluginHub"); 3236 3237 var accumulate = _dereq_("./accumulate"); 3238 var forEachAccumulated = _dereq_("./forEachAccumulated"); 3239 3240 var PropagationPhases = EventConstants.PropagationPhases; 3241 var getListener = EventPluginHub.getListener; 3242 3243 /** 3244 * Some event types have a notion of different registration names for different 3245 * "phases" of propagation. This finds listeners by a given phase. 3246 */ 3247 function listenerAtPhase(id, event, propagationPhase) { 3248 var registrationName = 3249 event.dispatchConfig.phasedRegistrationNames[propagationPhase]; 3250 return getListener(id, registrationName); 3251 } 3252 3253 /** 3254 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function 3255 * here, allows us to not have to bind or create functions for each event. 3256 * Mutating the event's members allows us to not have to create a wrapping 3257 * "dispatch" object that pairs the event with the listener. 3258 */ 3259 function accumulateDirectionalDispatches(domID, upwards, event) { 3260 if ("production" !== "development") { 3261 if (!domID) { 3262 throw new Error('Dispatching id must not be null'); 3263 } 3264 } 3265 var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured; 3266 var listener = listenerAtPhase(domID, event, phase); 3267 if (listener) { 3268 event._dispatchListeners = accumulate(event._dispatchListeners, listener); 3269 event._dispatchIDs = accumulate(event._dispatchIDs, domID); 3270 } 3271 } 3272 3273 /** 3274 * Collect dispatches (must be entirely collected before dispatching - see unit 3275 * tests). Lazily allocate the array to conserve memory. We must loop through 3276 * each event and perform the traversal for each one. We can not perform a 3277 * single traversal for the entire collection of events because each event may 3278 * have a different target. 3279 */ 3280 function accumulateTwoPhaseDispatchesSingle(event) { 3281 if (event && event.dispatchConfig.phasedRegistrationNames) { 3282 EventPluginHub.injection.getInstanceHandle().traverseTwoPhase( 3283 event.dispatchMarker, 3284 accumulateDirectionalDispatches, 3285 event 3286 ); 3287 } 3288 } 3289 3290 3291 /** 3292 * Accumulates without regard to direction, does not look for phased 3293 * registration names. Same as `accumulateDirectDispatchesSingle` but without 3294 * requiring that the `dispatchMarker` be the same as the dispatched ID. 3295 */ 3296 function accumulateDispatches(id, ignoredDirection, event) { 3297 if (event && event.dispatchConfig.registrationName) { 3298 var registrationName = event.dispatchConfig.registrationName; 3299 var listener = getListener(id, registrationName); 3300 if (listener) { 3301 event._dispatchListeners = accumulate(event._dispatchListeners, listener); 3302 event._dispatchIDs = accumulate(event._dispatchIDs, id); 3303 } 3304 } 3305 } 3306 3307 /** 3308 * Accumulates dispatches on an `SyntheticEvent`, but only for the 3309 * `dispatchMarker`. 3310 * @param {SyntheticEvent} event 3311 */ 3312 function accumulateDirectDispatchesSingle(event) { 3313 if (event && event.dispatchConfig.registrationName) { 3314 accumulateDispatches(event.dispatchMarker, null, event); 3315 } 3316 } 3317 3318 function accumulateTwoPhaseDispatches(events) { 3319 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); 3320 } 3321 3322 function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) { 3323 EventPluginHub.injection.getInstanceHandle().traverseEnterLeave( 3324 fromID, 3325 toID, 3326 accumulateDispatches, 3327 leave, 3328 enter 3329 ); 3330 } 3331 3332 3333 function accumulateDirectDispatches(events) { 3334 forEachAccumulated(events, accumulateDirectDispatchesSingle); 3335 } 3336 3337 3338 3339 /** 3340 * A small set of propagation patterns, each of which will accept a small amount 3341 * of information, and generate a set of "dispatch ready event objects" - which 3342 * are sets of events that have already been annotated with a set of dispatched 3343 * listener functions/ids. The API is designed this way to discourage these 3344 * propagation strategies from actually executing the dispatches, since we 3345 * always want to collect the entire set of dispatches before executing event a 3346 * single one. 3347 * 3348 * @constructor EventPropagators 3349 */ 3350 var EventPropagators = { 3351 accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, 3352 accumulateDirectDispatches: accumulateDirectDispatches, 3353 accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches 3354 }; 3355 3356 module.exports = EventPropagators; 3357 3358 },{"./EventConstants":15,"./EventPluginHub":17,"./accumulate":98,"./forEachAccumulated":114}],21:[function(_dereq_,module,exports){ 3359 /** 3360 * Copyright 2013-2014 Facebook, Inc. 3361 * 3362 * Licensed under the Apache License, Version 2.0 (the "License"); 3363 * you may not use this file except in compliance with the License. 3364 * You may obtain a copy of the License at 3365 * 3366 * http://www.apache.org/licenses/LICENSE-2.0 3367 * 3368 * Unless required by applicable law or agreed to in writing, software 3369 * distributed under the License is distributed on an "AS IS" BASIS, 3370 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3371 * See the License for the specific language governing permissions and 3372 * limitations under the License. 3373 * 3374 * @providesModule ExecutionEnvironment 3375 */ 3376 3377 /*jslint evil: true */ 3378 3379 "use strict"; 3380 3381 var canUseDOM = typeof window !== 'undefined'; 3382 3383 /** 3384 * Simple, lightweight module assisting with the detection and context of 3385 * Worker. Helps avoid circular dependencies and allows code to reason about 3386 * whether or not they are in a Worker, even if they never include the main 3387 * `ReactWorker` dependency. 3388 */ 3389 var ExecutionEnvironment = { 3390 3391 canUseDOM: canUseDOM, 3392 3393 canUseWorkers: typeof Worker !== 'undefined', 3394 3395 canUseEventListeners: 3396 canUseDOM && (window.addEventListener || window.attachEvent), 3397 3398 isInWorker: !canUseDOM // For now, this is true - might change in the future. 3399 3400 }; 3401 3402 module.exports = ExecutionEnvironment; 3403 3404 },{}],22:[function(_dereq_,module,exports){ 3405 /** 3406 * Copyright 2013-2014 Facebook, Inc. 3407 * 3408 * Licensed under the Apache License, Version 2.0 (the "License"); 3409 * you may not use this file except in compliance with the License. 3410 * You may obtain a copy of the License at 3411 * 3412 * http://www.apache.org/licenses/LICENSE-2.0 3413 * 3414 * Unless required by applicable law or agreed to in writing, software 3415 * distributed under the License is distributed on an "AS IS" BASIS, 3416 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3417 * See the License for the specific language governing permissions and 3418 * limitations under the License. 3419 * 3420 * @providesModule LinkedStateMixin 3421 * @typechecks static-only 3422 */ 3423 3424 "use strict"; 3425 3426 var ReactLink = _dereq_("./ReactLink"); 3427 var ReactStateSetters = _dereq_("./ReactStateSetters"); 3428 3429 /** 3430 * A simple mixin around ReactLink.forState(). 3431 */ 3432 var LinkedStateMixin = { 3433 /** 3434 * Create a ReactLink that's linked to part of this component's state. The 3435 * ReactLink will have the current value of this.state[key] and will call 3436 * setState() when a change is requested. 3437 * 3438 * @param {string} key state key to update. Note: you may want to use keyOf() 3439 * if you're using Google Closure Compiler advanced mode. 3440 * @return {ReactLink} ReactLink instance linking to the state. 3441 */ 3442 linkState: function(key) { 3443 return new ReactLink( 3444 this.state[key], 3445 ReactStateSetters.createStateKeySetter(this, key) 3446 ); 3447 } 3448 }; 3449 3450 module.exports = LinkedStateMixin; 3451 3452 },{"./ReactLink":58,"./ReactStateSetters":75}],23:[function(_dereq_,module,exports){ 3453 /** 3454 * Copyright 2013-2014 Facebook, Inc. 3455 * 3456 * Licensed under the Apache License, Version 2.0 (the "License"); 3457 * you may not use this file except in compliance with the License. 3458 * You may obtain a copy of the License at 3459 * 3460 * http://www.apache.org/licenses/LICENSE-2.0 3461 * 3462 * Unless required by applicable law or agreed to in writing, software 3463 * distributed under the License is distributed on an "AS IS" BASIS, 3464 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3465 * See the License for the specific language governing permissions and 3466 * limitations under the License. 3467 * 3468 * @providesModule LinkedValueUtils 3469 * @typechecks static-only 3470 */ 3471 3472 "use strict"; 3473 3474 var ReactPropTypes = _dereq_("./ReactPropTypes"); 3475 3476 var invariant = _dereq_("./invariant"); 3477 var warning = _dereq_("./warning"); 3478 3479 var hasReadOnlyValue = { 3480 'button': true, 3481 'checkbox': true, 3482 'image': true, 3483 'hidden': true, 3484 'radio': true, 3485 'reset': true, 3486 'submit': true 3487 }; 3488 3489 function _assertSingleLink(input) { 3490 ("production" !== "development" ? invariant( 3491 input.props.checkedLink == null || input.props.valueLink == null, 3492 'Cannot provide a checkedLink and a valueLink. If you want to use ' + 3493 'checkedLink, you probably don\'t want to use valueLink and vice versa.' 3494 ) : invariant(input.props.checkedLink == null || input.props.valueLink == null)); 3495 } 3496 function _assertValueLink(input) { 3497 _assertSingleLink(input); 3498 ("production" !== "development" ? invariant( 3499 input.props.value == null && input.props.onChange == null, 3500 'Cannot provide a valueLink and a value or onChange event. If you want ' + 3501 'to use value or onChange, you probably don\'t want to use valueLink.' 3502 ) : invariant(input.props.value == null && input.props.onChange == null)); 3503 } 3504 3505 function _assertCheckedLink(input) { 3506 _assertSingleLink(input); 3507 ("production" !== "development" ? invariant( 3508 input.props.checked == null && input.props.onChange == null, 3509 'Cannot provide a checkedLink and a checked property or onChange event. ' + 3510 'If you want to use checked or onChange, you probably don\'t want to ' + 3511 'use checkedLink' 3512 ) : invariant(input.props.checked == null && input.props.onChange == null)); 3513 } 3514 3515 /** 3516 * @param {SyntheticEvent} e change event to handle 3517 */ 3518 function _handleLinkedValueChange(e) { 3519 /*jshint validthis:true */ 3520 this.props.valueLink.requestChange(e.target.value); 3521 } 3522 3523 /** 3524 * @param {SyntheticEvent} e change event to handle 3525 */ 3526 function _handleLinkedCheckChange(e) { 3527 /*jshint validthis:true */ 3528 this.props.checkedLink.requestChange(e.target.checked); 3529 } 3530 3531 /** 3532 * Provide a linked `value` attribute for controlled forms. You should not use 3533 * this outside of the ReactDOM controlled form components. 3534 */ 3535 var LinkedValueUtils = { 3536 Mixin: { 3537 propTypes: { 3538 value: function(props, propName, componentName) { 3539 if ("production" !== "development") { 3540 ("production" !== "development" ? warning( 3541 !props[propName] || 3542 hasReadOnlyValue[props.type] || 3543 props.onChange || 3544 props.readOnly || 3545 props.disabled, 3546 'You provided a `value` prop to a form field without an ' + 3547 '`onChange` handler. This will render a read-only field. If ' + 3548 'the field should be mutable use `defaultValue`. Otherwise, ' + 3549 'set either `onChange` or `readOnly`.' 3550 ) : null); 3551 } 3552 }, 3553 checked: function(props, propName, componentName) { 3554 if ("production" !== "development") { 3555 ("production" !== "development" ? warning( 3556 !props[propName] || 3557 props.onChange || 3558 props.readOnly || 3559 props.disabled, 3560 'You provided a `checked` prop to a form field without an ' + 3561 '`onChange` handler. This will render a read-only field. If ' + 3562 'the field should be mutable use `defaultChecked`. Otherwise, ' + 3563 'set either `onChange` or `readOnly`.' 3564 ) : null); 3565 } 3566 }, 3567 onChange: ReactPropTypes.func 3568 } 3569 }, 3570 3571 /** 3572 * @param {ReactComponent} input Form component 3573 * @return {*} current value of the input either from value prop or link. 3574 */ 3575 getValue: function(input) { 3576 if (input.props.valueLink) { 3577 _assertValueLink(input); 3578 return input.props.valueLink.value; 3579 } 3580 return input.props.value; 3581 }, 3582 3583 /** 3584 * @param {ReactComponent} input Form component 3585 * @return {*} current checked status of the input either from checked prop 3586 * or link. 3587 */ 3588 getChecked: function(input) { 3589 if (input.props.checkedLink) { 3590 _assertCheckedLink(input); 3591 return input.props.checkedLink.value; 3592 } 3593 return input.props.checked; 3594 }, 3595 3596 /** 3597 * @param {ReactComponent} input Form component 3598 * @return {function} change callback either from onChange prop or link. 3599 */ 3600 getOnChange: function(input) { 3601 if (input.props.valueLink) { 3602 _assertValueLink(input); 3603 return _handleLinkedValueChange; 3604 } else if (input.props.checkedLink) { 3605 _assertCheckedLink(input); 3606 return _handleLinkedCheckChange; 3607 } 3608 return input.props.onChange; 3609 } 3610 }; 3611 3612 module.exports = LinkedValueUtils; 3613 3614 },{"./ReactPropTypes":69,"./invariant":125,"./warning":148}],24:[function(_dereq_,module,exports){ 3615 /** 3616 * Copyright 2013-2014 Facebook, Inc. 3617 * 3618 * Licensed under the Apache License, Version 2.0 (the "License"); 3619 * you may not use this file except in compliance with the License. 3620 * You may obtain a copy of the License at 3621 * 3622 * http://www.apache.org/licenses/LICENSE-2.0 3623 * 3624 * Unless required by applicable law or agreed to in writing, software 3625 * distributed under the License is distributed on an "AS IS" BASIS, 3626 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3627 * See the License for the specific language governing permissions and 3628 * limitations under the License. 3629 * 3630 * @providesModule MobileSafariClickEventPlugin 3631 * @typechecks static-only 3632 */ 3633 3634 "use strict"; 3635 3636 var EventConstants = _dereq_("./EventConstants"); 3637 3638 var emptyFunction = _dereq_("./emptyFunction"); 3639 3640 var topLevelTypes = EventConstants.topLevelTypes; 3641 3642 /** 3643 * Mobile Safari does not fire properly bubble click events on non-interactive 3644 * elements, which means delegated click listeners do not fire. The workaround 3645 * for this bug involves attaching an empty click listener on the target node. 3646 * 3647 * This particular plugin works around the bug by attaching an empty click 3648 * listener on `touchstart` (which does fire on every element). 3649 */ 3650 var MobileSafariClickEventPlugin = { 3651 3652 eventTypes: null, 3653 3654 /** 3655 * @param {string} topLevelType Record from `EventConstants`. 3656 * @param {DOMEventTarget} topLevelTarget The listening component root node. 3657 * @param {string} topLevelTargetID ID of `topLevelTarget`. 3658 * @param {object} nativeEvent Native browser event. 3659 * @return {*} An accumulation of synthetic events. 3660 * @see {EventPluginHub.extractEvents} 3661 */ 3662 extractEvents: function( 3663 topLevelType, 3664 topLevelTarget, 3665 topLevelTargetID, 3666 nativeEvent) { 3667 if (topLevelType === topLevelTypes.topTouchStart) { 3668 var target = nativeEvent.target; 3669 if (target && !target.onclick) { 3670 target.onclick = emptyFunction; 3671 } 3672 } 3673 } 3674 3675 }; 3676 3677 module.exports = MobileSafariClickEventPlugin; 3678 3679 },{"./EventConstants":15,"./emptyFunction":109}],25:[function(_dereq_,module,exports){ 3680 /** 3681 * Copyright 2013-2014 Facebook, Inc. 3682 * 3683 * Licensed under the Apache License, Version 2.0 (the "License"); 3684 * you may not use this file except in compliance with the License. 3685 * You may obtain a copy of the License at 3686 * 3687 * http://www.apache.org/licenses/LICENSE-2.0 3688 * 3689 * Unless required by applicable law or agreed to in writing, software 3690 * distributed under the License is distributed on an "AS IS" BASIS, 3691 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3692 * See the License for the specific language governing permissions and 3693 * limitations under the License. 3694 * 3695 * @providesModule PooledClass 3696 */ 3697 3698 "use strict"; 3699 3700 var invariant = _dereq_("./invariant"); 3701 3702 /** 3703 * Static poolers. Several custom versions for each potential number of 3704 * arguments. A completely generic pooler is easy to implement, but would 3705 * require accessing the `arguments` object. In each of these, `this` refers to 3706 * the Class itself, not an instance. If any others are needed, simply add them 3707 * here, or in their own files. 3708 */ 3709 var oneArgumentPooler = function(copyFieldsFrom) { 3710 var Klass = this; 3711 if (Klass.instancePool.length) { 3712 var instance = Klass.instancePool.pop(); 3713 Klass.call(instance, copyFieldsFrom); 3714 return instance; 3715 } else { 3716 return new Klass(copyFieldsFrom); 3717 } 3718 }; 3719 3720 var twoArgumentPooler = function(a1, a2) { 3721 var Klass = this; 3722 if (Klass.instancePool.length) { 3723 var instance = Klass.instancePool.pop(); 3724 Klass.call(instance, a1, a2); 3725 return instance; 3726 } else { 3727 return new Klass(a1, a2); 3728 } 3729 }; 3730 3731 var threeArgumentPooler = function(a1, a2, a3) { 3732 var Klass = this; 3733 if (Klass.instancePool.length) { 3734 var instance = Klass.instancePool.pop(); 3735 Klass.call(instance, a1, a2, a3); 3736 return instance; 3737 } else { 3738 return new Klass(a1, a2, a3); 3739 } 3740 }; 3741 3742 var fiveArgumentPooler = function(a1, a2, a3, a4, a5) { 3743 var Klass = this; 3744 if (Klass.instancePool.length) { 3745 var instance = Klass.instancePool.pop(); 3746 Klass.call(instance, a1, a2, a3, a4, a5); 3747 return instance; 3748 } else { 3749 return new Klass(a1, a2, a3, a4, a5); 3750 } 3751 }; 3752 3753 var standardReleaser = function(instance) { 3754 var Klass = this; 3755 ("production" !== "development" ? invariant( 3756 instance instanceof Klass, 3757 'Trying to release an instance into a pool of a different type.' 3758 ) : invariant(instance instanceof Klass)); 3759 if (instance.destructor) { 3760 instance.destructor(); 3761 } 3762 if (Klass.instancePool.length < Klass.poolSize) { 3763 Klass.instancePool.push(instance); 3764 } 3765 }; 3766 3767 var DEFAULT_POOL_SIZE = 10; 3768 var DEFAULT_POOLER = oneArgumentPooler; 3769 3770 /** 3771 * Augments `CopyConstructor` to be a poolable class, augmenting only the class 3772 * itself (statically) not adding any prototypical fields. Any CopyConstructor 3773 * you give this may have a `poolSize` property, and will look for a 3774 * prototypical `destructor` on instances (optional). 3775 * 3776 * @param {Function} CopyConstructor Constructor that can be used to reset. 3777 * @param {Function} pooler Customizable pooler. 3778 */ 3779 var addPoolingTo = function(CopyConstructor, pooler) { 3780 var NewKlass = CopyConstructor; 3781 NewKlass.instancePool = []; 3782 NewKlass.getPooled = pooler || DEFAULT_POOLER; 3783 if (!NewKlass.poolSize) { 3784 NewKlass.poolSize = DEFAULT_POOL_SIZE; 3785 } 3786 NewKlass.release = standardReleaser; 3787 return NewKlass; 3788 }; 3789 3790 var PooledClass = { 3791 addPoolingTo: addPoolingTo, 3792 oneArgumentPooler: oneArgumentPooler, 3793 twoArgumentPooler: twoArgumentPooler, 3794 threeArgumentPooler: threeArgumentPooler, 3795 fiveArgumentPooler: fiveArgumentPooler 3796 }; 3797 3798 module.exports = PooledClass; 3799 3800 },{"./invariant":125}],26:[function(_dereq_,module,exports){ 3801 /** 3802 * Copyright 2013-2014 Facebook, Inc. 3803 * 3804 * Licensed under the Apache License, Version 2.0 (the "License"); 3805 * you may not use this file except in compliance with the License. 3806 * You may obtain a copy of the License at 3807 * 3808 * http://www.apache.org/licenses/LICENSE-2.0 3809 * 3810 * Unless required by applicable law or agreed to in writing, software 3811 * distributed under the License is distributed on an "AS IS" BASIS, 3812 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3813 * See the License for the specific language governing permissions and 3814 * limitations under the License. 3815 * 3816 * @providesModule React 3817 */ 3818 3819 "use strict"; 3820 3821 var DOMPropertyOperations = _dereq_("./DOMPropertyOperations"); 3822 var EventPluginUtils = _dereq_("./EventPluginUtils"); 3823 var ReactChildren = _dereq_("./ReactChildren"); 3824 var ReactComponent = _dereq_("./ReactComponent"); 3825 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 3826 var ReactContext = _dereq_("./ReactContext"); 3827 var ReactCurrentOwner = _dereq_("./ReactCurrentOwner"); 3828 var ReactDOM = _dereq_("./ReactDOM"); 3829 var ReactDOMComponent = _dereq_("./ReactDOMComponent"); 3830 var ReactDefaultInjection = _dereq_("./ReactDefaultInjection"); 3831 var ReactInstanceHandles = _dereq_("./ReactInstanceHandles"); 3832 var ReactMount = _dereq_("./ReactMount"); 3833 var ReactMultiChild = _dereq_("./ReactMultiChild"); 3834 var ReactPerf = _dereq_("./ReactPerf"); 3835 var ReactPropTypes = _dereq_("./ReactPropTypes"); 3836 var ReactServerRendering = _dereq_("./ReactServerRendering"); 3837 var ReactTextComponent = _dereq_("./ReactTextComponent"); 3838 3839 var onlyChild = _dereq_("./onlyChild"); 3840 3841 ReactDefaultInjection.inject(); 3842 3843 var React = { 3844 Children: { 3845 map: ReactChildren.map, 3846 forEach: ReactChildren.forEach, 3847 only: onlyChild 3848 }, 3849 DOM: ReactDOM, 3850 PropTypes: ReactPropTypes, 3851 initializeTouchEvents: function(shouldUseTouch) { 3852 EventPluginUtils.useTouchEvents = shouldUseTouch; 3853 }, 3854 createClass: ReactCompositeComponent.createClass, 3855 constructAndRenderComponent: ReactMount.constructAndRenderComponent, 3856 constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID, 3857 renderComponent: ReactPerf.measure( 3858 'React', 3859 'renderComponent', 3860 ReactMount.renderComponent 3861 ), 3862 renderComponentToString: ReactServerRendering.renderComponentToString, 3863 renderComponentToStaticMarkup: 3864 ReactServerRendering.renderComponentToStaticMarkup, 3865 unmountComponentAtNode: ReactMount.unmountComponentAtNode, 3866 isValidClass: ReactCompositeComponent.isValidClass, 3867 isValidComponent: ReactComponent.isValidComponent, 3868 withContext: ReactContext.withContext, 3869 __internals: { 3870 Component: ReactComponent, 3871 CurrentOwner: ReactCurrentOwner, 3872 DOMComponent: ReactDOMComponent, 3873 DOMPropertyOperations: DOMPropertyOperations, 3874 InstanceHandles: ReactInstanceHandles, 3875 Mount: ReactMount, 3876 MultiChild: ReactMultiChild, 3877 TextComponent: ReactTextComponent 3878 } 3879 }; 3880 3881 if ("production" !== "development") { 3882 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 3883 if (ExecutionEnvironment.canUseDOM && 3884 window.top === window.self && 3885 navigator.userAgent.indexOf('Chrome') > -1) { 3886 console.debug( 3887 'Download the React DevTools for a better development experience: ' + 3888 'http://fb.me/react-devtools' 3889 ); 3890 } 3891 } 3892 3893 // Version exists only in the open-source version of React, not in Facebook's 3894 // internal version. 3895 React.version = '0.10.0'; 3896 3897 module.exports = React; 3898 3899 },{"./DOMPropertyOperations":10,"./EventPluginUtils":19,"./ExecutionEnvironment":21,"./ReactChildren":30,"./ReactComponent":31,"./ReactCompositeComponent":33,"./ReactContext":34,"./ReactCurrentOwner":35,"./ReactDOM":36,"./ReactDOMComponent":38,"./ReactDefaultInjection":48,"./ReactInstanceHandles":57,"./ReactMount":60,"./ReactMultiChild":62,"./ReactPerf":65,"./ReactPropTypes":69,"./ReactServerRendering":73,"./ReactTextComponent":77,"./onlyChild":141}],27:[function(_dereq_,module,exports){ 3900 /** 3901 * Copyright 2013-2014 Facebook, Inc. 3902 * 3903 * Licensed under the Apache License, Version 2.0 (the "License"); 3904 * you may not use this file except in compliance with the License. 3905 * You may obtain a copy of the License at 3906 * 3907 * http://www.apache.org/licenses/LICENSE-2.0 3908 * 3909 * Unless required by applicable law or agreed to in writing, software 3910 * distributed under the License is distributed on an "AS IS" BASIS, 3911 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3912 * See the License for the specific language governing permissions and 3913 * limitations under the License. 3914 * 3915 * @providesModule ReactBrowserComponentMixin 3916 */ 3917 3918 "use strict"; 3919 3920 var ReactMount = _dereq_("./ReactMount"); 3921 3922 var invariant = _dereq_("./invariant"); 3923 3924 var ReactBrowserComponentMixin = { 3925 /** 3926 * Returns the DOM node rendered by this component. 3927 * 3928 * @return {DOMElement} The root node of this component. 3929 * @final 3930 * @protected 3931 */ 3932 getDOMNode: function() { 3933 ("production" !== "development" ? invariant( 3934 this.isMounted(), 3935 'getDOMNode(): A component must be mounted to have a DOM node.' 3936 ) : invariant(this.isMounted())); 3937 return ReactMount.getNode(this._rootNodeID); 3938 } 3939 }; 3940 3941 module.exports = ReactBrowserComponentMixin; 3942 3943 },{"./ReactMount":60,"./invariant":125}],28:[function(_dereq_,module,exports){ 3944 /** 3945 * Copyright 2013-2014 Facebook, Inc. 3946 * 3947 * Licensed under the Apache License, Version 2.0 (the "License"); 3948 * you may not use this file except in compliance with the License. 3949 * You may obtain a copy of the License at 3950 * 3951 * http://www.apache.org/licenses/LICENSE-2.0 3952 * 3953 * Unless required by applicable law or agreed to in writing, software 3954 * distributed under the License is distributed on an "AS IS" BASIS, 3955 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 3956 * See the License for the specific language governing permissions and 3957 * limitations under the License. 3958 * 3959 * @typechecks 3960 * @providesModule ReactCSSTransitionGroup 3961 */ 3962 3963 "use strict"; 3964 3965 var React = _dereq_("./React"); 3966 3967 var ReactTransitionGroup = _dereq_("./ReactTransitionGroup"); 3968 var ReactCSSTransitionGroupChild = _dereq_("./ReactCSSTransitionGroupChild"); 3969 3970 var ReactCSSTransitionGroup = React.createClass({ 3971 propTypes: { 3972 transitionName: React.PropTypes.string.isRequired, 3973 transitionEnter: React.PropTypes.bool, 3974 transitionLeave: React.PropTypes.bool 3975 }, 3976 3977 getDefaultProps: function() { 3978 return { 3979 transitionEnter: true, 3980 transitionLeave: true 3981 }; 3982 }, 3983 3984 _wrapChild: function(child) { 3985 // We need to provide this childFactory so that 3986 // ReactCSSTransitionGroupChild can receive updates to name, enter, and 3987 // leave while it is leaving. 3988 return ReactCSSTransitionGroupChild( 3989 { 3990 name: this.props.transitionName, 3991 enter: this.props.transitionEnter, 3992 leave: this.props.transitionLeave 3993 }, 3994 child 3995 ); 3996 }, 3997 3998 render: function() { 3999 return this.transferPropsTo( 4000 ReactTransitionGroup( 4001 {childFactory: this._wrapChild}, 4002 this.props.children 4003 ) 4004 ); 4005 } 4006 }); 4007 4008 module.exports = ReactCSSTransitionGroup; 4009 4010 },{"./React":26,"./ReactCSSTransitionGroupChild":29,"./ReactTransitionGroup":80}],29:[function(_dereq_,module,exports){ 4011 /** 4012 * Copyright 2013-2014 Facebook, Inc. 4013 * 4014 * Licensed under the Apache License, Version 2.0 (the "License"); 4015 * you may not use this file except in compliance with the License. 4016 * You may obtain a copy of the License at 4017 * 4018 * http://www.apache.org/licenses/LICENSE-2.0 4019 * 4020 * Unless required by applicable law or agreed to in writing, software 4021 * distributed under the License is distributed on an "AS IS" BASIS, 4022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4023 * See the License for the specific language governing permissions and 4024 * limitations under the License. 4025 * 4026 * @typechecks 4027 * @providesModule ReactCSSTransitionGroupChild 4028 */ 4029 4030 "use strict"; 4031 4032 var React = _dereq_("./React"); 4033 4034 var CSSCore = _dereq_("./CSSCore"); 4035 var ReactTransitionEvents = _dereq_("./ReactTransitionEvents"); 4036 4037 var onlyChild = _dereq_("./onlyChild"); 4038 4039 // We don't remove the element from the DOM until we receive an animationend or 4040 // transitionend event. If the user screws up and forgets to add an animation 4041 // their node will be stuck in the DOM forever, so we detect if an animation 4042 // does not start and if it doesn't, we just call the end listener immediately. 4043 var TICK = 17; 4044 var NO_EVENT_TIMEOUT = 5000; 4045 4046 var noEventListener = null; 4047 4048 4049 if ("production" !== "development") { 4050 noEventListener = function() { 4051 console.warn( 4052 'transition(): tried to perform an animation without ' + 4053 'an animationend or transitionend event after timeout (' + 4054 NO_EVENT_TIMEOUT + 'ms). You should either disable this ' + 4055 'transition in JS or add a CSS animation/transition.' 4056 ); 4057 }; 4058 } 4059 4060 var ReactCSSTransitionGroupChild = React.createClass({ 4061 transition: function(animationType, finishCallback) { 4062 var node = this.getDOMNode(); 4063 var className = this.props.name + '-' + animationType; 4064 var activeClassName = className + '-active'; 4065 var noEventTimeout = null; 4066 4067 var endListener = function() { 4068 if ("production" !== "development") { 4069 clearTimeout(noEventTimeout); 4070 } 4071 4072 CSSCore.removeClass(node, className); 4073 CSSCore.removeClass(node, activeClassName); 4074 4075 ReactTransitionEvents.removeEndEventListener(node, endListener); 4076 4077 // Usually this optional callback is used for informing an owner of 4078 // a leave animation and telling it to remove the child. 4079 finishCallback && finishCallback(); 4080 }; 4081 4082 ReactTransitionEvents.addEndEventListener(node, endListener); 4083 4084 CSSCore.addClass(node, className); 4085 4086 // Need to do this to actually trigger a transition. 4087 this.queueClass(activeClassName); 4088 4089 if ("production" !== "development") { 4090 noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT); 4091 } 4092 }, 4093 4094 queueClass: function(className) { 4095 this.classNameQueue.push(className); 4096 4097 if (this.props.runNextTick) { 4098 this.props.runNextTick(this.flushClassNameQueue); 4099 return; 4100 } 4101 4102 if (!this.timeout) { 4103 this.timeout = setTimeout(this.flushClassNameQueue, TICK); 4104 } 4105 }, 4106 4107 flushClassNameQueue: function() { 4108 if (this.isMounted()) { 4109 this.classNameQueue.forEach( 4110 CSSCore.addClass.bind(CSSCore, this.getDOMNode()) 4111 ); 4112 } 4113 this.classNameQueue.length = 0; 4114 this.timeout = null; 4115 }, 4116 4117 componentWillMount: function() { 4118 this.classNameQueue = []; 4119 }, 4120 4121 componentWillUnmount: function() { 4122 if (this.timeout) { 4123 clearTimeout(this.timeout); 4124 } 4125 }, 4126 4127 componentWillEnter: function(done) { 4128 if (this.props.enter) { 4129 this.transition('enter', done); 4130 } else { 4131 done(); 4132 } 4133 }, 4134 4135 componentWillLeave: function(done) { 4136 if (this.props.leave) { 4137 this.transition('leave', done); 4138 } else { 4139 done(); 4140 } 4141 }, 4142 4143 render: function() { 4144 return onlyChild(this.props.children); 4145 } 4146 }); 4147 4148 module.exports = ReactCSSTransitionGroupChild; 4149 4150 },{"./CSSCore":2,"./React":26,"./ReactTransitionEvents":79,"./onlyChild":141}],30:[function(_dereq_,module,exports){ 4151 /** 4152 * Copyright 2013-2014 Facebook, Inc. 4153 * 4154 * Licensed under the Apache License, Version 2.0 (the "License"); 4155 * you may not use this file except in compliance with the License. 4156 * You may obtain a copy of the License at 4157 * 4158 * http://www.apache.org/licenses/LICENSE-2.0 4159 * 4160 * Unless required by applicable law or agreed to in writing, software 4161 * distributed under the License is distributed on an "AS IS" BASIS, 4162 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4163 * See the License for the specific language governing permissions and 4164 * limitations under the License. 4165 * 4166 * @providesModule ReactChildren 4167 */ 4168 4169 "use strict"; 4170 4171 var PooledClass = _dereq_("./PooledClass"); 4172 4173 var invariant = _dereq_("./invariant"); 4174 var traverseAllChildren = _dereq_("./traverseAllChildren"); 4175 4176 var twoArgumentPooler = PooledClass.twoArgumentPooler; 4177 var threeArgumentPooler = PooledClass.threeArgumentPooler; 4178 4179 /** 4180 * PooledClass representing the bookkeeping associated with performing a child 4181 * traversal. Allows avoiding binding callbacks. 4182 * 4183 * @constructor ForEachBookKeeping 4184 * @param {!function} forEachFunction Function to perform traversal with. 4185 * @param {?*} forEachContext Context to perform context with. 4186 */ 4187 function ForEachBookKeeping(forEachFunction, forEachContext) { 4188 this.forEachFunction = forEachFunction; 4189 this.forEachContext = forEachContext; 4190 } 4191 PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); 4192 4193 function forEachSingleChild(traverseContext, child, name, i) { 4194 var forEachBookKeeping = traverseContext; 4195 forEachBookKeeping.forEachFunction.call( 4196 forEachBookKeeping.forEachContext, child, i); 4197 } 4198 4199 /** 4200 * Iterates through children that are typically specified as `props.children`. 4201 * 4202 * The provided forEachFunc(child, index) will be called for each 4203 * leaf child. 4204 * 4205 * @param {?*} children Children tree container. 4206 * @param {function(*, int)} forEachFunc. 4207 * @param {*} forEachContext Context for forEachContext. 4208 */ 4209 function forEachChildren(children, forEachFunc, forEachContext) { 4210 if (children == null) { 4211 return children; 4212 } 4213 4214 var traverseContext = 4215 ForEachBookKeeping.getPooled(forEachFunc, forEachContext); 4216 traverseAllChildren(children, forEachSingleChild, traverseContext); 4217 ForEachBookKeeping.release(traverseContext); 4218 } 4219 4220 /** 4221 * PooledClass representing the bookkeeping associated with performing a child 4222 * mapping. Allows avoiding binding callbacks. 4223 * 4224 * @constructor MapBookKeeping 4225 * @param {!*} mapResult Object containing the ordered map of results. 4226 * @param {!function} mapFunction Function to perform mapping with. 4227 * @param {?*} mapContext Context to perform mapping with. 4228 */ 4229 function MapBookKeeping(mapResult, mapFunction, mapContext) { 4230 this.mapResult = mapResult; 4231 this.mapFunction = mapFunction; 4232 this.mapContext = mapContext; 4233 } 4234 PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler); 4235 4236 function mapSingleChildIntoContext(traverseContext, child, name, i) { 4237 var mapBookKeeping = traverseContext; 4238 var mapResult = mapBookKeeping.mapResult; 4239 var mappedChild = 4240 mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i); 4241 // We found a component instance 4242 ("production" !== "development" ? invariant( 4243 !mapResult.hasOwnProperty(name), 4244 'ReactChildren.map(...): Encountered two children with the same key, ' + 4245 '`%s`. Children keys must be unique.', 4246 name 4247 ) : invariant(!mapResult.hasOwnProperty(name))); 4248 mapResult[name] = mappedChild; 4249 } 4250 4251 /** 4252 * Maps children that are typically specified as `props.children`. 4253 * 4254 * The provided mapFunction(child, key, index) will be called for each 4255 * leaf child. 4256 * 4257 * TODO: This may likely break any calls to `ReactChildren.map` that were 4258 * previously relying on the fact that we guarded against null children. 4259 * 4260 * @param {?*} children Children tree container. 4261 * @param {function(*, int)} mapFunction. 4262 * @param {*} mapContext Context for mapFunction. 4263 * @return {object} Object containing the ordered map of results. 4264 */ 4265 function mapChildren(children, func, context) { 4266 if (children == null) { 4267 return children; 4268 } 4269 4270 var mapResult = {}; 4271 var traverseContext = MapBookKeeping.getPooled(mapResult, func, context); 4272 traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); 4273 MapBookKeeping.release(traverseContext); 4274 return mapResult; 4275 } 4276 4277 var ReactChildren = { 4278 forEach: forEachChildren, 4279 map: mapChildren 4280 }; 4281 4282 module.exports = ReactChildren; 4283 4284 },{"./PooledClass":25,"./invariant":125,"./traverseAllChildren":146}],31:[function(_dereq_,module,exports){ 4285 /** 4286 * Copyright 2013-2014 Facebook, Inc. 4287 * 4288 * Licensed under the Apache License, Version 2.0 (the "License"); 4289 * you may not use this file except in compliance with the License. 4290 * You may obtain a copy of the License at 4291 * 4292 * http://www.apache.org/licenses/LICENSE-2.0 4293 * 4294 * Unless required by applicable law or agreed to in writing, software 4295 * distributed under the License is distributed on an "AS IS" BASIS, 4296 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4297 * See the License for the specific language governing permissions and 4298 * limitations under the License. 4299 * 4300 * @providesModule ReactComponent 4301 */ 4302 4303 "use strict"; 4304 4305 var ReactCurrentOwner = _dereq_("./ReactCurrentOwner"); 4306 var ReactOwner = _dereq_("./ReactOwner"); 4307 var ReactUpdates = _dereq_("./ReactUpdates"); 4308 4309 var invariant = _dereq_("./invariant"); 4310 var keyMirror = _dereq_("./keyMirror"); 4311 var merge = _dereq_("./merge"); 4312 var monitorCodeUse = _dereq_("./monitorCodeUse"); 4313 4314 /** 4315 * Every React component is in one of these life cycles. 4316 */ 4317 var ComponentLifeCycle = keyMirror({ 4318 /** 4319 * Mounted components have a DOM node representation and are capable of 4320 * receiving new props. 4321 */ 4322 MOUNTED: null, 4323 /** 4324 * Unmounted components are inactive and cannot receive new props. 4325 */ 4326 UNMOUNTED: null 4327 }); 4328 4329 /** 4330 * Warn if there's no key explicitly set on dynamic arrays of children or 4331 * object keys are not valid. This allows us to keep track of children between 4332 * updates. 4333 */ 4334 4335 var ownerHasExplicitKeyWarning = {}; 4336 var ownerHasPropertyWarning = {}; 4337 var ownerHasMonitoredObjectMap = {}; 4338 4339 var NUMERIC_PROPERTY_REGEX = /^\d+$/; 4340 4341 var injected = false; 4342 4343 /** 4344 * Optionally injectable environment dependent cleanup hook. (server vs. 4345 * browser etc). Example: A browser system caches DOM nodes based on component 4346 * ID and must remove that cache entry when this instance is unmounted. 4347 * 4348 * @private 4349 */ 4350 var unmountIDFromEnvironment = null; 4351 4352 /** 4353 * The "image" of a component tree, is the platform specific (typically 4354 * serialized) data that represents a tree of lower level UI building blocks. 4355 * On the web, this "image" is HTML markup which describes a construction of 4356 * low level `div` and `span` nodes. Other platforms may have different 4357 * encoding of this "image". This must be injected. 4358 * 4359 * @private 4360 */ 4361 var mountImageIntoNode = null; 4362 4363 /** 4364 * Warn if the component doesn't have an explicit key assigned to it. 4365 * This component is in an array. The array could grow and shrink or be 4366 * reordered. All children that haven't already been validated are required to 4367 * have a "key" property assigned to it. 4368 * 4369 * @internal 4370 * @param {ReactComponent} component Component that requires a key. 4371 */ 4372 function validateExplicitKey(component) { 4373 if (component.__keyValidated__ || component.props.key != null) { 4374 return; 4375 } 4376 component.__keyValidated__ = true; 4377 4378 // We can't provide friendly warnings for top level components. 4379 if (!ReactCurrentOwner.current) { 4380 return; 4381 } 4382 4383 // Name of the component whose render method tried to pass children. 4384 var currentName = ReactCurrentOwner.current.constructor.displayName; 4385 if (ownerHasExplicitKeyWarning.hasOwnProperty(currentName)) { 4386 return; 4387 } 4388 ownerHasExplicitKeyWarning[currentName] = true; 4389 4390 var message = 'Each child in an array should have a unique "key" prop. ' + 4391 'Check the render method of ' + currentName + '.'; 4392 4393 var childOwnerName = null; 4394 if (!component.isOwnedBy(ReactCurrentOwner.current)) { 4395 // Name of the component that originally created this child. 4396 childOwnerName = 4397 component._owner && 4398 component._owner.constructor.displayName; 4399 4400 // Usually the current owner is the offender, but if it accepts 4401 // children as a property, it may be the creator of the child that's 4402 // responsible for assigning it a key. 4403 message += ' It was passed a child from ' + childOwnerName + '.'; 4404 } 4405 4406 message += ' See http://fb.me/react-warning-keys for more information.'; 4407 monitorCodeUse('react_key_warning', { 4408 component: currentName, 4409 componentOwner: childOwnerName 4410 }); 4411 console.warn(message); 4412 } 4413 4414 /** 4415 * Warn if the key is being defined as an object property but has an incorrect 4416 * value. 4417 * 4418 * @internal 4419 * @param {string} name Property name of the key. 4420 * @param {ReactComponent} component Component that requires a key. 4421 */ 4422 function validatePropertyKey(name) { 4423 if (NUMERIC_PROPERTY_REGEX.test(name)) { 4424 // Name of the component whose render method tried to pass children. 4425 var currentName = ReactCurrentOwner.current.constructor.displayName; 4426 if (ownerHasPropertyWarning.hasOwnProperty(currentName)) { 4427 return; 4428 } 4429 ownerHasPropertyWarning[currentName] = true; 4430 4431 monitorCodeUse('react_numeric_key_warning'); 4432 console.warn( 4433 'Child objects should have non-numeric keys so ordering is preserved. ' + 4434 'Check the render method of ' + currentName + '. ' + 4435 'See http://fb.me/react-warning-keys for more information.' 4436 ); 4437 } 4438 } 4439 4440 /** 4441 * Log that we're using an object map. We're considering deprecating this 4442 * feature and replace it with proper Map and ImmutableMap data structures. 4443 * 4444 * @internal 4445 */ 4446 function monitorUseOfObjectMap() { 4447 // Name of the component whose render method tried to pass children. 4448 // We only use this to avoid spewing the logs. We lose additional 4449 // owner stacks but hopefully one level is enough to trace the source. 4450 var currentName = (ReactCurrentOwner.current && 4451 ReactCurrentOwner.current.constructor.displayName) || ''; 4452 if (ownerHasMonitoredObjectMap.hasOwnProperty(currentName)) { 4453 return; 4454 } 4455 ownerHasMonitoredObjectMap[currentName] = true; 4456 monitorCodeUse('react_object_map_children'); 4457 } 4458 4459 /** 4460 * Ensure that every component either is passed in a static location, in an 4461 * array with an explicit keys property defined, or in an object literal 4462 * with valid key property. 4463 * 4464 * @internal 4465 * @param {*} component Statically passed child of any type. 4466 * @return {boolean} 4467 */ 4468 function validateChildKeys(component) { 4469 if (Array.isArray(component)) { 4470 for (var i = 0; i < component.length; i++) { 4471 var child = component[i]; 4472 if (ReactComponent.isValidComponent(child)) { 4473 validateExplicitKey(child); 4474 } 4475 } 4476 } else if (ReactComponent.isValidComponent(component)) { 4477 // This component was passed in a valid location. 4478 component.__keyValidated__ = true; 4479 } else if (component && typeof component === 'object') { 4480 monitorUseOfObjectMap(); 4481 for (var name in component) { 4482 validatePropertyKey(name, component); 4483 } 4484 } 4485 } 4486 4487 /** 4488 * Components are the basic units of composition in React. 4489 * 4490 * Every component accepts a set of keyed input parameters known as "props" that 4491 * are initialized by the constructor. Once a component is mounted, the props 4492 * can be mutated using `setProps` or `replaceProps`. 4493 * 4494 * Every component is capable of the following operations: 4495 * 4496 * `mountComponent` 4497 * Initializes the component, renders markup, and registers event listeners. 4498 * 4499 * `receiveComponent` 4500 * Updates the rendered DOM nodes to match the given component. 4501 * 4502 * `unmountComponent` 4503 * Releases any resources allocated by this component. 4504 * 4505 * Components can also be "owned" by other components. Being owned by another 4506 * component means being constructed by that component. This is different from 4507 * being the child of a component, which means having a DOM representation that 4508 * is a child of the DOM representation of that component. 4509 * 4510 * @class ReactComponent 4511 */ 4512 var ReactComponent = { 4513 4514 injection: { 4515 injectEnvironment: function(ReactComponentEnvironment) { 4516 ("production" !== "development" ? invariant( 4517 !injected, 4518 'ReactComponent: injectEnvironment() can only be called once.' 4519 ) : invariant(!injected)); 4520 mountImageIntoNode = ReactComponentEnvironment.mountImageIntoNode; 4521 unmountIDFromEnvironment = 4522 ReactComponentEnvironment.unmountIDFromEnvironment; 4523 ReactComponent.BackendIDOperations = 4524 ReactComponentEnvironment.BackendIDOperations; 4525 ReactComponent.ReactReconcileTransaction = 4526 ReactComponentEnvironment.ReactReconcileTransaction; 4527 injected = true; 4528 } 4529 }, 4530 4531 /** 4532 * @param {?object} object 4533 * @return {boolean} True if `object` is a valid component. 4534 * @final 4535 */ 4536 isValidComponent: function(object) { 4537 if (!object || !object.type || !object.type.prototype) { 4538 return false; 4539 } 4540 // This is the safer way of duck checking the type of instance this is. 4541 // The object can be a generic descriptor but the type property refers to 4542 // the constructor and it's prototype can be used to inspect the type that 4543 // will actually get mounted. 4544 var prototype = object.type.prototype; 4545 return ( 4546 typeof prototype.mountComponentIntoNode === 'function' && 4547 typeof prototype.receiveComponent === 'function' 4548 ); 4549 }, 4550 4551 /** 4552 * @internal 4553 */ 4554 LifeCycle: ComponentLifeCycle, 4555 4556 /** 4557 * Injected module that provides ability to mutate individual properties. 4558 * Injected into the base class because many different subclasses need access 4559 * to this. 4560 * 4561 * @internal 4562 */ 4563 BackendIDOperations: null, 4564 4565 /** 4566 * React references `ReactReconcileTransaction` using this property in order 4567 * to allow dependency injection. 4568 * 4569 * @internal 4570 */ 4571 ReactReconcileTransaction: null, 4572 4573 /** 4574 * Base functionality for every ReactComponent constructor. Mixed into the 4575 * `ReactComponent` prototype, but exposed statically for easy access. 4576 * 4577 * @lends {ReactComponent.prototype} 4578 */ 4579 Mixin: { 4580 4581 /** 4582 * Checks whether or not this component is mounted. 4583 * 4584 * @return {boolean} True if mounted, false otherwise. 4585 * @final 4586 * @protected 4587 */ 4588 isMounted: function() { 4589 return this._lifeCycleState === ComponentLifeCycle.MOUNTED; 4590 }, 4591 4592 /** 4593 * Sets a subset of the props. 4594 * 4595 * @param {object} partialProps Subset of the next props. 4596 * @param {?function} callback Called after props are updated. 4597 * @final 4598 * @public 4599 */ 4600 setProps: function(partialProps, callback) { 4601 // Merge with `_pendingProps` if it exists, otherwise with existing props. 4602 this.replaceProps( 4603 merge(this._pendingProps || this.props, partialProps), 4604 callback 4605 ); 4606 }, 4607 4608 /** 4609 * Replaces all of the props. 4610 * 4611 * @param {object} props New props. 4612 * @param {?function} callback Called after props are updated. 4613 * @final 4614 * @public 4615 */ 4616 replaceProps: function(props, callback) { 4617 ("production" !== "development" ? invariant( 4618 this.isMounted(), 4619 'replaceProps(...): Can only update a mounted component.' 4620 ) : invariant(this.isMounted())); 4621 ("production" !== "development" ? invariant( 4622 this._mountDepth === 0, 4623 'replaceProps(...): You called `setProps` or `replaceProps` on a ' + 4624 'component with a parent. This is an anti-pattern since props will ' + 4625 'get reactively updated when rendered. Instead, change the owner\'s ' + 4626 '`render` method to pass the correct value as props to the component ' + 4627 'where it is created.' 4628 ) : invariant(this._mountDepth === 0)); 4629 this._pendingProps = props; 4630 ReactUpdates.enqueueUpdate(this, callback); 4631 }, 4632 4633 /** 4634 * Base constructor for all React components. 4635 * 4636 * Subclasses that override this method should make sure to invoke 4637 * `ReactComponent.Mixin.construct.call(this, ...)`. 4638 * 4639 * @param {?object} initialProps 4640 * @param {*} children 4641 * @internal 4642 */ 4643 construct: function(initialProps, children) { 4644 this.props = initialProps || {}; 4645 // Record the component responsible for creating this component. 4646 this._owner = ReactCurrentOwner.current; 4647 // All components start unmounted. 4648 this._lifeCycleState = ComponentLifeCycle.UNMOUNTED; 4649 4650 this._pendingProps = null; 4651 this._pendingCallbacks = null; 4652 4653 // Unlike _pendingProps and _pendingCallbacks, we won't use null to 4654 // indicate that nothing is pending because it's possible for a component 4655 // to have a null owner. Instead, an owner change is pending when 4656 // this._owner !== this._pendingOwner. 4657 this._pendingOwner = this._owner; 4658 4659 // Children can be more than one argument 4660 var childrenLength = arguments.length - 1; 4661 if (childrenLength === 1) { 4662 if ("production" !== "development") { 4663 validateChildKeys(children); 4664 } 4665 this.props.children = children; 4666 } else if (childrenLength > 1) { 4667 var childArray = Array(childrenLength); 4668 for (var i = 0; i < childrenLength; i++) { 4669 if ("production" !== "development") { 4670 validateChildKeys(arguments[i + 1]); 4671 } 4672 childArray[i] = arguments[i + 1]; 4673 } 4674 this.props.children = childArray; 4675 } 4676 }, 4677 4678 /** 4679 * Initializes the component, renders markup, and registers event listeners. 4680 * 4681 * NOTE: This does not insert any nodes into the DOM. 4682 * 4683 * Subclasses that override this method should make sure to invoke 4684 * `ReactComponent.Mixin.mountComponent.call(this, ...)`. 4685 * 4686 * @param {string} rootID DOM ID of the root node. 4687 * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction 4688 * @param {number} mountDepth number of components in the owner hierarchy. 4689 * @return {?string} Rendered markup to be inserted into the DOM. 4690 * @internal 4691 */ 4692 mountComponent: function(rootID, transaction, mountDepth) { 4693 ("production" !== "development" ? invariant( 4694 !this.isMounted(), 4695 'mountComponent(%s, ...): Can only mount an unmounted component. ' + 4696 'Make sure to avoid storing components between renders or reusing a ' + 4697 'single component instance in multiple places.', 4698 rootID 4699 ) : invariant(!this.isMounted())); 4700 var props = this.props; 4701 if (props.ref != null) { 4702 ReactOwner.addComponentAsRefTo(this, props.ref, this._owner); 4703 } 4704 this._rootNodeID = rootID; 4705 this._lifeCycleState = ComponentLifeCycle.MOUNTED; 4706 this._mountDepth = mountDepth; 4707 // Effectively: return ''; 4708 }, 4709 4710 /** 4711 * Releases any resources allocated by `mountComponent`. 4712 * 4713 * NOTE: This does not remove any nodes from the DOM. 4714 * 4715 * Subclasses that override this method should make sure to invoke 4716 * `ReactComponent.Mixin.unmountComponent.call(this)`. 4717 * 4718 * @internal 4719 */ 4720 unmountComponent: function() { 4721 ("production" !== "development" ? invariant( 4722 this.isMounted(), 4723 'unmountComponent(): Can only unmount a mounted component.' 4724 ) : invariant(this.isMounted())); 4725 var props = this.props; 4726 if (props.ref != null) { 4727 ReactOwner.removeComponentAsRefFrom(this, props.ref, this._owner); 4728 } 4729 unmountIDFromEnvironment(this._rootNodeID); 4730 this._rootNodeID = null; 4731 this._lifeCycleState = ComponentLifeCycle.UNMOUNTED; 4732 }, 4733 4734 /** 4735 * Given a new instance of this component, updates the rendered DOM nodes 4736 * as if that instance was rendered instead. 4737 * 4738 * Subclasses that override this method should make sure to invoke 4739 * `ReactComponent.Mixin.receiveComponent.call(this, ...)`. 4740 * 4741 * @param {object} nextComponent Next set of properties. 4742 * @param {ReactReconcileTransaction} transaction 4743 * @internal 4744 */ 4745 receiveComponent: function(nextComponent, transaction) { 4746 ("production" !== "development" ? invariant( 4747 this.isMounted(), 4748 'receiveComponent(...): Can only update a mounted component.' 4749 ) : invariant(this.isMounted())); 4750 this._pendingOwner = nextComponent._owner; 4751 this._pendingProps = nextComponent.props; 4752 this._performUpdateIfNecessary(transaction); 4753 }, 4754 4755 /** 4756 * Call `_performUpdateIfNecessary` within a new transaction. 4757 * 4758 * @internal 4759 */ 4760 performUpdateIfNecessary: function() { 4761 var transaction = ReactComponent.ReactReconcileTransaction.getPooled(); 4762 transaction.perform(this._performUpdateIfNecessary, this, transaction); 4763 ReactComponent.ReactReconcileTransaction.release(transaction); 4764 }, 4765 4766 /** 4767 * If `_pendingProps` is set, update the component. 4768 * 4769 * @param {ReactReconcileTransaction} transaction 4770 * @internal 4771 */ 4772 _performUpdateIfNecessary: function(transaction) { 4773 if (this._pendingProps == null) { 4774 return; 4775 } 4776 var prevProps = this.props; 4777 var prevOwner = this._owner; 4778 this.props = this._pendingProps; 4779 this._owner = this._pendingOwner; 4780 this._pendingProps = null; 4781 this.updateComponent(transaction, prevProps, prevOwner); 4782 }, 4783 4784 /** 4785 * Updates the component's currently mounted representation. 4786 * 4787 * @param {ReactReconcileTransaction} transaction 4788 * @param {object} prevProps 4789 * @internal 4790 */ 4791 updateComponent: function(transaction, prevProps, prevOwner) { 4792 var props = this.props; 4793 // If either the owner or a `ref` has changed, make sure the newest owner 4794 // has stored a reference to `this`, and the previous owner (if different) 4795 // has forgotten the reference to `this`. 4796 if (this._owner !== prevOwner || props.ref !== prevProps.ref) { 4797 if (prevProps.ref != null) { 4798 ReactOwner.removeComponentAsRefFrom( 4799 this, prevProps.ref, prevOwner 4800 ); 4801 } 4802 // Correct, even if the owner is the same, and only the ref has changed. 4803 if (props.ref != null) { 4804 ReactOwner.addComponentAsRefTo(this, props.ref, this._owner); 4805 } 4806 } 4807 }, 4808 4809 /** 4810 * Mounts this component and inserts it into the DOM. 4811 * 4812 * @param {string} rootID DOM ID of the root node. 4813 * @param {DOMElement} container DOM element to mount into. 4814 * @param {boolean} shouldReuseMarkup If true, do not insert markup 4815 * @final 4816 * @internal 4817 * @see {ReactMount.renderComponent} 4818 */ 4819 mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) { 4820 var transaction = ReactComponent.ReactReconcileTransaction.getPooled(); 4821 transaction.perform( 4822 this._mountComponentIntoNode, 4823 this, 4824 rootID, 4825 container, 4826 transaction, 4827 shouldReuseMarkup 4828 ); 4829 ReactComponent.ReactReconcileTransaction.release(transaction); 4830 }, 4831 4832 /** 4833 * @param {string} rootID DOM ID of the root node. 4834 * @param {DOMElement} container DOM element to mount into. 4835 * @param {ReactReconcileTransaction} transaction 4836 * @param {boolean} shouldReuseMarkup If true, do not insert markup 4837 * @final 4838 * @private 4839 */ 4840 _mountComponentIntoNode: function( 4841 rootID, 4842 container, 4843 transaction, 4844 shouldReuseMarkup) { 4845 var markup = this.mountComponent(rootID, transaction, 0); 4846 mountImageIntoNode(markup, container, shouldReuseMarkup); 4847 }, 4848 4849 /** 4850 * Checks if this component is owned by the supplied `owner` component. 4851 * 4852 * @param {ReactComponent} owner Component to check. 4853 * @return {boolean} True if `owners` owns this component. 4854 * @final 4855 * @internal 4856 */ 4857 isOwnedBy: function(owner) { 4858 return this._owner === owner; 4859 }, 4860 4861 /** 4862 * Gets another component, that shares the same owner as this one, by ref. 4863 * 4864 * @param {string} ref of a sibling Component. 4865 * @return {?ReactComponent} the actual sibling Component. 4866 * @final 4867 * @internal 4868 */ 4869 getSiblingByRef: function(ref) { 4870 var owner = this._owner; 4871 if (!owner || !owner.refs) { 4872 return null; 4873 } 4874 return owner.refs[ref]; 4875 } 4876 } 4877 }; 4878 4879 module.exports = ReactComponent; 4880 4881 },{"./ReactCurrentOwner":35,"./ReactOwner":64,"./ReactUpdates":81,"./invariant":125,"./keyMirror":131,"./merge":134,"./monitorCodeUse":138}],32:[function(_dereq_,module,exports){ 4882 /** 4883 * Copyright 2013-2014 Facebook, Inc. 4884 * 4885 * Licensed under the Apache License, Version 2.0 (the "License"); 4886 * you may not use this file except in compliance with the License. 4887 * You may obtain a copy of the License at 4888 * 4889 * http://www.apache.org/licenses/LICENSE-2.0 4890 * 4891 * Unless required by applicable law or agreed to in writing, software 4892 * distributed under the License is distributed on an "AS IS" BASIS, 4893 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 4894 * See the License for the specific language governing permissions and 4895 * limitations under the License. 4896 * 4897 * @providesModule ReactComponentBrowserEnvironment 4898 */ 4899 4900 /*jslint evil: true */ 4901 4902 "use strict"; 4903 4904 var ReactDOMIDOperations = _dereq_("./ReactDOMIDOperations"); 4905 var ReactMarkupChecksum = _dereq_("./ReactMarkupChecksum"); 4906 var ReactMount = _dereq_("./ReactMount"); 4907 var ReactPerf = _dereq_("./ReactPerf"); 4908 var ReactReconcileTransaction = _dereq_("./ReactReconcileTransaction"); 4909 4910 var getReactRootElementInContainer = _dereq_("./getReactRootElementInContainer"); 4911 var invariant = _dereq_("./invariant"); 4912 4913 4914 var ELEMENT_NODE_TYPE = 1; 4915 var DOC_NODE_TYPE = 9; 4916 4917 4918 /** 4919 * Abstracts away all functionality of `ReactComponent` requires knowledge of 4920 * the browser context. 4921 */ 4922 var ReactComponentBrowserEnvironment = { 4923 ReactReconcileTransaction: ReactReconcileTransaction, 4924 4925 BackendIDOperations: ReactDOMIDOperations, 4926 4927 /** 4928 * If a particular environment requires that some resources be cleaned up, 4929 * specify this in the injected Mixin. In the DOM, we would likely want to 4930 * purge any cached node ID lookups. 4931 * 4932 * @private 4933 */ 4934 unmountIDFromEnvironment: function(rootNodeID) { 4935 ReactMount.purgeID(rootNodeID); 4936 }, 4937 4938 /** 4939 * @param {string} markup Markup string to place into the DOM Element. 4940 * @param {DOMElement} container DOM Element to insert markup into. 4941 * @param {boolean} shouldReuseMarkup Should reuse the existing markup in the 4942 * container if possible. 4943 */ 4944 mountImageIntoNode: ReactPerf.measure( 4945 'ReactComponentBrowserEnvironment', 4946 'mountImageIntoNode', 4947 function(markup, container, shouldReuseMarkup) { 4948 ("production" !== "development" ? invariant( 4949 container && ( 4950 container.nodeType === ELEMENT_NODE_TYPE || 4951 container.nodeType === DOC_NODE_TYPE 4952 ), 4953 'mountComponentIntoNode(...): Target container is not valid.' 4954 ) : invariant(container && ( 4955 container.nodeType === ELEMENT_NODE_TYPE || 4956 container.nodeType === DOC_NODE_TYPE 4957 ))); 4958 4959 if (shouldReuseMarkup) { 4960 if (ReactMarkupChecksum.canReuseMarkup( 4961 markup, 4962 getReactRootElementInContainer(container))) { 4963 return; 4964 } else { 4965 ("production" !== "development" ? invariant( 4966 container.nodeType !== DOC_NODE_TYPE, 4967 'You\'re trying to render a component to the document using ' + 4968 'server rendering but the checksum was invalid. This usually ' + 4969 'means you rendered a different component type or props on ' + 4970 'the client from the one on the server, or your render() ' + 4971 'methods are impure. React cannot handle this case due to ' + 4972 'cross-browser quirks by rendering at the document root. You ' + 4973 'should look for environment dependent code in your components ' + 4974 'and ensure the props are the same client and server side.' 4975 ) : invariant(container.nodeType !== DOC_NODE_TYPE)); 4976 4977 if ("production" !== "development") { 4978 console.warn( 4979 'React attempted to use reuse markup in a container but the ' + 4980 'checksum was invalid. This generally means that you are ' + 4981 'using server rendering and the markup generated on the ' + 4982 'server was not what the client was expecting. React injected' + 4983 'new markup to compensate which works but you have lost many ' + 4984 'of the benefits of server rendering. Instead, figure out ' + 4985 'why the markup being generated is different on the client ' + 4986 'or server.' 4987 ); 4988 } 4989 } 4990 } 4991 4992 ("production" !== "development" ? invariant( 4993 container.nodeType !== DOC_NODE_TYPE, 4994 'You\'re trying to render a component to the document but ' + 4995 'you didn\'t use server rendering. We can\'t do this ' + 4996 'without using server rendering due to cross-browser quirks. ' + 4997 'See renderComponentToString() for server rendering.' 4998 ) : invariant(container.nodeType !== DOC_NODE_TYPE)); 4999 5000 container.innerHTML = markup; 5001 } 5002 ) 5003 }; 5004 5005 module.exports = ReactComponentBrowserEnvironment; 5006 5007 },{"./ReactDOMIDOperations":40,"./ReactMarkupChecksum":59,"./ReactMount":60,"./ReactPerf":65,"./ReactReconcileTransaction":71,"./getReactRootElementInContainer":120,"./invariant":125}],33:[function(_dereq_,module,exports){ 5008 /** 5009 * Copyright 2013-2014 Facebook, Inc. 5010 * 5011 * Licensed under the Apache License, Version 2.0 (the "License"); 5012 * you may not use this file except in compliance with the License. 5013 * You may obtain a copy of the License at 5014 * 5015 * http://www.apache.org/licenses/LICENSE-2.0 5016 * 5017 * Unless required by applicable law or agreed to in writing, software 5018 * distributed under the License is distributed on an "AS IS" BASIS, 5019 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 5020 * See the License for the specific language governing permissions and 5021 * limitations under the License. 5022 * 5023 * @providesModule ReactCompositeComponent 5024 */ 5025 5026 "use strict"; 5027 5028 var ReactComponent = _dereq_("./ReactComponent"); 5029 var ReactContext = _dereq_("./ReactContext"); 5030 var ReactCurrentOwner = _dereq_("./ReactCurrentOwner"); 5031 var ReactErrorUtils = _dereq_("./ReactErrorUtils"); 5032 var ReactOwner = _dereq_("./ReactOwner"); 5033 var ReactPerf = _dereq_("./ReactPerf"); 5034 var ReactPropTransferer = _dereq_("./ReactPropTransferer"); 5035 var ReactPropTypeLocations = _dereq_("./ReactPropTypeLocations"); 5036 var ReactPropTypeLocationNames = _dereq_("./ReactPropTypeLocationNames"); 5037 var ReactUpdates = _dereq_("./ReactUpdates"); 5038 5039 var instantiateReactComponent = _dereq_("./instantiateReactComponent"); 5040 var invariant = _dereq_("./invariant"); 5041 var keyMirror = _dereq_("./keyMirror"); 5042 var merge = _dereq_("./merge"); 5043 var mixInto = _dereq_("./mixInto"); 5044 var monitorCodeUse = _dereq_("./monitorCodeUse"); 5045 var objMap = _dereq_("./objMap"); 5046 var shouldUpdateReactComponent = _dereq_("./shouldUpdateReactComponent"); 5047 var warning = _dereq_("./warning"); 5048 5049 /** 5050 * Policies that describe methods in `ReactCompositeComponentInterface`. 5051 */ 5052 var SpecPolicy = keyMirror({ 5053 /** 5054 * These methods may be defined only once by the class specification or mixin. 5055 */ 5056 DEFINE_ONCE: null, 5057 /** 5058 * These methods may be defined by both the class specification and mixins. 5059 * Subsequent definitions will be chained. These methods must return void. 5060 */ 5061 DEFINE_MANY: null, 5062 /** 5063 * These methods are overriding the base ReactCompositeComponent class. 5064 */ 5065 OVERRIDE_BASE: null, 5066 /** 5067 * These methods are similar to DEFINE_MANY, except we assume they return 5068 * objects. We try to merge the keys of the return values of all the mixed in 5069 * functions. If there is a key conflict we throw. 5070 */ 5071 DEFINE_MANY_MERGED: null 5072 }); 5073 5074 5075 var injectedMixins = []; 5076 5077 /** 5078 * Composite components are higher-level components that compose other composite 5079 * or native components. 5080 * 5081 * To create a new type of `ReactCompositeComponent`, pass a specification of 5082 * your new class to `React.createClass`. The only requirement of your class 5083 * specification is that you implement a `render` method. 5084 * 5085 * var MyComponent = React.createClass({ 5086 * render: function() { 5087 * return <div>Hello World</div>; 5088 * } 5089 * }); 5090 * 5091 * The class specification supports a specific protocol of methods that have 5092 * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for 5093 * more the comprehensive protocol. Any other properties and methods in the 5094 * class specification will available on the prototype. 5095 * 5096 * @interface ReactCompositeComponentInterface 5097 * @internal 5098 */ 5099 var ReactCompositeComponentInterface = { 5100 5101 /** 5102 * An array of Mixin objects to include when defining your component. 5103 * 5104 * @type {array} 5105 * @optional 5106 */ 5107 mixins: SpecPolicy.DEFINE_MANY, 5108 5109 /** 5110 * An object containing properties and methods that should be defined on 5111 * the component's constructor instead of its prototype (static methods). 5112 * 5113 * @type {object} 5114 * @optional 5115 */ 5116 statics: SpecPolicy.DEFINE_MANY, 5117 5118 /** 5119 * Definition of prop types for this component. 5120 * 5121 * @type {object} 5122 * @optional 5123 */ 5124 propTypes: SpecPolicy.DEFINE_MANY, 5125 5126 /** 5127 * Definition of context types for this component. 5128 * 5129 * @type {object} 5130 * @optional 5131 */ 5132 contextTypes: SpecPolicy.DEFINE_MANY, 5133 5134 /** 5135 * Definition of context types this component sets for its children. 5136 * 5137 * @type {object} 5138 * @optional 5139 */ 5140 childContextTypes: SpecPolicy.DEFINE_MANY, 5141 5142 // ==== Definition methods ==== 5143 5144 /** 5145 * Invoked when the component is mounted. Values in the mapping will be set on 5146 * `this.props` if that prop is not specified (i.e. using an `in` check). 5147 * 5148 * This method is invoked before `getInitialState` and therefore cannot rely 5149 * on `this.state` or use `this.setState`. 5150 * 5151 * @return {object} 5152 * @optional 5153 */ 5154 getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, 5155 5156 /** 5157 * Invoked once before the component is mounted. The return value will be used 5158 * as the initial value of `this.state`. 5159 * 5160 * getInitialState: function() { 5161 * return { 5162 * isOn: false, 5163 * fooBaz: new BazFoo() 5164 * } 5165 * } 5166 * 5167 * @return {object} 5168 * @optional 5169 */ 5170 getInitialState: SpecPolicy.DEFINE_MANY_MERGED, 5171 5172 /** 5173 * @return {object} 5174 * @optional 5175 */ 5176 getChildContext: SpecPolicy.DEFINE_MANY_MERGED, 5177 5178 /** 5179 * Uses props from `this.props` and state from `this.state` to render the 5180 * structure of the component. 5181 * 5182 * No guarantees are made about when or how often this method is invoked, so 5183 * it must not have side effects. 5184 * 5185 * render: function() { 5186 * var name = this.props.name; 5187 * return <div>Hello, {name}!</div>; 5188 * } 5189 * 5190 * @return {ReactComponent} 5191 * @nosideeffects 5192 * @required 5193 */ 5194 render: SpecPolicy.DEFINE_ONCE, 5195 5196 5197 5198 // ==== Delegate methods ==== 5199 5200 /** 5201 * Invoked when the component is initially created and about to be mounted. 5202 * This may have side effects, but any external subscriptions or data created 5203 * by this method must be cleaned up in `componentWillUnmount`. 5204 * 5205 * @optional 5206 */ 5207 componentWillMount: SpecPolicy.DEFINE_MANY, 5208 5209 /** 5210 * Invoked when the component has been mounted and has a DOM representation. 5211 * However, there is no guarantee that the DOM node is in the document. 5212 * 5213 * Use this as an opportunity to operate on the DOM when the component has 5214 * been mounted (initialized and rendered) for the first time. 5215 * 5216 * @param {DOMElement} rootNode DOM element representing the component. 5217 * @optional 5218 */ 5219 componentDidMount: SpecPolicy.DEFINE_MANY, 5220 5221 /** 5222 * Invoked before the component receives new props. 5223 * 5224 * Use this as an opportunity to react to a prop transition by updating the 5225 * state using `this.setState`. Current props are accessed via `this.props`. 5226 * 5227 * componentWillReceiveProps: function(nextProps, nextContext) { 5228 * this.setState({ 5229 * likesIncreasing: nextProps.likeCount > this.props.likeCount 5230 * }); 5231 * } 5232 * 5233 * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop 5234 * transition may cause a state change, but the opposite is not true. If you 5235 * need it, you are probably looking for `componentWillUpdate`. 5236 * 5237 * @param {object} nextProps 5238 * @optional 5239 */ 5240 componentWillReceiveProps: SpecPolicy.DEFINE_MANY, 5241 5242 /** 5243 * Invoked while deciding if the component should be updated as a result of 5244 * receiving new props, state and/or context. 5245 * 5246 * Use this as an opportunity to `return false` when you're certain that the 5247 * transition to the new props/state/context will not require a component 5248 * update. 5249 * 5250 * shouldComponentUpdate: function(nextProps, nextState, nextContext) { 5251 * return !equal(nextProps, this.props) || 5252 * !equal(nextState, this.state) || 5253 * !equal(nextContext, this.context); 5254 * } 5255 * 5256 * @param {object} nextProps 5257 * @param {?object} nextState 5258 * @param {?object} nextContext 5259 * @return {boolean} True if the component should update. 5260 * @optional 5261 */ 5262 shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, 5263 5264 /** 5265 * Invoked when the component is about to update due to a transition from 5266 * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` 5267 * and `nextContext`. 5268 * 5269 * Use this as an opportunity to perform preparation before an update occurs. 5270 * 5271 * NOTE: You **cannot** use `this.setState()` in this method. 5272 * 5273 * @param {object} nextProps 5274 * @param {?object} nextState 5275 * @param {?object} nextContext 5276 * @param {ReactReconcileTransaction} transaction 5277 * @optional 5278 */ 5279 componentWillUpdate: SpecPolicy.DEFINE_MANY, 5280 5281 /** 5282 * Invoked when the component's DOM representation has been updated. 5283 * 5284 * Use this as an opportunity to operate on the DOM when the component has 5285 * been updated. 5286 * 5287 * @param {object} prevProps 5288 * @param {?object} prevState 5289 * @param {?object} prevContext 5290 * @param {DOMElement} rootNode DOM element representing the component. 5291 * @optional 5292 */ 5293 componentDidUpdate: SpecPolicy.DEFINE_MANY, 5294 5295 /** 5296 * Invoked when the component is about to be removed from its parent and have 5297 * its DOM representation destroyed. 5298 * 5299 * Use this as an opportunity to deallocate any external resources. 5300 * 5301 * NOTE: There is no `componentDidUnmount` since your component will have been 5302 * destroyed by that point. 5303 * 5304 * @optional 5305 */ 5306 componentWillUnmount: SpecPolicy.DEFINE_MANY, 5307 5308 5309 5310 // ==== Advanced methods ==== 5311 5312 /** 5313 * Updates the component's currently mounted DOM representation. 5314 * 5315 * By default, this implements React's rendering and reconciliation algorithm. 5316 * Sophisticated clients may wish to override this. 5317 * 5318 * @param {ReactReconcileTransaction} transaction 5319 * @internal 5320 * @overridable 5321 */ 5322 updateComponent: SpecPolicy.OVERRIDE_BASE 5323 5324 }; 5325 5326 /** 5327 * Mapping from class specification keys to special processing functions. 5328 * 5329 * Although these are declared like instance properties in the specification 5330 * when defining classes using `React.createClass`, they are actually static 5331 * and are accessible on the constructor instead of the prototype. Despite 5332 * being static, they must be defined outside of the "statics" key under 5333 * which all other static methods are defined. 5334 */ 5335 var RESERVED_SPEC_KEYS = { 5336 displayName: function(ConvenienceConstructor, displayName) { 5337 ConvenienceConstructor.componentConstructor.displayName = displayName; 5338 }, 5339 mixins: function(ConvenienceConstructor, mixins) { 5340 if (mixins) { 5341 for (var i = 0; i < mixins.length; i++) { 5342 mixSpecIntoComponent(ConvenienceConstructor, mixins[i]); 5343 } 5344 } 5345 }, 5346 childContextTypes: function(ConvenienceConstructor, childContextTypes) { 5347 var Constructor = ConvenienceConstructor.componentConstructor; 5348 validateTypeDef( 5349 Constructor, 5350 childContextTypes, 5351 ReactPropTypeLocations.childContext 5352 ); 5353 Constructor.childContextTypes = merge( 5354 Constructor.childContextTypes, 5355 childContextTypes 5356 ); 5357 }, 5358 contextTypes: function(ConvenienceConstructor, contextTypes) { 5359 var Constructor = ConvenienceConstructor.componentConstructor; 5360 validateTypeDef( 5361 Constructor, 5362 contextTypes, 5363 ReactPropTypeLocations.context 5364 ); 5365 Constructor.contextTypes = merge(Constructor.contextTypes, contextTypes); 5366 }, 5367 propTypes: function(ConvenienceConstructor, propTypes) { 5368 var Constructor = ConvenienceConstructor.componentConstructor; 5369 validateTypeDef( 5370 Constructor, 5371 propTypes, 5372 ReactPropTypeLocations.prop 5373 ); 5374 Constructor.propTypes = merge(Constructor.propTypes, propTypes); 5375 }, 5376 statics: function(ConvenienceConstructor, statics) { 5377 mixStaticSpecIntoComponent(ConvenienceConstructor, statics); 5378 } 5379 }; 5380 5381 function validateTypeDef(Constructor, typeDef, location) { 5382 for (var propName in typeDef) { 5383 if (typeDef.hasOwnProperty(propName)) { 5384 ("production" !== "development" ? invariant( 5385 typeof typeDef[propName] == 'function', 5386 '%s: %s type `%s` is invalid; it must be a function, usually from ' + 5387 'React.PropTypes.', 5388 Constructor.displayName || 'ReactCompositeComponent', 5389 ReactPropTypeLocationNames[location], 5390 propName 5391 ) : invariant(typeof typeDef[propName] == 'function')); 5392 } 5393 } 5394 } 5395 5396 function validateMethodOverride(proto, name) { 5397 var specPolicy = ReactCompositeComponentInterface[name]; 5398 5399 // Disallow overriding of base class methods unless explicitly allowed. 5400 if (ReactCompositeComponentMixin.hasOwnProperty(name)) { 5401 ("production" !== "development" ? invariant( 5402 specPolicy === SpecPolicy.OVERRIDE_BASE, 5403 'ReactCompositeComponentInterface: You are attempting to override ' + 5404 '`%s` from your class specification. Ensure that your method names ' + 5405 'do not overlap with React methods.', 5406 name 5407 ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE)); 5408 } 5409 5410 // Disallow defining methods more than once unless explicitly allowed. 5411 if (proto.hasOwnProperty(name)) { 5412 ("production" !== "development" ? invariant( 5413 specPolicy === SpecPolicy.DEFINE_MANY || 5414 specPolicy === SpecPolicy.DEFINE_MANY_MERGED, 5415 'ReactCompositeComponentInterface: You are attempting to define ' + 5416 '`%s` on your component more than once. This conflict may be due ' + 5417 'to a mixin.', 5418 name 5419 ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY || 5420 specPolicy === SpecPolicy.DEFINE_MANY_MERGED)); 5421 } 5422 } 5423 5424 function validateLifeCycleOnReplaceState(instance) { 5425 var compositeLifeCycleState = instance._compositeLifeCycleState; 5426 ("production" !== "development" ? invariant( 5427 instance.isMounted() || 5428 compositeLifeCycleState === CompositeLifeCycle.MOUNTING, 5429 'replaceState(...): Can only update a mounted or mounting component.' 5430 ) : invariant(instance.isMounted() || 5431 compositeLifeCycleState === CompositeLifeCycle.MOUNTING)); 5432 ("production" !== "development" ? invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE, 5433 'replaceState(...): Cannot update during an existing state transition ' + 5434 '(such as within `render`). This could potentially cause an infinite ' + 5435 'loop so it is forbidden.' 5436 ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE)); 5437 ("production" !== "development" ? invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING, 5438 'replaceState(...): Cannot update while unmounting component. This ' + 5439 'usually means you called setState() on an unmounted component.' 5440 ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING)); 5441 } 5442 5443 /** 5444 * Custom version of `mixInto` which handles policy validation and reserved 5445 * specification keys when building `ReactCompositeComponent` classses. 5446 */ 5447 function mixSpecIntoComponent(ConvenienceConstructor, spec) { 5448 ("production" !== "development" ? invariant( 5449 !isValidClass(spec), 5450 'ReactCompositeComponent: You\'re attempting to ' + 5451 'use a component class as a mixin. Instead, just use a regular object.' 5452 ) : invariant(!isValidClass(spec))); 5453 ("production" !== "development" ? invariant( 5454 !ReactComponent.isValidComponent(spec), 5455 'ReactCompositeComponent: You\'re attempting to ' + 5456 'use a component as a mixin. Instead, just use a regular object.' 5457 ) : invariant(!ReactComponent.isValidComponent(spec))); 5458 5459 var Constructor = ConvenienceConstructor.componentConstructor; 5460 var proto = Constructor.prototype; 5461 for (var name in spec) { 5462 var property = spec[name]; 5463 if (!spec.hasOwnProperty(name)) { 5464 continue; 5465 } 5466 5467 validateMethodOverride(proto, name); 5468 5469 if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { 5470 RESERVED_SPEC_KEYS[name](ConvenienceConstructor, property); 5471 } else { 5472 // Setup methods on prototype: 5473 // The following member methods should not be automatically bound: 5474 // 1. Expected ReactCompositeComponent methods (in the "interface"). 5475 // 2. Overridden methods (that were mixed in). 5476 var isCompositeComponentMethod = name in ReactCompositeComponentInterface; 5477 var isInherited = name in proto; 5478 var markedDontBind = property && property.__reactDontBind; 5479 var isFunction = typeof property === 'function'; 5480 var shouldAutoBind = 5481 isFunction && 5482 !isCompositeComponentMethod && 5483 !isInherited && 5484 !markedDontBind; 5485 5486 if (shouldAutoBind) { 5487 if (!proto.__reactAutoBindMap) { 5488 proto.__reactAutoBindMap = {}; 5489 } 5490 proto.__reactAutoBindMap[name] = property; 5491 proto[name] = property; 5492 } else { 5493 if (isInherited) { 5494 // For methods which are defined more than once, call the existing 5495 // methods before calling the new property. 5496 if (ReactCompositeComponentInterface[name] === 5497 SpecPolicy.DEFINE_MANY_MERGED) { 5498 proto[name] = createMergedResultFunction(proto[name], property); 5499 } else { 5500 proto[name] = createChainedFunction(proto[name], property); 5501 } 5502 } else { 5503 proto[name] = property; 5504 } 5505 } 5506 } 5507 } 5508 } 5509 5510 function mixStaticSpecIntoComponent(ConvenienceConstructor, statics) { 5511 if (!statics) { 5512 return; 5513 } 5514 for (var name in statics) { 5515 var property = statics[name]; 5516 if (!statics.hasOwnProperty(name)) { 5517 return; 5518 } 5519 5520 var isInherited = name in ConvenienceConstructor; 5521 var result = property; 5522 if (isInherited) { 5523 var existingProperty = ConvenienceConstructor[name]; 5524 var existingType = typeof existingProperty; 5525 var propertyType = typeof property; 5526 ("production" !== "development" ? invariant( 5527 existingType === 'function' && propertyType === 'function', 5528 'ReactCompositeComponent: You are attempting to define ' + 5529 '`%s` on your component more than once, but that is only supported ' + 5530 'for functions, which are chained together. This conflict may be ' + 5531 'due to a mixin.', 5532 name 5533 ) : invariant(existingType === 'function' && propertyType === 'function')); 5534 result = createChainedFunction(existingProperty, property); 5535 } 5536 ConvenienceConstructor[name] = result; 5537 ConvenienceConstructor.componentConstructor[name] = result; 5538 } 5539 } 5540 5541 /** 5542 * Merge two objects, but throw if both contain the same key. 5543 * 5544 * @param {object} one The first object, which is mutated. 5545 * @param {object} two The second object 5546 * @return {object} one after it has been mutated to contain everything in two. 5547 */ 5548 function mergeObjectsWithNoDuplicateKeys(one, two) { 5549 ("production" !== "development" ? invariant( 5550 one && two && typeof one === 'object' && typeof two === 'object', 5551 'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects' 5552 ) : invariant(one && two && typeof one === 'object' && typeof two === 'object')); 5553 5554 objMap(two, function(value, key) { 5555 ("production" !== "development" ? invariant( 5556 one[key] === undefined, 5557 'mergeObjectsWithNoDuplicateKeys(): ' + 5558 'Tried to merge two objects with the same key: %s', 5559 key 5560 ) : invariant(one[key] === undefined)); 5561 one[key] = value; 5562 }); 5563 return one; 5564 } 5565 5566 /** 5567 * Creates a function that invokes two functions and merges their return values. 5568 * 5569 * @param {function} one Function to invoke first. 5570 * @param {function} two Function to invoke second. 5571 * @return {function} Function that invokes the two argument functions. 5572 * @private 5573 */ 5574 function createMergedResultFunction(one, two) { 5575 return function mergedResult() { 5576 var a = one.apply(this, arguments); 5577 var b = two.apply(this, arguments); 5578 if (a == null) { 5579 return b; 5580 } else if (b == null) { 5581 return a; 5582 } 5583 return mergeObjectsWithNoDuplicateKeys(a, b); 5584 }; 5585 } 5586 5587 /** 5588 * Creates a function that invokes two functions and ignores their return vales. 5589 * 5590 * @param {function} one Function to invoke first. 5591 * @param {function} two Function to invoke second. 5592 * @return {function} Function that invokes the two argument functions. 5593 * @private 5594 */ 5595 function createChainedFunction(one, two) { 5596 return function chainedFunction() { 5597 one.apply(this, arguments); 5598 two.apply(this, arguments); 5599 }; 5600 } 5601 5602 if ("production" !== "development") { 5603 5604 var unmountedPropertyWhitelist = { 5605 constructor: true, 5606 construct: true, 5607 isOwnedBy: true, // should be deprecated but can have code mod (internal) 5608 type: true, 5609 props: true, 5610 // currently private but belong on the descriptor and are valid for use 5611 // inside the framework: 5612 __keyValidated__: true, 5613 _owner: true, 5614 _currentContext: true 5615 }; 5616 5617 var componentInstanceProperties = { 5618 __keyValidated__: true, 5619 __keySetters: true, 5620 _compositeLifeCycleState: true, 5621 _currentContext: true, 5622 _defaultProps: true, 5623 _instance: true, 5624 _lifeCycleState: true, 5625 _mountDepth: true, 5626 _owner: true, 5627 _pendingCallbacks: true, 5628 _pendingContext: true, 5629 _pendingForceUpdate: true, 5630 _pendingOwner: true, 5631 _pendingProps: true, 5632 _pendingState: true, 5633 _renderedComponent: true, 5634 _rootNodeID: true, 5635 context: true, 5636 props: true, 5637 refs: true, 5638 state: true, 5639 5640 // These are known instance properties coming from other sources 5641 _pendingQueries: true, 5642 _queryPropListeners: true, 5643 queryParams: true 5644 5645 }; 5646 5647 var hasWarnedOnComponentType = {}; 5648 5649 var warningStackCounter = 0; 5650 5651 var issueMembraneWarning = function(instance, key) { 5652 var isWhitelisted = unmountedPropertyWhitelist.hasOwnProperty(key); 5653 if (warningStackCounter > 0 || isWhitelisted) { 5654 return; 5655 } 5656 var name = instance.constructor.displayName || 'Unknown'; 5657 var owner = ReactCurrentOwner.current; 5658 var ownerName = (owner && owner.constructor.displayName) || 'Unknown'; 5659 var warningKey = key + '|' + name + '|' + ownerName; 5660 if (hasWarnedOnComponentType.hasOwnProperty(warningKey)) { 5661 // We have already warned for this combination. Skip it this time. 5662 return; 5663 } 5664 hasWarnedOnComponentType[warningKey] = true; 5665 5666 var context = owner ? ' in ' + ownerName + '.' : ' at the top level.'; 5667 var staticMethodExample = '<' + name + ' />.type.' + key + '(...)'; 5668 5669 monitorCodeUse('react_descriptor_property_access', { component: name }); 5670 console.warn( 5671 'Invalid access to component property "' + key + '" on ' + name + 5672 context + ' See http://fb.me/react-warning-descriptors .' + 5673 ' Use a static method instead: ' + staticMethodExample 5674 ); 5675 }; 5676 5677 var wrapInMembraneFunction = function(fn, thisBinding) { 5678 if (fn.__reactMembraneFunction && fn.__reactMembraneSelf === thisBinding) { 5679 return fn.__reactMembraneFunction; 5680 } 5681 return fn.__reactMembraneFunction = function() { 5682 /** 5683 * By getting this function, you've already received a warning. The 5684 * internals of this function will likely cause more warnings. To avoid 5685 * Spamming too much we disable any warning triggered inside of this 5686 * stack. 5687 */ 5688 warningStackCounter++; 5689 try { 5690 // If the this binding is unchanged, we defer to the real component. 5691 // This is important to keep some referential integrity in the 5692 // internals. E.g. owner equality check. 5693 var self = this === thisBinding ? this.__realComponentInstance : this; 5694 return fn.apply(self, arguments); 5695 } finally { 5696 warningStackCounter--; 5697 } 5698 }; 5699 }; 5700 5701 var defineMembraneProperty = function(membrane, prototype, key) { 5702 Object.defineProperty(membrane, key, { 5703 5704 configurable: false, 5705 enumerable: true, 5706 5707 get: function() { 5708 if (this === membrane) { 5709 // We're allowed to access the prototype directly. 5710 return prototype[key]; 5711 } 5712 issueMembraneWarning(this, key); 5713 5714 var realValue = this.__realComponentInstance[key]; 5715 // If the real value is a function, we need to provide a wrapper that 5716 // disables nested warnings. The properties type and constructors are 5717 // expected to the be constructors and therefore is often use with an 5718 // equality check and we shouldn't try to rebind those. 5719 if (typeof realValue === 'function' && 5720 key !== 'type' && 5721 key !== 'constructor') { 5722 return wrapInMembraneFunction(realValue, this); 5723 } 5724 return realValue; 5725 }, 5726 5727 set: function(value) { 5728 if (this === membrane) { 5729 // We're allowed to set a value on the prototype directly. 5730 prototype[key] = value; 5731 return; 5732 } 5733 issueMembraneWarning(this, key); 5734 this.__realComponentInstance[key] = value; 5735 } 5736 5737 }); 5738 }; 5739 5740 /** 5741 * Creates a membrane prototype which wraps the original prototype. If any 5742 * property is accessed in an unmounted state, a warning is issued. 5743 * 5744 * @param {object} prototype Original prototype. 5745 * @return {object} The membrane prototype. 5746 * @private 5747 */ 5748 var createMountWarningMembrane = function(prototype) { 5749 var membrane = {}; 5750 var key; 5751 for (key in prototype) { 5752 defineMembraneProperty(membrane, prototype, key); 5753 } 5754 // These are properties that goes into the instance but not the prototype. 5755 // We can create the membrane on the prototype even though this will 5756 // result in a faulty hasOwnProperty check it's better perf. 5757 for (key in componentInstanceProperties) { 5758 if (componentInstanceProperties.hasOwnProperty(key) && 5759 !(key in prototype)) { 5760 defineMembraneProperty(membrane, prototype, key); 5761 } 5762 } 5763 return membrane; 5764 }; 5765 5766 /** 5767 * Creates a membrane constructor which wraps the component that gets mounted. 5768 * 5769 * @param {function} constructor Original constructor. 5770 * @return {function} The membrane constructor. 5771 * @private 5772 */ 5773 var createDescriptorProxy = function(constructor) { 5774 try { 5775 var ProxyConstructor = function() { 5776 this.__realComponentInstance = new constructor(); 5777 5778 // We can only safely pass through known instance variables. Unknown 5779 // expandos are not safe. Use the real mounted instance to avoid this 5780 // problem if it blows something up. 5781 Object.freeze(this); 5782 }; 5783 5784 ProxyConstructor.prototype = createMountWarningMembrane( 5785 constructor.prototype 5786 ); 5787 5788 return ProxyConstructor; 5789 } catch(x) { 5790 // In IE8 define property will fail on non-DOM objects. If anything in 5791 // the membrane creation fails, we'll bail out and just use the plain 5792 // constructor without warnings. 5793 return constructor; 5794 } 5795 }; 5796 5797 } 5798 5799 /** 5800 * `ReactCompositeComponent` maintains an auxiliary life cycle state in 5801 * `this._compositeLifeCycleState` (which can be null). 5802 * 5803 * This is different from the life cycle state maintained by `ReactComponent` in 5804 * `this._lifeCycleState`. The following diagram shows how the states overlap in 5805 * time. There are times when the CompositeLifeCycle is null - at those times it 5806 * is only meaningful to look at ComponentLifeCycle alone. 5807 * 5808 * Top Row: ReactComponent.ComponentLifeCycle 5809 * Low Row: ReactComponent.CompositeLifeCycle 5810 * 5811 * +-------+------------------------------------------------------+--------+ 5812 * | UN | MOUNTED | UN | 5813 * |MOUNTED| | MOUNTED| 5814 * +-------+------------------------------------------------------+--------+ 5815 * | ^--------+ +------+ +------+ +------+ +--------^ | 5816 * | | | | | | | | | | | | 5817 * | 0--|MOUNTING|-0-|RECEIV|-0-|RECEIV|-0-|RECEIV|-0-| UN |--->0 | 5818 * | | | |PROPS | | PROPS| | STATE| |MOUNTING| | 5819 * | | | | | | | | | | | | 5820 * | | | | | | | | | | | | 5821 * | +--------+ +------+ +------+ +------+ +--------+ | 5822 * | | | | 5823 * +-------+------------------------------------------------------+--------+ 5824 */ 5825 var CompositeLifeCycle = keyMirror({ 5826 /** 5827 * Components in the process of being mounted respond to state changes 5828 * differently. 5829 */ 5830 MOUNTING: null, 5831 /** 5832 * Components in the process of being unmounted are guarded against state 5833 * changes. 5834 */ 5835 UNMOUNTING: null, 5836 /** 5837 * Components that are mounted and receiving new props respond to state 5838 * changes differently. 5839 */ 5840 RECEIVING_PROPS: null, 5841 /** 5842 * Components that are mounted and receiving new state are guarded against 5843 * additional state changes. 5844 */ 5845 RECEIVING_STATE: null 5846 }); 5847 5848 /** 5849 * @lends {ReactCompositeComponent.prototype} 5850 */ 5851 var ReactCompositeComponentMixin = { 5852 5853 /** 5854 * Base constructor for all composite component. 5855 * 5856 * @param {?object} initialProps 5857 * @param {*} children 5858 * @final 5859 * @internal 5860 */ 5861 construct: function(initialProps, children) { 5862 // Children can be either an array or more than one argument 5863 ReactComponent.Mixin.construct.apply(this, arguments); 5864 ReactOwner.Mixin.construct.apply(this, arguments); 5865 5866 this.state = null; 5867 this._pendingState = null; 5868 5869 this.context = null; 5870 this._currentContext = ReactContext.current; 5871 this._pendingContext = null; 5872 5873 // The descriptor that was used to instantiate this component. Will be 5874 // set by the instantiator instead of the constructor since this 5875 // constructor is currently used by both instances and descriptors. 5876 this._descriptor = null; 5877 5878 this._compositeLifeCycleState = null; 5879 }, 5880 5881 /** 5882 * Components in the intermediate state now has cyclic references. To avoid 5883 * breaking JSON serialization we expose a custom JSON format. 5884 * @return {object} JSON compatible representation. 5885 * @internal 5886 * @final 5887 */ 5888 toJSON: function() { 5889 return { type: this.type, props: this.props }; 5890 }, 5891 5892 /** 5893 * Checks whether or not this composite component is mounted. 5894 * @return {boolean} True if mounted, false otherwise. 5895 * @protected 5896 * @final 5897 */ 5898 isMounted: function() { 5899 return ReactComponent.Mixin.isMounted.call(this) && 5900 this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING; 5901 }, 5902 5903 /** 5904 * Initializes the component, renders markup, and registers event listeners. 5905 * 5906 * @param {string} rootID DOM ID of the root node. 5907 * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction 5908 * @param {number} mountDepth number of components in the owner hierarchy 5909 * @return {?string} Rendered markup to be inserted into the DOM. 5910 * @final 5911 * @internal 5912 */ 5913 mountComponent: ReactPerf.measure( 5914 'ReactCompositeComponent', 5915 'mountComponent', 5916 function(rootID, transaction, mountDepth) { 5917 ReactComponent.Mixin.mountComponent.call( 5918 this, 5919 rootID, 5920 transaction, 5921 mountDepth 5922 ); 5923 this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING; 5924 5925 this.context = this._processContext(this._currentContext); 5926 this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null; 5927 this.props = this._processProps(this.props); 5928 5929 if (this.__reactAutoBindMap) { 5930 this._bindAutoBindMethods(); 5931 } 5932 5933 this.state = this.getInitialState ? this.getInitialState() : null; 5934 ("production" !== "development" ? invariant( 5935 typeof this.state === 'object' && !Array.isArray(this.state), 5936 '%s.getInitialState(): must return an object or null', 5937 this.constructor.displayName || 'ReactCompositeComponent' 5938 ) : invariant(typeof this.state === 'object' && !Array.isArray(this.state))); 5939 5940 this._pendingState = null; 5941 this._pendingForceUpdate = false; 5942 5943 if (this.componentWillMount) { 5944 this.componentWillMount(); 5945 // When mounting, calls to `setState` by `componentWillMount` will set 5946 // `this._pendingState` without triggering a re-render. 5947 if (this._pendingState) { 5948 this.state = this._pendingState; 5949 this._pendingState = null; 5950 } 5951 } 5952 5953 this._renderedComponent = instantiateReactComponent( 5954 this._renderValidatedComponent() 5955 ); 5956 5957 // Done with mounting, `setState` will now trigger UI changes. 5958 this._compositeLifeCycleState = null; 5959 var markup = this._renderedComponent.mountComponent( 5960 rootID, 5961 transaction, 5962 mountDepth + 1 5963 ); 5964 if (this.componentDidMount) { 5965 transaction.getReactMountReady().enqueue(this, this.componentDidMount); 5966 } 5967 return markup; 5968 } 5969 ), 5970 5971 /** 5972 * Releases any resources allocated by `mountComponent`. 5973 * 5974 * @final 5975 * @internal 5976 */ 5977 unmountComponent: function() { 5978 this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING; 5979 if (this.componentWillUnmount) { 5980 this.componentWillUnmount(); 5981 } 5982 this._compositeLifeCycleState = null; 5983 5984 this._defaultProps = null; 5985 5986 this._renderedComponent.unmountComponent(); 5987 this._renderedComponent = null; 5988 5989 ReactComponent.Mixin.unmountComponent.call(this); 5990 5991 // Some existing components rely on this.props even after they've been 5992 // destroyed (in event handlers). 5993 // TODO: this.props = null; 5994 // TODO: this.state = null; 5995 }, 5996 5997 /** 5998 * Sets a subset of the state. Always use this or `replaceState` to mutate 5999 * state. You should treat `this.state` as immutable. 6000 * 6001 * There is no guarantee that `this.state` will be immediately updated, so 6002 * accessing `this.state` after calling this method may return the old value. 6003 * 6004 * There is no guarantee that calls to `setState` will run synchronously, 6005 * as they may eventually be batched together. You can provide an optional 6006 * callback that will be executed when the call to setState is actually 6007 * completed. 6008 * 6009 * @param {object} partialState Next partial state to be merged with state. 6010 * @param {?function} callback Called after state is updated. 6011 * @final 6012 * @protected 6013 */ 6014 setState: function(partialState, callback) { 6015 ("production" !== "development" ? invariant( 6016 typeof partialState === 'object' || partialState == null, 6017 'setState(...): takes an object of state variables to update.' 6018 ) : invariant(typeof partialState === 'object' || partialState == null)); 6019 if ("production" !== "development") { 6020 ("production" !== "development" ? warning( 6021 partialState != null, 6022 'setState(...): You passed an undefined or null state object; ' + 6023 'instead, use forceUpdate().' 6024 ) : null); 6025 } 6026 // Merge with `_pendingState` if it exists, otherwise with existing state. 6027 this.replaceState( 6028 merge(this._pendingState || this.state, partialState), 6029 callback 6030 ); 6031 }, 6032 6033 /** 6034 * Replaces all of the state. Always use this or `setState` to mutate state. 6035 * You should treat `this.state` as immutable. 6036 * 6037 * There is no guarantee that `this.state` will be immediately updated, so 6038 * accessing `this.state` after calling this method may return the old value. 6039 * 6040 * @param {object} completeState Next state. 6041 * @param {?function} callback Called after state is updated. 6042 * @final 6043 * @protected 6044 */ 6045 replaceState: function(completeState, callback) { 6046 validateLifeCycleOnReplaceState(this); 6047 this._pendingState = completeState; 6048 ReactUpdates.enqueueUpdate(this, callback); 6049 }, 6050 6051 /** 6052 * Filters the context object to only contain keys specified in 6053 * `contextTypes`, and asserts that they are valid. 6054 * 6055 * @param {object} context 6056 * @return {?object} 6057 * @private 6058 */ 6059 _processContext: function(context) { 6060 var maskedContext = null; 6061 var contextTypes = this.constructor.contextTypes; 6062 if (contextTypes) { 6063 maskedContext = {}; 6064 for (var contextName in contextTypes) { 6065 maskedContext[contextName] = context[contextName]; 6066 } 6067 if ("production" !== "development") { 6068 this._checkPropTypes( 6069 contextTypes, 6070 maskedContext, 6071 ReactPropTypeLocations.context 6072 ); 6073 } 6074 } 6075 return maskedContext; 6076 }, 6077 6078 /** 6079 * @param {object} currentContext 6080 * @return {object} 6081 * @private 6082 */ 6083 _processChildContext: function(currentContext) { 6084 var childContext = this.getChildContext && this.getChildContext(); 6085 var displayName = this.constructor.displayName || 'ReactCompositeComponent'; 6086 if (childContext) { 6087 ("production" !== "development" ? invariant( 6088 typeof this.constructor.childContextTypes === 'object', 6089 '%s.getChildContext(): childContextTypes must be defined in order to ' + 6090 'use getChildContext().', 6091 displayName 6092 ) : invariant(typeof this.constructor.childContextTypes === 'object')); 6093 if ("production" !== "development") { 6094 this._checkPropTypes( 6095 this.constructor.childContextTypes, 6096 childContext, 6097 ReactPropTypeLocations.childContext 6098 ); 6099 } 6100 for (var name in childContext) { 6101 ("production" !== "development" ? invariant( 6102 name in this.constructor.childContextTypes, 6103 '%s.getChildContext(): key "%s" is not defined in childContextTypes.', 6104 displayName, 6105 name 6106 ) : invariant(name in this.constructor.childContextTypes)); 6107 } 6108 return merge(currentContext, childContext); 6109 } 6110 return currentContext; 6111 }, 6112 6113 /** 6114 * Processes props by setting default values for unspecified props and 6115 * asserting that the props are valid. Does not mutate its argument; returns 6116 * a new props object with defaults merged in. 6117 * 6118 * @param {object} newProps 6119 * @return {object} 6120 * @private 6121 */ 6122 _processProps: function(newProps) { 6123 var props = merge(newProps); 6124 var defaultProps = this._defaultProps; 6125 for (var propName in defaultProps) { 6126 if (typeof props[propName] === 'undefined') { 6127 props[propName] = defaultProps[propName]; 6128 } 6129 } 6130 if ("production" !== "development") { 6131 var propTypes = this.constructor.propTypes; 6132 if (propTypes) { 6133 this._checkPropTypes(propTypes, props, ReactPropTypeLocations.prop); 6134 } 6135 } 6136 return props; 6137 }, 6138 6139 /** 6140 * Assert that the props are valid 6141 * 6142 * @param {object} propTypes Map of prop name to a ReactPropType 6143 * @param {object} props 6144 * @param {string} location e.g. "prop", "context", "child context" 6145 * @private 6146 */ 6147 _checkPropTypes: function(propTypes, props, location) { 6148 var componentName = this.constructor.displayName; 6149 for (var propName in propTypes) { 6150 if (propTypes.hasOwnProperty(propName)) { 6151 propTypes[propName](props, propName, componentName, location); 6152 } 6153 } 6154 }, 6155 6156 performUpdateIfNecessary: function() { 6157 var compositeLifeCycleState = this._compositeLifeCycleState; 6158 // Do not trigger a state transition if we are in the middle of mounting or 6159 // receiving props because both of those will already be doing this. 6160 if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING || 6161 compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) { 6162 return; 6163 } 6164 ReactComponent.Mixin.performUpdateIfNecessary.call(this); 6165 }, 6166 6167 /** 6168 * If any of `_pendingProps`, `_pendingState`, or `_pendingForceUpdate` is 6169 * set, update the component. 6170 * 6171 * @param {ReactReconcileTransaction} transaction 6172 * @internal 6173 */ 6174 _performUpdateIfNecessary: function(transaction) { 6175 if (this._pendingProps == null && 6176 this._pendingState == null && 6177 this._pendingContext == null && 6178 !this._pendingForceUpdate) { 6179 return; 6180 } 6181 6182 var nextFullContext = this._pendingContext || this._currentContext; 6183 var nextContext = this._processContext(nextFullContext); 6184 this._pendingContext = null; 6185 6186 var nextProps = this.props; 6187 if (this._pendingProps != null) { 6188 nextProps = this._processProps(this._pendingProps); 6189 this._pendingProps = null; 6190 6191 this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS; 6192 if (this.componentWillReceiveProps) { 6193 this.componentWillReceiveProps(nextProps, nextContext); 6194 } 6195 } 6196 6197 this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE; 6198 6199 // Unlike props, state, and context, we specifically don't want to set 6200 // _pendingOwner to null here because it's possible for a component to have 6201 // a null owner, so we instead make `this._owner === this._pendingOwner` 6202 // mean that there's no owner change pending. 6203 var nextOwner = this._pendingOwner; 6204 6205 var nextState = this._pendingState || this.state; 6206 this._pendingState = null; 6207 6208 try { 6209 if (this._pendingForceUpdate || 6210 !this.shouldComponentUpdate || 6211 this.shouldComponentUpdate(nextProps, nextState, nextContext)) { 6212 this._pendingForceUpdate = false; 6213 // Will set `this.props`, `this.state` and `this.context`. 6214 this._performComponentUpdate( 6215 nextProps, 6216 nextOwner, 6217 nextState, 6218 nextFullContext, 6219 nextContext, 6220 transaction 6221 ); 6222 } else { 6223 // If it's determined that a component should not update, we still want 6224 // to set props and state. 6225 this.props = nextProps; 6226 this._owner = nextOwner; 6227 this.state = nextState; 6228 this._currentContext = nextFullContext; 6229 this.context = nextContext; 6230 } 6231 } finally { 6232 this._compositeLifeCycleState = null; 6233 } 6234 }, 6235 6236 /** 6237 * Merges new props and state, notifies delegate methods of update and 6238 * performs update. 6239 * 6240 * @param {object} nextProps Next object to set as properties. 6241 * @param {?ReactComponent} nextOwner Next component to set as owner 6242 * @param {?object} nextState Next object to set as state. 6243 * @param {?object} nextFullContext Next object to set as _currentContext. 6244 * @param {?object} nextContext Next object to set as context. 6245 * @param {ReactReconcileTransaction} transaction 6246 * @private 6247 */ 6248 _performComponentUpdate: function( 6249 nextProps, 6250 nextOwner, 6251 nextState, 6252 nextFullContext, 6253 nextContext, 6254 transaction 6255 ) { 6256 var prevProps = this.props; 6257 var prevOwner = this._owner; 6258 var prevState = this.state; 6259 var prevContext = this.context; 6260 6261 if (this.componentWillUpdate) { 6262 this.componentWillUpdate(nextProps, nextState, nextContext); 6263 } 6264 6265 this.props = nextProps; 6266 this._owner = nextOwner; 6267 this.state = nextState; 6268 this._currentContext = nextFullContext; 6269 this.context = nextContext; 6270 6271 this.updateComponent( 6272 transaction, 6273 prevProps, 6274 prevOwner, 6275 prevState, 6276 prevContext 6277 ); 6278 6279 if (this.componentDidUpdate) { 6280 transaction.getReactMountReady().enqueue( 6281 this, 6282 this.componentDidUpdate.bind(this, prevProps, prevState, prevContext) 6283 ); 6284 } 6285 }, 6286 6287 receiveComponent: function(nextComponent, transaction) { 6288 if (nextComponent === this._descriptor) { 6289 // Since props and context are immutable after the component is 6290 // mounted, we can do a cheap identity compare here to determine 6291 // if this is a superfluous reconcile. 6292 return; 6293 } 6294 6295 // Update the descriptor that was last used by this component instance 6296 this._descriptor = nextComponent; 6297 6298 this._pendingContext = nextComponent._currentContext; 6299 ReactComponent.Mixin.receiveComponent.call( 6300 this, 6301 nextComponent, 6302 transaction 6303 ); 6304 }, 6305 6306 /** 6307 * Updates the component's currently mounted DOM representation. 6308 * 6309 * By default, this implements React's rendering and reconciliation algorithm. 6310 * Sophisticated clients may wish to override this. 6311 * 6312 * @param {ReactReconcileTransaction} transaction 6313 * @param {object} prevProps 6314 * @param {?ReactComponent} prevOwner 6315 * @param {?object} prevState 6316 * @param {?object} prevContext 6317 * @internal 6318 * @overridable 6319 */ 6320 updateComponent: ReactPerf.measure( 6321 'ReactCompositeComponent', 6322 'updateComponent', 6323 function(transaction, prevProps, prevOwner, prevState, prevContext) { 6324 ReactComponent.Mixin.updateComponent.call( 6325 this, 6326 transaction, 6327 prevProps, 6328 prevOwner 6329 ); 6330 6331 6332 var prevComponentInstance = this._renderedComponent; 6333 var nextComponent = this._renderValidatedComponent(); 6334 if (shouldUpdateReactComponent(prevComponentInstance, nextComponent)) { 6335 prevComponentInstance.receiveComponent(nextComponent, transaction); 6336 } else { 6337 // These two IDs are actually the same! But nothing should rely on that. 6338 var thisID = this._rootNodeID; 6339 var prevComponentID = prevComponentInstance._rootNodeID; 6340 prevComponentInstance.unmountComponent(); 6341 this._renderedComponent = instantiateReactComponent(nextComponent); 6342 var nextMarkup = this._renderedComponent.mountComponent( 6343 thisID, 6344 transaction, 6345 this._mountDepth + 1 6346 ); 6347 ReactComponent.BackendIDOperations.dangerouslyReplaceNodeWithMarkupByID( 6348 prevComponentID, 6349 nextMarkup 6350 ); 6351 } 6352 } 6353 ), 6354 6355 /** 6356 * Forces an update. This should only be invoked when it is known with 6357 * certainty that we are **not** in a DOM transaction. 6358 * 6359 * You may want to call this when you know that some deeper aspect of the 6360 * component's state has changed but `setState` was not called. 6361 * 6362 * This will not invoke `shouldUpdateComponent`, but it will invoke 6363 * `componentWillUpdate` and `componentDidUpdate`. 6364 * 6365 * @param {?function} callback Called after update is complete. 6366 * @final 6367 * @protected 6368 */ 6369 forceUpdate: function(callback) { 6370 var compositeLifeCycleState = this._compositeLifeCycleState; 6371 ("production" !== "development" ? invariant( 6372 this.isMounted() || 6373 compositeLifeCycleState === CompositeLifeCycle.MOUNTING, 6374 'forceUpdate(...): Can only force an update on mounted or mounting ' + 6375 'components.' 6376 ) : invariant(this.isMounted() || 6377 compositeLifeCycleState === CompositeLifeCycle.MOUNTING)); 6378 ("production" !== "development" ? invariant( 6379 compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE && 6380 compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING, 6381 'forceUpdate(...): Cannot force an update while unmounting component ' + 6382 'or during an existing state transition (such as within `render`).' 6383 ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE && 6384 compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING)); 6385 this._pendingForceUpdate = true; 6386 ReactUpdates.enqueueUpdate(this, callback); 6387 }, 6388 6389 /** 6390 * @private 6391 */ 6392 _renderValidatedComponent: ReactPerf.measure( 6393 'ReactCompositeComponent', 6394 '_renderValidatedComponent', 6395 function() { 6396 var renderedComponent; 6397 var previousContext = ReactContext.current; 6398 ReactContext.current = this._processChildContext(this._currentContext); 6399 ReactCurrentOwner.current = this; 6400 try { 6401 renderedComponent = this.render(); 6402 } finally { 6403 ReactContext.current = previousContext; 6404 ReactCurrentOwner.current = null; 6405 } 6406 ("production" !== "development" ? invariant( 6407 ReactComponent.isValidComponent(renderedComponent), 6408 '%s.render(): A valid ReactComponent must be returned. You may have ' + 6409 'returned null, undefined, an array, or some other invalid object.', 6410 this.constructor.displayName || 'ReactCompositeComponent' 6411 ) : invariant(ReactComponent.isValidComponent(renderedComponent))); 6412 return renderedComponent; 6413 } 6414 ), 6415 6416 /** 6417 * @private 6418 */ 6419 _bindAutoBindMethods: function() { 6420 for (var autoBindKey in this.__reactAutoBindMap) { 6421 if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { 6422 continue; 6423 } 6424 var method = this.__reactAutoBindMap[autoBindKey]; 6425 this[autoBindKey] = this._bindAutoBindMethod(ReactErrorUtils.guard( 6426 method, 6427 this.constructor.displayName + '.' + autoBindKey 6428 )); 6429 } 6430 }, 6431 6432 /** 6433 * Binds a method to the component. 6434 * 6435 * @param {function} method Method to be bound. 6436 * @private 6437 */ 6438 _bindAutoBindMethod: function(method) { 6439 var component = this; 6440 var boundMethod = function() { 6441 return method.apply(component, arguments); 6442 }; 6443 if ("production" !== "development") { 6444 boundMethod.__reactBoundContext = component; 6445 boundMethod.__reactBoundMethod = method; 6446 boundMethod.__reactBoundArguments = null; 6447 var componentName = component.constructor.displayName; 6448 var _bind = boundMethod.bind; 6449 boundMethod.bind = function(newThis ) {var args=Array.prototype.slice.call(arguments,1); 6450 // User is trying to bind() an autobound method; we effectively will 6451 // ignore the value of "this" that the user is trying to use, so 6452 // let's warn. 6453 if (newThis !== component && newThis !== null) { 6454 monitorCodeUse('react_bind_warning', { component: componentName }); 6455 console.warn( 6456 'bind(): React component methods may only be bound to the ' + 6457 'component instance. See ' + componentName 6458 ); 6459 } else if (!args.length) { 6460 monitorCodeUse('react_bind_warning', { component: componentName }); 6461 console.warn( 6462 'bind(): You are binding a component method to the component. ' + 6463 'React does this for you automatically in a high-performance ' + 6464 'way, so you can safely remove this call. See ' + componentName 6465 ); 6466 return boundMethod; 6467 } 6468 var reboundMethod = _bind.apply(boundMethod, arguments); 6469 reboundMethod.__reactBoundContext = component; 6470 reboundMethod.__reactBoundMethod = method; 6471 reboundMethod.__reactBoundArguments = args; 6472 return reboundMethod; 6473 }; 6474 } 6475 return boundMethod; 6476 } 6477 }; 6478 6479 var ReactCompositeComponentBase = function() {}; 6480 mixInto(ReactCompositeComponentBase, ReactComponent.Mixin); 6481 mixInto(ReactCompositeComponentBase, ReactOwner.Mixin); 6482 mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin); 6483 mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin); 6484 6485 /** 6486 * Checks if a value is a valid component constructor. 6487 * 6488 * @param {*} 6489 * @return {boolean} 6490 * @public 6491 */ 6492 function isValidClass(componentClass) { 6493 return componentClass instanceof Function && 6494 'componentConstructor' in componentClass && 6495 componentClass.componentConstructor instanceof Function; 6496 } 6497 /** 6498 * Module for creating composite components. 6499 * 6500 * @class ReactCompositeComponent 6501 * @extends ReactComponent 6502 * @extends ReactOwner 6503 * @extends ReactPropTransferer 6504 */ 6505 var ReactCompositeComponent = { 6506 6507 LifeCycle: CompositeLifeCycle, 6508 6509 Base: ReactCompositeComponentBase, 6510 6511 /** 6512 * Creates a composite component class given a class specification. 6513 * 6514 * @param {object} spec Class specification (which must define `render`). 6515 * @return {function} Component constructor function. 6516 * @public 6517 */ 6518 createClass: function(spec) { 6519 var Constructor = function() {}; 6520 Constructor.prototype = new ReactCompositeComponentBase(); 6521 Constructor.prototype.constructor = Constructor; 6522 6523 var DescriptorConstructor = Constructor; 6524 6525 var ConvenienceConstructor = function(props, children) { 6526 var descriptor = new DescriptorConstructor(); 6527 descriptor.construct.apply(descriptor, arguments); 6528 return descriptor; 6529 }; 6530 ConvenienceConstructor.componentConstructor = Constructor; 6531 Constructor.ConvenienceConstructor = ConvenienceConstructor; 6532 ConvenienceConstructor.originalSpec = spec; 6533 6534 injectedMixins.forEach( 6535 mixSpecIntoComponent.bind(null, ConvenienceConstructor) 6536 ); 6537 6538 mixSpecIntoComponent(ConvenienceConstructor, spec); 6539 6540 ("production" !== "development" ? invariant( 6541 Constructor.prototype.render, 6542 'createClass(...): Class specification must implement a `render` method.' 6543 ) : invariant(Constructor.prototype.render)); 6544 6545 if ("production" !== "development") { 6546 if (Constructor.prototype.componentShouldUpdate) { 6547 monitorCodeUse( 6548 'react_component_should_update_warning', 6549 { component: spec.displayName } 6550 ); 6551 console.warn( 6552 (spec.displayName || 'A component') + ' has a method called ' + 6553 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 6554 'The name is phrased as a question because the function is ' + 6555 'expected to return a value.' 6556 ); 6557 } 6558 } 6559 6560 // Expose the convience constructor on the prototype so that it can be 6561 // easily accessed on descriptors. E.g. <Foo />.type === Foo.type and for 6562 // static methods like <Foo />.type.staticMethod(); 6563 // This should not be named constructor since this may not be the function 6564 // that created the descriptor, and it may not even be a constructor. 6565 ConvenienceConstructor.type = Constructor; 6566 Constructor.prototype.type = Constructor; 6567 6568 // Reduce time spent doing lookups by setting these on the prototype. 6569 for (var methodName in ReactCompositeComponentInterface) { 6570 if (!Constructor.prototype[methodName]) { 6571 Constructor.prototype[methodName] = null; 6572 } 6573 } 6574 6575 if ("production" !== "development") { 6576 // In DEV the convenience constructor generates a proxy to another 6577 // instance around it to warn about access to properties on the 6578 // descriptor. 6579 DescriptorConstructor = createDescriptorProxy(Constructor); 6580 } 6581 6582 return ConvenienceConstructor; 6583 }, 6584 6585 isValidClass: isValidClass, 6586 6587 injection: { 6588 injectMixin: function(mixin) { 6589 injectedMixins.push(mixin); 6590 } 6591 } 6592 }; 6593 6594 module.exports = ReactCompositeComponent; 6595 6596 },{"./ReactComponent":31,"./ReactContext":34,"./ReactCurrentOwner":35,"./ReactErrorUtils":51,"./ReactOwner":64,"./ReactPerf":65,"./ReactPropTransferer":66,"./ReactPropTypeLocationNames":67,"./ReactPropTypeLocations":68,"./ReactUpdates":81,"./instantiateReactComponent":124,"./invariant":125,"./keyMirror":131,"./merge":134,"./mixInto":137,"./monitorCodeUse":138,"./objMap":139,"./shouldUpdateReactComponent":144,"./warning":148}],34:[function(_dereq_,module,exports){ 6597 /** 6598 * Copyright 2013-2014 Facebook, Inc. 6599 * 6600 * Licensed under the Apache License, Version 2.0 (the "License"); 6601 * you may not use this file except in compliance with the License. 6602 * You may obtain a copy of the License at 6603 * 6604 * http://www.apache.org/licenses/LICENSE-2.0 6605 * 6606 * Unless required by applicable law or agreed to in writing, software 6607 * distributed under the License is distributed on an "AS IS" BASIS, 6608 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 6609 * See the License for the specific language governing permissions and 6610 * limitations under the License. 6611 * 6612 * @providesModule ReactContext 6613 */ 6614 6615 "use strict"; 6616 6617 var merge = _dereq_("./merge"); 6618 6619 /** 6620 * Keeps track of the current context. 6621 * 6622 * The context is automatically passed down the component ownership hierarchy 6623 * and is accessible via `this.context` on ReactCompositeComponents. 6624 */ 6625 var ReactContext = { 6626 6627 /** 6628 * @internal 6629 * @type {object} 6630 */ 6631 current: {}, 6632 6633 /** 6634 * Temporarily extends the current context while executing scopedCallback. 6635 * 6636 * A typical use case might look like 6637 * 6638 * render: function() { 6639 * var children = ReactContext.withContext({foo: 'foo'} () => ( 6640 * 6641 * )); 6642 * return <div>{children}</div>; 6643 * } 6644 * 6645 * @param {object} newContext New context to merge into the existing context 6646 * @param {function} scopedCallback Callback to run with the new context 6647 * @return {ReactComponent|array<ReactComponent>} 6648 */ 6649 withContext: function(newContext, scopedCallback) { 6650 var result; 6651 var previousContext = ReactContext.current; 6652 ReactContext.current = merge(previousContext, newContext); 6653 try { 6654 result = scopedCallback(); 6655 } finally { 6656 ReactContext.current = previousContext; 6657 } 6658 return result; 6659 } 6660 6661 }; 6662 6663 module.exports = ReactContext; 6664 6665 },{"./merge":134}],35:[function(_dereq_,module,exports){ 6666 /** 6667 * Copyright 2013-2014 Facebook, Inc. 6668 * 6669 * Licensed under the Apache License, Version 2.0 (the "License"); 6670 * you may not use this file except in compliance with the License. 6671 * You may obtain a copy of the License at 6672 * 6673 * http://www.apache.org/licenses/LICENSE-2.0 6674 * 6675 * Unless required by applicable law or agreed to in writing, software 6676 * distributed under the License is distributed on an "AS IS" BASIS, 6677 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 6678 * See the License for the specific language governing permissions and 6679 * limitations under the License. 6680 * 6681 * @providesModule ReactCurrentOwner 6682 */ 6683 6684 "use strict"; 6685 6686 /** 6687 * Keeps track of the current owner. 6688 * 6689 * The current owner is the component who should own any components that are 6690 * currently being constructed. 6691 * 6692 * The depth indicate how many composite components are above this render level. 6693 */ 6694 var ReactCurrentOwner = { 6695 6696 /** 6697 * @internal 6698 * @type {ReactComponent} 6699 */ 6700 current: null 6701 6702 }; 6703 6704 module.exports = ReactCurrentOwner; 6705 6706 },{}],36:[function(_dereq_,module,exports){ 6707 /** 6708 * Copyright 2013-2014 Facebook, Inc. 6709 * 6710 * Licensed under the Apache License, Version 2.0 (the "License"); 6711 * you may not use this file except in compliance with the License. 6712 * You may obtain a copy of the License at 6713 * 6714 * http://www.apache.org/licenses/LICENSE-2.0 6715 * 6716 * Unless required by applicable law or agreed to in writing, software 6717 * distributed under the License is distributed on an "AS IS" BASIS, 6718 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 6719 * See the License for the specific language governing permissions and 6720 * limitations under the License. 6721 * 6722 * @providesModule ReactDOM 6723 * @typechecks static-only 6724 */ 6725 6726 "use strict"; 6727 6728 var ReactDOMComponent = _dereq_("./ReactDOMComponent"); 6729 6730 var mergeInto = _dereq_("./mergeInto"); 6731 var objMapKeyVal = _dereq_("./objMapKeyVal"); 6732 6733 /** 6734 * Creates a new React class that is idempotent and capable of containing other 6735 * React components. It accepts event listeners and DOM properties that are 6736 * valid according to `DOMProperty`. 6737 * 6738 * - Event listeners: `onClick`, `onMouseDown`, etc. 6739 * - DOM properties: `className`, `name`, `title`, etc. 6740 * 6741 * The `style` property functions differently from the DOM API. It accepts an 6742 * object mapping of style properties to values. 6743 * 6744 * @param {string} tag Tag name (e.g. `div`). 6745 * @param {boolean} omitClose True if the close tag should be omitted. 6746 * @private 6747 */ 6748 function createDOMComponentClass(tag, omitClose) { 6749 var Constructor = function() {}; 6750 Constructor.prototype = new ReactDOMComponent(tag, omitClose); 6751 Constructor.prototype.constructor = Constructor; 6752 Constructor.displayName = tag; 6753 6754 var ConvenienceConstructor = function(props, children) { 6755 var instance = new Constructor(); 6756 instance.construct.apply(instance, arguments); 6757 return instance; 6758 }; 6759 6760 // Expose the constructor on the ConvenienceConstructor and prototype so that 6761 // it can be easily easily accessed on descriptors. 6762 // E.g. <div />.type === div.type 6763 ConvenienceConstructor.type = Constructor; 6764 Constructor.prototype.type = Constructor; 6765 6766 Constructor.ConvenienceConstructor = ConvenienceConstructor; 6767 ConvenienceConstructor.componentConstructor = Constructor; 6768 return ConvenienceConstructor; 6769 } 6770 6771 /** 6772 * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. 6773 * This is also accessible via `React.DOM`. 6774 * 6775 * @public 6776 */ 6777 var ReactDOM = objMapKeyVal({ 6778 a: false, 6779 abbr: false, 6780 address: false, 6781 area: true, 6782 article: false, 6783 aside: false, 6784 audio: false, 6785 b: false, 6786 base: true, 6787 bdi: false, 6788 bdo: false, 6789 big: false, 6790 blockquote: false, 6791 body: false, 6792 br: true, 6793 button: false, 6794 canvas: false, 6795 caption: false, 6796 cite: false, 6797 code: false, 6798 col: true, 6799 colgroup: false, 6800 data: false, 6801 datalist: false, 6802 dd: false, 6803 del: false, 6804 details: false, 6805 dfn: false, 6806 div: false, 6807 dl: false, 6808 dt: false, 6809 em: false, 6810 embed: true, 6811 fieldset: false, 6812 figcaption: false, 6813 figure: false, 6814 footer: false, 6815 form: false, // NOTE: Injected, see `ReactDOMForm`. 6816 h1: false, 6817 h2: false, 6818 h3: false, 6819 h4: false, 6820 h5: false, 6821 h6: false, 6822 head: false, 6823 header: false, 6824 hr: true, 6825 html: false, 6826 i: false, 6827 iframe: false, 6828 img: true, 6829 input: true, 6830 ins: false, 6831 kbd: false, 6832 keygen: true, 6833 label: false, 6834 legend: false, 6835 li: false, 6836 link: true, 6837 main: false, 6838 map: false, 6839 mark: false, 6840 menu: false, 6841 menuitem: false, // NOTE: Close tag should be omitted, but causes problems. 6842 meta: true, 6843 meter: false, 6844 nav: false, 6845 noscript: false, 6846 object: false, 6847 ol: false, 6848 optgroup: false, 6849 option: false, 6850 output: false, 6851 p: false, 6852 param: true, 6853 pre: false, 6854 progress: false, 6855 q: false, 6856 rp: false, 6857 rt: false, 6858 ruby: false, 6859 s: false, 6860 samp: false, 6861 script: false, 6862 section: false, 6863 select: false, 6864 small: false, 6865 source: true, 6866 span: false, 6867 strong: false, 6868 style: false, 6869 sub: false, 6870 summary: false, 6871 sup: false, 6872 table: false, 6873 tbody: false, 6874 td: false, 6875 textarea: false, // NOTE: Injected, see `ReactDOMTextarea`. 6876 tfoot: false, 6877 th: false, 6878 thead: false, 6879 time: false, 6880 title: false, 6881 tr: false, 6882 track: true, 6883 u: false, 6884 ul: false, 6885 'var': false, 6886 video: false, 6887 wbr: true, 6888 6889 // SVG 6890 circle: false, 6891 defs: false, 6892 g: false, 6893 line: false, 6894 linearGradient: false, 6895 path: false, 6896 polygon: false, 6897 polyline: false, 6898 radialGradient: false, 6899 rect: false, 6900 stop: false, 6901 svg: false, 6902 text: false 6903 }, createDOMComponentClass); 6904 6905 var injection = { 6906 injectComponentClasses: function(componentClasses) { 6907 mergeInto(ReactDOM, componentClasses); 6908 } 6909 }; 6910 6911 ReactDOM.injection = injection; 6912 6913 module.exports = ReactDOM; 6914 6915 },{"./ReactDOMComponent":38,"./mergeInto":136,"./objMapKeyVal":140}],37:[function(_dereq_,module,exports){ 6916 /** 6917 * Copyright 2013-2014 Facebook, Inc. 6918 * 6919 * Licensed under the Apache License, Version 2.0 (the "License"); 6920 * you may not use this file except in compliance with the License. 6921 * You may obtain a copy of the License at 6922 * 6923 * http://www.apache.org/licenses/LICENSE-2.0 6924 * 6925 * Unless required by applicable law or agreed to in writing, software 6926 * distributed under the License is distributed on an "AS IS" BASIS, 6927 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 6928 * See the License for the specific language governing permissions and 6929 * limitations under the License. 6930 * 6931 * @providesModule ReactDOMButton 6932 */ 6933 6934 "use strict"; 6935 6936 var AutoFocusMixin = _dereq_("./AutoFocusMixin"); 6937 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 6938 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 6939 var ReactDOM = _dereq_("./ReactDOM"); 6940 6941 var keyMirror = _dereq_("./keyMirror"); 6942 6943 // Store a reference to the <button> `ReactDOMComponent`. 6944 var button = ReactDOM.button; 6945 6946 var mouseListenerNames = keyMirror({ 6947 onClick: true, 6948 onDoubleClick: true, 6949 onMouseDown: true, 6950 onMouseMove: true, 6951 onMouseUp: true, 6952 onClickCapture: true, 6953 onDoubleClickCapture: true, 6954 onMouseDownCapture: true, 6955 onMouseMoveCapture: true, 6956 onMouseUpCapture: true 6957 }); 6958 6959 /** 6960 * Implements a <button> native component that does not receive mouse events 6961 * when `disabled` is set. 6962 */ 6963 var ReactDOMButton = ReactCompositeComponent.createClass({ 6964 displayName: 'ReactDOMButton', 6965 6966 mixins: [AutoFocusMixin, ReactBrowserComponentMixin], 6967 6968 render: function() { 6969 var props = {}; 6970 6971 // Copy the props; except the mouse listeners if we're disabled 6972 for (var key in this.props) { 6973 if (this.props.hasOwnProperty(key) && 6974 (!this.props.disabled || !mouseListenerNames[key])) { 6975 props[key] = this.props[key]; 6976 } 6977 } 6978 6979 return button(props, this.props.children); 6980 } 6981 6982 }); 6983 6984 module.exports = ReactDOMButton; 6985 6986 },{"./AutoFocusMixin":1,"./ReactBrowserComponentMixin":27,"./ReactCompositeComponent":33,"./ReactDOM":36,"./keyMirror":131}],38:[function(_dereq_,module,exports){ 6987 /** 6988 * Copyright 2013-2014 Facebook, Inc. 6989 * 6990 * Licensed under the Apache License, Version 2.0 (the "License"); 6991 * you may not use this file except in compliance with the License. 6992 * You may obtain a copy of the License at 6993 * 6994 * http://www.apache.org/licenses/LICENSE-2.0 6995 * 6996 * Unless required by applicable law or agreed to in writing, software 6997 * distributed under the License is distributed on an "AS IS" BASIS, 6998 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 6999 * See the License for the specific language governing permissions and 7000 * limitations under the License. 7001 * 7002 * @providesModule ReactDOMComponent 7003 * @typechecks static-only 7004 */ 7005 7006 "use strict"; 7007 7008 var CSSPropertyOperations = _dereq_("./CSSPropertyOperations"); 7009 var DOMProperty = _dereq_("./DOMProperty"); 7010 var DOMPropertyOperations = _dereq_("./DOMPropertyOperations"); 7011 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 7012 var ReactComponent = _dereq_("./ReactComponent"); 7013 var ReactEventEmitter = _dereq_("./ReactEventEmitter"); 7014 var ReactMount = _dereq_("./ReactMount"); 7015 var ReactMultiChild = _dereq_("./ReactMultiChild"); 7016 var ReactPerf = _dereq_("./ReactPerf"); 7017 7018 var escapeTextForBrowser = _dereq_("./escapeTextForBrowser"); 7019 var invariant = _dereq_("./invariant"); 7020 var keyOf = _dereq_("./keyOf"); 7021 var merge = _dereq_("./merge"); 7022 var mixInto = _dereq_("./mixInto"); 7023 7024 var deleteListener = ReactEventEmitter.deleteListener; 7025 var listenTo = ReactEventEmitter.listenTo; 7026 var registrationNameModules = ReactEventEmitter.registrationNameModules; 7027 7028 // For quickly matching children type, to test if can be treated as content. 7029 var CONTENT_TYPES = {'string': true, 'number': true}; 7030 7031 var STYLE = keyOf({style: null}); 7032 7033 var ELEMENT_NODE_TYPE = 1; 7034 7035 /** 7036 * @param {?object} props 7037 */ 7038 function assertValidProps(props) { 7039 if (!props) { 7040 return; 7041 } 7042 // Note the use of `==` which checks for null or undefined. 7043 ("production" !== "development" ? invariant( 7044 props.children == null || props.dangerouslySetInnerHTML == null, 7045 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.' 7046 ) : invariant(props.children == null || props.dangerouslySetInnerHTML == null)); 7047 ("production" !== "development" ? invariant( 7048 props.style == null || typeof props.style === 'object', 7049 'The `style` prop expects a mapping from style properties to values, ' + 7050 'not a string.' 7051 ) : invariant(props.style == null || typeof props.style === 'object')); 7052 } 7053 7054 function putListener(id, registrationName, listener, transaction) { 7055 var container = ReactMount.findReactContainerForID(id); 7056 if (container) { 7057 var doc = container.nodeType === ELEMENT_NODE_TYPE ? 7058 container.ownerDocument : 7059 container; 7060 listenTo(registrationName, doc); 7061 } 7062 transaction.getPutListenerQueue().enqueuePutListener( 7063 id, 7064 registrationName, 7065 listener 7066 ); 7067 } 7068 7069 7070 /** 7071 * @constructor ReactDOMComponent 7072 * @extends ReactComponent 7073 * @extends ReactMultiChild 7074 */ 7075 function ReactDOMComponent(tag, omitClose) { 7076 this._tagOpen = '<' + tag; 7077 this._tagClose = omitClose ? '' : '</' + tag + '>'; 7078 this.tagName = tag.toUpperCase(); 7079 } 7080 7081 ReactDOMComponent.Mixin = { 7082 7083 /** 7084 * Generates root tag markup then recurses. This method has side effects and 7085 * is not idempotent. 7086 * 7087 * @internal 7088 * @param {string} rootID The root DOM ID for this node. 7089 * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction 7090 * @param {number} mountDepth number of components in the owner hierarchy 7091 * @return {string} The computed markup. 7092 */ 7093 mountComponent: ReactPerf.measure( 7094 'ReactDOMComponent', 7095 'mountComponent', 7096 function(rootID, transaction, mountDepth) { 7097 ReactComponent.Mixin.mountComponent.call( 7098 this, 7099 rootID, 7100 transaction, 7101 mountDepth 7102 ); 7103 assertValidProps(this.props); 7104 return ( 7105 this._createOpenTagMarkupAndPutListeners(transaction) + 7106 this._createContentMarkup(transaction) + 7107 this._tagClose 7108 ); 7109 } 7110 ), 7111 7112 /** 7113 * Creates markup for the open tag and all attributes. 7114 * 7115 * This method has side effects because events get registered. 7116 * 7117 * Iterating over object properties is faster than iterating over arrays. 7118 * @see http://jsperf.com/obj-vs-arr-iteration 7119 * 7120 * @private 7121 * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction 7122 * @return {string} Markup of opening tag. 7123 */ 7124 _createOpenTagMarkupAndPutListeners: function(transaction) { 7125 var props = this.props; 7126 var ret = this._tagOpen; 7127 7128 for (var propKey in props) { 7129 if (!props.hasOwnProperty(propKey)) { 7130 continue; 7131 } 7132 var propValue = props[propKey]; 7133 if (propValue == null) { 7134 continue; 7135 } 7136 if (registrationNameModules[propKey]) { 7137 putListener(this._rootNodeID, propKey, propValue, transaction); 7138 } else { 7139 if (propKey === STYLE) { 7140 if (propValue) { 7141 propValue = props.style = merge(props.style); 7142 } 7143 propValue = CSSPropertyOperations.createMarkupForStyles(propValue); 7144 } 7145 var markup = 7146 DOMPropertyOperations.createMarkupForProperty(propKey, propValue); 7147 if (markup) { 7148 ret += ' ' + markup; 7149 } 7150 } 7151 } 7152 7153 // For static pages, no need to put React ID and checksum. Saves lots of 7154 // bytes. 7155 if (transaction.renderToStaticMarkup) { 7156 return ret + '>'; 7157 } 7158 7159 var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID); 7160 return ret + ' ' + markupForID + '>'; 7161 }, 7162 7163 /** 7164 * Creates markup for the content between the tags. 7165 * 7166 * @private 7167 * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction 7168 * @return {string} Content markup. 7169 */ 7170 _createContentMarkup: function(transaction) { 7171 // Intentional use of != to avoid catching zero/false. 7172 var innerHTML = this.props.dangerouslySetInnerHTML; 7173 if (innerHTML != null) { 7174 if (innerHTML.__html != null) { 7175 return innerHTML.__html; 7176 } 7177 } else { 7178 var contentToUse = 7179 CONTENT_TYPES[typeof this.props.children] ? this.props.children : null; 7180 var childrenToUse = contentToUse != null ? null : this.props.children; 7181 if (contentToUse != null) { 7182 return escapeTextForBrowser(contentToUse); 7183 } else if (childrenToUse != null) { 7184 var mountImages = this.mountChildren( 7185 childrenToUse, 7186 transaction 7187 ); 7188 return mountImages.join(''); 7189 } 7190 } 7191 return ''; 7192 }, 7193 7194 receiveComponent: function(nextComponent, transaction) { 7195 if (nextComponent === this) { 7196 // Since props and context are immutable after the component is 7197 // mounted, we can do a cheap identity compare here to determine 7198 // if this is a superfluous reconcile. 7199 7200 // TODO: compare the descriptor 7201 return; 7202 } 7203 7204 assertValidProps(nextComponent.props); 7205 ReactComponent.Mixin.receiveComponent.call( 7206 this, 7207 nextComponent, 7208 transaction 7209 ); 7210 }, 7211 7212 /** 7213 * Updates a native DOM component after it has already been allocated and 7214 * attached to the DOM. Reconciles the root DOM node, then recurses. 7215 * 7216 * @param {ReactReconcileTransaction} transaction 7217 * @param {object} prevProps 7218 * @internal 7219 * @overridable 7220 */ 7221 updateComponent: ReactPerf.measure( 7222 'ReactDOMComponent', 7223 'updateComponent', 7224 function(transaction, prevProps, prevOwner) { 7225 ReactComponent.Mixin.updateComponent.call( 7226 this, 7227 transaction, 7228 prevProps, 7229 prevOwner 7230 ); 7231 this._updateDOMProperties(prevProps, transaction); 7232 this._updateDOMChildren(prevProps, transaction); 7233 } 7234 ), 7235 7236 /** 7237 * Reconciles the properties by detecting differences in property values and 7238 * updating the DOM as necessary. This function is probably the single most 7239 * critical path for performance optimization. 7240 * 7241 * TODO: Benchmark whether checking for changed values in memory actually 7242 * improves performance (especially statically positioned elements). 7243 * TODO: Benchmark the effects of putting this at the top since 99% of props 7244 * do not change for a given reconciliation. 7245 * TODO: Benchmark areas that can be improved with caching. 7246 * 7247 * @private 7248 * @param {object} lastProps 7249 * @param {ReactReconcileTransaction} transaction 7250 */ 7251 _updateDOMProperties: function(lastProps, transaction) { 7252 var nextProps = this.props; 7253 var propKey; 7254 var styleName; 7255 var styleUpdates; 7256 for (propKey in lastProps) { 7257 if (nextProps.hasOwnProperty(propKey) || 7258 !lastProps.hasOwnProperty(propKey)) { 7259 continue; 7260 } 7261 if (propKey === STYLE) { 7262 var lastStyle = lastProps[propKey]; 7263 for (styleName in lastStyle) { 7264 if (lastStyle.hasOwnProperty(styleName)) { 7265 styleUpdates = styleUpdates || {}; 7266 styleUpdates[styleName] = ''; 7267 } 7268 } 7269 } else if (registrationNameModules[propKey]) { 7270 deleteListener(this._rootNodeID, propKey); 7271 } else if ( 7272 DOMProperty.isStandardName[propKey] || 7273 DOMProperty.isCustomAttribute(propKey)) { 7274 ReactComponent.BackendIDOperations.deletePropertyByID( 7275 this._rootNodeID, 7276 propKey 7277 ); 7278 } 7279 } 7280 for (propKey in nextProps) { 7281 var nextProp = nextProps[propKey]; 7282 var lastProp = lastProps[propKey]; 7283 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) { 7284 continue; 7285 } 7286 if (propKey === STYLE) { 7287 if (nextProp) { 7288 nextProp = nextProps.style = merge(nextProp); 7289 } 7290 if (lastProp) { 7291 // Unset styles on `lastProp` but not on `nextProp`. 7292 for (styleName in lastProp) { 7293 if (lastProp.hasOwnProperty(styleName) && 7294 !nextProp.hasOwnProperty(styleName)) { 7295 styleUpdates = styleUpdates || {}; 7296 styleUpdates[styleName] = ''; 7297 } 7298 } 7299 // Update styles that changed since `lastProp`. 7300 for (styleName in nextProp) { 7301 if (nextProp.hasOwnProperty(styleName) && 7302 lastProp[styleName] !== nextProp[styleName]) { 7303 styleUpdates = styleUpdates || {}; 7304 styleUpdates[styleName] = nextProp[styleName]; 7305 } 7306 } 7307 } else { 7308 // Relies on `updateStylesByID` not mutating `styleUpdates`. 7309 styleUpdates = nextProp; 7310 } 7311 } else if (registrationNameModules[propKey]) { 7312 putListener(this._rootNodeID, propKey, nextProp, transaction); 7313 } else if ( 7314 DOMProperty.isStandardName[propKey] || 7315 DOMProperty.isCustomAttribute(propKey)) { 7316 ReactComponent.BackendIDOperations.updatePropertyByID( 7317 this._rootNodeID, 7318 propKey, 7319 nextProp 7320 ); 7321 } 7322 } 7323 if (styleUpdates) { 7324 ReactComponent.BackendIDOperations.updateStylesByID( 7325 this._rootNodeID, 7326 styleUpdates 7327 ); 7328 } 7329 }, 7330 7331 /** 7332 * Reconciles the children with the various properties that affect the 7333 * children content. 7334 * 7335 * @param {object} lastProps 7336 * @param {ReactReconcileTransaction} transaction 7337 */ 7338 _updateDOMChildren: function(lastProps, transaction) { 7339 var nextProps = this.props; 7340 7341 var lastContent = 7342 CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null; 7343 var nextContent = 7344 CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null; 7345 7346 var lastHtml = 7347 lastProps.dangerouslySetInnerHTML && 7348 lastProps.dangerouslySetInnerHTML.__html; 7349 var nextHtml = 7350 nextProps.dangerouslySetInnerHTML && 7351 nextProps.dangerouslySetInnerHTML.__html; 7352 7353 // Note the use of `!=` which checks for null or undefined. 7354 var lastChildren = lastContent != null ? null : lastProps.children; 7355 var nextChildren = nextContent != null ? null : nextProps.children; 7356 7357 // If we're switching from children to content/html or vice versa, remove 7358 // the old content 7359 var lastHasContentOrHtml = lastContent != null || lastHtml != null; 7360 var nextHasContentOrHtml = nextContent != null || nextHtml != null; 7361 if (lastChildren != null && nextChildren == null) { 7362 this.updateChildren(null, transaction); 7363 } else if (lastHasContentOrHtml && !nextHasContentOrHtml) { 7364 this.updateTextContent(''); 7365 } 7366 7367 if (nextContent != null) { 7368 if (lastContent !== nextContent) { 7369 this.updateTextContent('' + nextContent); 7370 } 7371 } else if (nextHtml != null) { 7372 if (lastHtml !== nextHtml) { 7373 ReactComponent.BackendIDOperations.updateInnerHTMLByID( 7374 this._rootNodeID, 7375 nextHtml 7376 ); 7377 } 7378 } else if (nextChildren != null) { 7379 this.updateChildren(nextChildren, transaction); 7380 } 7381 }, 7382 7383 /** 7384 * Destroys all event registrations for this instance. Does not remove from 7385 * the DOM. That must be done by the parent. 7386 * 7387 * @internal 7388 */ 7389 unmountComponent: function() { 7390 this.unmountChildren(); 7391 ReactEventEmitter.deleteAllListeners(this._rootNodeID); 7392 ReactComponent.Mixin.unmountComponent.call(this); 7393 } 7394 7395 }; 7396 7397 mixInto(ReactDOMComponent, ReactComponent.Mixin); 7398 mixInto(ReactDOMComponent, ReactDOMComponent.Mixin); 7399 mixInto(ReactDOMComponent, ReactMultiChild.Mixin); 7400 mixInto(ReactDOMComponent, ReactBrowserComponentMixin); 7401 7402 module.exports = ReactDOMComponent; 7403 7404 },{"./CSSPropertyOperations":4,"./DOMProperty":9,"./DOMPropertyOperations":10,"./ReactBrowserComponentMixin":27,"./ReactComponent":31,"./ReactEventEmitter":52,"./ReactMount":60,"./ReactMultiChild":62,"./ReactPerf":65,"./escapeTextForBrowser":111,"./invariant":125,"./keyOf":132,"./merge":134,"./mixInto":137}],39:[function(_dereq_,module,exports){ 7405 /** 7406 * Copyright 2013-2014 Facebook, Inc. 7407 * 7408 * Licensed under the Apache License, Version 2.0 (the "License"); 7409 * you may not use this file except in compliance with the License. 7410 * You may obtain a copy of the License at 7411 * 7412 * http://www.apache.org/licenses/LICENSE-2.0 7413 * 7414 * Unless required by applicable law or agreed to in writing, software 7415 * distributed under the License is distributed on an "AS IS" BASIS, 7416 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 7417 * See the License for the specific language governing permissions and 7418 * limitations under the License. 7419 * 7420 * @providesModule ReactDOMForm 7421 */ 7422 7423 "use strict"; 7424 7425 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 7426 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 7427 var ReactDOM = _dereq_("./ReactDOM"); 7428 var ReactEventEmitter = _dereq_("./ReactEventEmitter"); 7429 var EventConstants = _dereq_("./EventConstants"); 7430 7431 // Store a reference to the <form> `ReactDOMComponent`. 7432 var form = ReactDOM.form; 7433 7434 /** 7435 * Since onSubmit doesn't bubble OR capture on the top level in IE8, we need 7436 * to capture it on the <form> element itself. There are lots of hacks we could 7437 * do to accomplish this, but the most reliable is to make <form> a 7438 * composite component and use `componentDidMount` to attach the event handlers. 7439 */ 7440 var ReactDOMForm = ReactCompositeComponent.createClass({ 7441 displayName: 'ReactDOMForm', 7442 7443 mixins: [ReactBrowserComponentMixin], 7444 7445 render: function() { 7446 // TODO: Instead of using `ReactDOM` directly, we should use JSX. However, 7447 // `jshint` fails to parse JSX so in order for linting to work in the open 7448 // source repo, we need to just use `ReactDOM.form`. 7449 return this.transferPropsTo(form(null, this.props.children)); 7450 }, 7451 7452 componentDidMount: function() { 7453 ReactEventEmitter.trapBubbledEvent( 7454 EventConstants.topLevelTypes.topReset, 7455 'reset', 7456 this.getDOMNode() 7457 ); 7458 ReactEventEmitter.trapBubbledEvent( 7459 EventConstants.topLevelTypes.topSubmit, 7460 'submit', 7461 this.getDOMNode() 7462 ); 7463 } 7464 }); 7465 7466 module.exports = ReactDOMForm; 7467 7468 },{"./EventConstants":15,"./ReactBrowserComponentMixin":27,"./ReactCompositeComponent":33,"./ReactDOM":36,"./ReactEventEmitter":52}],40:[function(_dereq_,module,exports){ 7469 /** 7470 * Copyright 2013-2014 Facebook, Inc. 7471 * 7472 * Licensed under the Apache License, Version 2.0 (the "License"); 7473 * you may not use this file except in compliance with the License. 7474 * You may obtain a copy of the License at 7475 * 7476 * http://www.apache.org/licenses/LICENSE-2.0 7477 * 7478 * Unless required by applicable law or agreed to in writing, software 7479 * distributed under the License is distributed on an "AS IS" BASIS, 7480 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 7481 * See the License for the specific language governing permissions and 7482 * limitations under the License. 7483 * 7484 * @providesModule ReactDOMIDOperations 7485 * @typechecks static-only 7486 */ 7487 7488 /*jslint evil: true */ 7489 7490 "use strict"; 7491 7492 var CSSPropertyOperations = _dereq_("./CSSPropertyOperations"); 7493 var DOMChildrenOperations = _dereq_("./DOMChildrenOperations"); 7494 var DOMPropertyOperations = _dereq_("./DOMPropertyOperations"); 7495 var ReactMount = _dereq_("./ReactMount"); 7496 var ReactPerf = _dereq_("./ReactPerf"); 7497 7498 var invariant = _dereq_("./invariant"); 7499 7500 /** 7501 * Errors for properties that should not be updated with `updatePropertyById()`. 7502 * 7503 * @type {object} 7504 * @private 7505 */ 7506 var INVALID_PROPERTY_ERRORS = { 7507 dangerouslySetInnerHTML: 7508 '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.', 7509 style: '`style` must be set using `updateStylesByID()`.' 7510 }; 7511 7512 var useWhitespaceWorkaround; 7513 7514 /** 7515 * Operations used to process updates to DOM nodes. This is made injectable via 7516 * `ReactComponent.BackendIDOperations`. 7517 */ 7518 var ReactDOMIDOperations = { 7519 7520 /** 7521 * Updates a DOM node with new property values. This should only be used to 7522 * update DOM properties in `DOMProperty`. 7523 * 7524 * @param {string} id ID of the node to update. 7525 * @param {string} name A valid property name, see `DOMProperty`. 7526 * @param {*} value New value of the property. 7527 * @internal 7528 */ 7529 updatePropertyByID: ReactPerf.measure( 7530 'ReactDOMIDOperations', 7531 'updatePropertyByID', 7532 function(id, name, value) { 7533 var node = ReactMount.getNode(id); 7534 ("production" !== "development" ? invariant( 7535 !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), 7536 'updatePropertyByID(...): %s', 7537 INVALID_PROPERTY_ERRORS[name] 7538 ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); 7539 7540 // If we're updating to null or undefined, we should remove the property 7541 // from the DOM node instead of inadvertantly setting to a string. This 7542 // brings us in line with the same behavior we have on initial render. 7543 if (value != null) { 7544 DOMPropertyOperations.setValueForProperty(node, name, value); 7545 } else { 7546 DOMPropertyOperations.deleteValueForProperty(node, name); 7547 } 7548 } 7549 ), 7550 7551 /** 7552 * Updates a DOM node to remove a property. This should only be used to remove 7553 * DOM properties in `DOMProperty`. 7554 * 7555 * @param {string} id ID of the node to update. 7556 * @param {string} name A property name to remove, see `DOMProperty`. 7557 * @internal 7558 */ 7559 deletePropertyByID: ReactPerf.measure( 7560 'ReactDOMIDOperations', 7561 'deletePropertyByID', 7562 function(id, name, value) { 7563 var node = ReactMount.getNode(id); 7564 ("production" !== "development" ? invariant( 7565 !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), 7566 'updatePropertyByID(...): %s', 7567 INVALID_PROPERTY_ERRORS[name] 7568 ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); 7569 DOMPropertyOperations.deleteValueForProperty(node, name, value); 7570 } 7571 ), 7572 7573 /** 7574 * Updates a DOM node with new style values. If a value is specified as '', 7575 * the corresponding style property will be unset. 7576 * 7577 * @param {string} id ID of the node to update. 7578 * @param {object} styles Mapping from styles to values. 7579 * @internal 7580 */ 7581 updateStylesByID: ReactPerf.measure( 7582 'ReactDOMIDOperations', 7583 'updateStylesByID', 7584 function(id, styles) { 7585 var node = ReactMount.getNode(id); 7586 CSSPropertyOperations.setValueForStyles(node, styles); 7587 } 7588 ), 7589 7590 /** 7591 * Updates a DOM node's innerHTML. 7592 * 7593 * @param {string} id ID of the node to update. 7594 * @param {string} html An HTML string. 7595 * @internal 7596 */ 7597 updateInnerHTMLByID: ReactPerf.measure( 7598 'ReactDOMIDOperations', 7599 'updateInnerHTMLByID', 7600 function(id, html) { 7601 var node = ReactMount.getNode(id); 7602 7603 // IE8: When updating a just created node with innerHTML only leading 7604 // whitespace is removed. When updating an existing node with innerHTML 7605 // whitespace in root TextNodes is also collapsed. 7606 // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html 7607 7608 if (useWhitespaceWorkaround === undefined) { 7609 // Feature detection; only IE8 is known to behave improperly like this. 7610 var temp = document.createElement('div'); 7611 temp.innerHTML = ' '; 7612 useWhitespaceWorkaround = temp.innerHTML === ''; 7613 } 7614 7615 if (useWhitespaceWorkaround) { 7616 // Magic theory: IE8 supposedly differentiates between added and updated 7617 // nodes when processing innerHTML, innerHTML on updated nodes suffers 7618 // from worse whitespace behavior. Re-adding a node like this triggers 7619 // the initial and more favorable whitespace behavior. 7620 node.parentNode.replaceChild(node, node); 7621 } 7622 7623 if (useWhitespaceWorkaround && html.match(/^[ \r\n\t\f]/)) { 7624 // Recover leading whitespace by temporarily prepending any character. 7625 // \uFEFF has the potential advantage of being zero-width/invisible. 7626 node.innerHTML = '\uFEFF' + html; 7627 node.firstChild.deleteData(0, 1); 7628 } else { 7629 node.innerHTML = html; 7630 } 7631 } 7632 ), 7633 7634 /** 7635 * Updates a DOM node's text content set by `props.content`. 7636 * 7637 * @param {string} id ID of the node to update. 7638 * @param {string} content Text content. 7639 * @internal 7640 */ 7641 updateTextContentByID: ReactPerf.measure( 7642 'ReactDOMIDOperations', 7643 'updateTextContentByID', 7644 function(id, content) { 7645 var node = ReactMount.getNode(id); 7646 DOMChildrenOperations.updateTextContent(node, content); 7647 } 7648 ), 7649 7650 /** 7651 * Replaces a DOM node that exists in the document with markup. 7652 * 7653 * @param {string} id ID of child to be replaced. 7654 * @param {string} markup Dangerous markup to inject in place of child. 7655 * @internal 7656 * @see {Danger.dangerouslyReplaceNodeWithMarkup} 7657 */ 7658 dangerouslyReplaceNodeWithMarkupByID: ReactPerf.measure( 7659 'ReactDOMIDOperations', 7660 'dangerouslyReplaceNodeWithMarkupByID', 7661 function(id, markup) { 7662 var node = ReactMount.getNode(id); 7663 DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup); 7664 } 7665 ), 7666 7667 /** 7668 * Updates a component's children by processing a series of updates. 7669 * 7670 * @param {array<object>} updates List of update configurations. 7671 * @param {array<string>} markup List of markup strings. 7672 * @internal 7673 */ 7674 dangerouslyProcessChildrenUpdates: ReactPerf.measure( 7675 'ReactDOMIDOperations', 7676 'dangerouslyProcessChildrenUpdates', 7677 function(updates, markup) { 7678 for (var i = 0; i < updates.length; i++) { 7679 updates[i].parentNode = ReactMount.getNode(updates[i].parentID); 7680 } 7681 DOMChildrenOperations.processUpdates(updates, markup); 7682 } 7683 ) 7684 }; 7685 7686 module.exports = ReactDOMIDOperations; 7687 7688 },{"./CSSPropertyOperations":4,"./DOMChildrenOperations":8,"./DOMPropertyOperations":10,"./ReactMount":60,"./ReactPerf":65,"./invariant":125}],41:[function(_dereq_,module,exports){ 7689 /** 7690 * Copyright 2013-2014 Facebook, Inc. 7691 * 7692 * Licensed under the Apache License, Version 2.0 (the "License"); 7693 * you may not use this file except in compliance with the License. 7694 * You may obtain a copy of the License at 7695 * 7696 * http://www.apache.org/licenses/LICENSE-2.0 7697 * 7698 * Unless required by applicable law or agreed to in writing, software 7699 * distributed under the License is distributed on an "AS IS" BASIS, 7700 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 7701 * See the License for the specific language governing permissions and 7702 * limitations under the License. 7703 * 7704 * @providesModule ReactDOMImg 7705 */ 7706 7707 "use strict"; 7708 7709 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 7710 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 7711 var ReactDOM = _dereq_("./ReactDOM"); 7712 var ReactEventEmitter = _dereq_("./ReactEventEmitter"); 7713 var EventConstants = _dereq_("./EventConstants"); 7714 7715 // Store a reference to the <img> `ReactDOMComponent`. 7716 var img = ReactDOM.img; 7717 7718 /** 7719 * Since onLoad doesn't bubble OR capture on the top level in IE8, we need to 7720 * capture it on the <img> element itself. There are lots of hacks we could do 7721 * to accomplish this, but the most reliable is to make <img> a composite 7722 * component and use `componentDidMount` to attach the event handlers. 7723 */ 7724 var ReactDOMImg = ReactCompositeComponent.createClass({ 7725 displayName: 'ReactDOMImg', 7726 tagName: 'IMG', 7727 7728 mixins: [ReactBrowserComponentMixin], 7729 7730 render: function() { 7731 return img(this.props); 7732 }, 7733 7734 componentDidMount: function() { 7735 var node = this.getDOMNode(); 7736 ReactEventEmitter.trapBubbledEvent( 7737 EventConstants.topLevelTypes.topLoad, 7738 'load', 7739 node 7740 ); 7741 ReactEventEmitter.trapBubbledEvent( 7742 EventConstants.topLevelTypes.topError, 7743 'error', 7744 node 7745 ); 7746 } 7747 }); 7748 7749 module.exports = ReactDOMImg; 7750 7751 },{"./EventConstants":15,"./ReactBrowserComponentMixin":27,"./ReactCompositeComponent":33,"./ReactDOM":36,"./ReactEventEmitter":52}],42:[function(_dereq_,module,exports){ 7752 /** 7753 * Copyright 2013-2014 Facebook, Inc. 7754 * 7755 * Licensed under the Apache License, Version 2.0 (the "License"); 7756 * you may not use this file except in compliance with the License. 7757 * You may obtain a copy of the License at 7758 * 7759 * http://www.apache.org/licenses/LICENSE-2.0 7760 * 7761 * Unless required by applicable law or agreed to in writing, software 7762 * distributed under the License is distributed on an "AS IS" BASIS, 7763 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 7764 * See the License for the specific language governing permissions and 7765 * limitations under the License. 7766 * 7767 * @providesModule ReactDOMInput 7768 */ 7769 7770 "use strict"; 7771 7772 var AutoFocusMixin = _dereq_("./AutoFocusMixin"); 7773 var DOMPropertyOperations = _dereq_("./DOMPropertyOperations"); 7774 var LinkedValueUtils = _dereq_("./LinkedValueUtils"); 7775 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 7776 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 7777 var ReactDOM = _dereq_("./ReactDOM"); 7778 var ReactMount = _dereq_("./ReactMount"); 7779 7780 var invariant = _dereq_("./invariant"); 7781 var merge = _dereq_("./merge"); 7782 7783 // Store a reference to the <input> `ReactDOMComponent`. 7784 var input = ReactDOM.input; 7785 7786 var instancesByReactID = {}; 7787 7788 /** 7789 * Implements an <input> native component that allows setting these optional 7790 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. 7791 * 7792 * If `checked` or `value` are not supplied (or null/undefined), user actions 7793 * that affect the checked state or value will trigger updates to the element. 7794 * 7795 * If they are supplied (and not null/undefined), the rendered element will not 7796 * trigger updates to the element. Instead, the props must change in order for 7797 * the rendered element to be updated. 7798 * 7799 * The rendered element will be initialized as unchecked (or `defaultChecked`) 7800 * with an empty value (or `defaultValue`). 7801 * 7802 * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html 7803 */ 7804 var ReactDOMInput = ReactCompositeComponent.createClass({ 7805 displayName: 'ReactDOMInput', 7806 7807 mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], 7808 7809 getInitialState: function() { 7810 var defaultValue = this.props.defaultValue; 7811 return { 7812 checked: this.props.defaultChecked || false, 7813 value: defaultValue != null ? defaultValue : null 7814 }; 7815 }, 7816 7817 shouldComponentUpdate: function() { 7818 // Defer any updates to this component during the `onChange` handler. 7819 return !this._isChanging; 7820 }, 7821 7822 render: function() { 7823 // Clone `this.props` so we don't mutate the input. 7824 var props = merge(this.props); 7825 7826 props.defaultChecked = null; 7827 props.defaultValue = null; 7828 7829 var value = LinkedValueUtils.getValue(this); 7830 props.value = value != null ? value : this.state.value; 7831 7832 var checked = LinkedValueUtils.getChecked(this); 7833 props.checked = checked != null ? checked : this.state.checked; 7834 7835 props.onChange = this._handleChange; 7836 7837 return input(props, this.props.children); 7838 }, 7839 7840 componentDidMount: function() { 7841 var id = ReactMount.getID(this.getDOMNode()); 7842 instancesByReactID[id] = this; 7843 }, 7844 7845 componentWillUnmount: function() { 7846 var rootNode = this.getDOMNode(); 7847 var id = ReactMount.getID(rootNode); 7848 delete instancesByReactID[id]; 7849 }, 7850 7851 componentDidUpdate: function(prevProps, prevState, prevContext) { 7852 var rootNode = this.getDOMNode(); 7853 if (this.props.checked != null) { 7854 DOMPropertyOperations.setValueForProperty( 7855 rootNode, 7856 'checked', 7857 this.props.checked || false 7858 ); 7859 } 7860 7861 var value = LinkedValueUtils.getValue(this); 7862 if (value != null) { 7863 // Cast `value` to a string to ensure the value is set correctly. While 7864 // browsers typically do this as necessary, jsdom doesn't. 7865 DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); 7866 } 7867 }, 7868 7869 _handleChange: function(event) { 7870 var returnValue; 7871 var onChange = LinkedValueUtils.getOnChange(this); 7872 if (onChange) { 7873 this._isChanging = true; 7874 returnValue = onChange.call(this, event); 7875 this._isChanging = false; 7876 } 7877 this.setState({ 7878 checked: event.target.checked, 7879 value: event.target.value 7880 }); 7881 7882 var name = this.props.name; 7883 if (this.props.type === 'radio' && name != null) { 7884 var rootNode = this.getDOMNode(); 7885 var queryRoot = rootNode; 7886 7887 while (queryRoot.parentNode) { 7888 queryRoot = queryRoot.parentNode; 7889 } 7890 7891 // If `rootNode.form` was non-null, then we could try `form.elements`, 7892 // but that sometimes behaves strangely in IE8. We could also try using 7893 // `form.getElementsByName`, but that will only return direct children 7894 // and won't include inputs that use the HTML5 `form=` attribute. Since 7895 // the input might not even be in a form, let's just use the global 7896 // `querySelectorAll` to ensure we don't miss anything. 7897 var group = queryRoot.querySelectorAll( 7898 'input[name=' + JSON.stringify('' + name) + '][type="radio"]'); 7899 7900 for (var i = 0, groupLen = group.length; i < groupLen; i++) { 7901 var otherNode = group[i]; 7902 if (otherNode === rootNode || 7903 otherNode.form !== rootNode.form) { 7904 continue; 7905 } 7906 var otherID = ReactMount.getID(otherNode); 7907 ("production" !== "development" ? invariant( 7908 otherID, 7909 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 7910 'same `name` is not supported.' 7911 ) : invariant(otherID)); 7912 var otherInstance = instancesByReactID[otherID]; 7913 ("production" !== "development" ? invariant( 7914 otherInstance, 7915 'ReactDOMInput: Unknown radio button ID %s.', 7916 otherID 7917 ) : invariant(otherInstance)); 7918 // In some cases, this will actually change the `checked` state value. 7919 // In other cases, there's no change but this forces a reconcile upon 7920 // which componentDidUpdate will reset the DOM property to whatever it 7921 // should be. 7922 otherInstance.setState({ 7923 checked: false 7924 }); 7925 } 7926 } 7927 7928 return returnValue; 7929 } 7930 7931 }); 7932 7933 module.exports = ReactDOMInput; 7934 7935 },{"./AutoFocusMixin":1,"./DOMPropertyOperations":10,"./LinkedValueUtils":23,"./ReactBrowserComponentMixin":27,"./ReactCompositeComponent":33,"./ReactDOM":36,"./ReactMount":60,"./invariant":125,"./merge":134}],43:[function(_dereq_,module,exports){ 7936 /** 7937 * Copyright 2013-2014 Facebook, Inc. 7938 * 7939 * Licensed under the Apache License, Version 2.0 (the "License"); 7940 * you may not use this file except in compliance with the License. 7941 * You may obtain a copy of the License at 7942 * 7943 * http://www.apache.org/licenses/LICENSE-2.0 7944 * 7945 * Unless required by applicable law or agreed to in writing, software 7946 * distributed under the License is distributed on an "AS IS" BASIS, 7947 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 7948 * See the License for the specific language governing permissions and 7949 * limitations under the License. 7950 * 7951 * @providesModule ReactDOMOption 7952 */ 7953 7954 "use strict"; 7955 7956 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 7957 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 7958 var ReactDOM = _dereq_("./ReactDOM"); 7959 7960 var warning = _dereq_("./warning"); 7961 7962 // Store a reference to the <option> `ReactDOMComponent`. 7963 var option = ReactDOM.option; 7964 7965 /** 7966 * Implements an <option> native component that warns when `selected` is set. 7967 */ 7968 var ReactDOMOption = ReactCompositeComponent.createClass({ 7969 displayName: 'ReactDOMOption', 7970 7971 mixins: [ReactBrowserComponentMixin], 7972 7973 componentWillMount: function() { 7974 // TODO (yungsters): Remove support for `selected` in <option>. 7975 if ("production" !== "development") { 7976 ("production" !== "development" ? warning( 7977 this.props.selected == null, 7978 'Use the `defaultValue` or `value` props on <select> instead of ' + 7979 'setting `selected` on <option>.' 7980 ) : null); 7981 } 7982 }, 7983 7984 render: function() { 7985 return option(this.props, this.props.children); 7986 } 7987 7988 }); 7989 7990 module.exports = ReactDOMOption; 7991 7992 },{"./ReactBrowserComponentMixin":27,"./ReactCompositeComponent":33,"./ReactDOM":36,"./warning":148}],44:[function(_dereq_,module,exports){ 7993 /** 7994 * Copyright 2013-2014 Facebook, Inc. 7995 * 7996 * Licensed under the Apache License, Version 2.0 (the "License"); 7997 * you may not use this file except in compliance with the License. 7998 * You may obtain a copy of the License at 7999 * 8000 * http://www.apache.org/licenses/LICENSE-2.0 8001 * 8002 * Unless required by applicable law or agreed to in writing, software 8003 * distributed under the License is distributed on an "AS IS" BASIS, 8004 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 8005 * See the License for the specific language governing permissions and 8006 * limitations under the License. 8007 * 8008 * @providesModule ReactDOMSelect 8009 */ 8010 8011 "use strict"; 8012 8013 var AutoFocusMixin = _dereq_("./AutoFocusMixin"); 8014 var LinkedValueUtils = _dereq_("./LinkedValueUtils"); 8015 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 8016 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 8017 var ReactDOM = _dereq_("./ReactDOM"); 8018 8019 var invariant = _dereq_("./invariant"); 8020 var merge = _dereq_("./merge"); 8021 8022 // Store a reference to the <select> `ReactDOMComponent`. 8023 var select = ReactDOM.select; 8024 8025 /** 8026 * Validation function for `value` and `defaultValue`. 8027 * @private 8028 */ 8029 function selectValueType(props, propName, componentName) { 8030 if (props[propName] == null) { 8031 return; 8032 } 8033 if (props.multiple) { 8034 ("production" !== "development" ? invariant( 8035 Array.isArray(props[propName]), 8036 'The `%s` prop supplied to <select> must be an array if `multiple` is ' + 8037 'true.', 8038 propName 8039 ) : invariant(Array.isArray(props[propName]))); 8040 } else { 8041 ("production" !== "development" ? invariant( 8042 !Array.isArray(props[propName]), 8043 'The `%s` prop supplied to <select> must be a scalar value if ' + 8044 '`multiple` is false.', 8045 propName 8046 ) : invariant(!Array.isArray(props[propName]))); 8047 } 8048 } 8049 8050 /** 8051 * If `value` is supplied, updates <option> elements on mount and update. 8052 * @param {ReactComponent} component Instance of ReactDOMSelect 8053 * @param {?*} propValue For uncontrolled components, null/undefined. For 8054 * controlled components, a string (or with `multiple`, a list of strings). 8055 * @private 8056 */ 8057 function updateOptions(component, propValue) { 8058 var multiple = component.props.multiple; 8059 var value = propValue != null ? propValue : component.state.value; 8060 var options = component.getDOMNode().options; 8061 var selectedValue, i, l; 8062 if (multiple) { 8063 selectedValue = {}; 8064 for (i = 0, l = value.length; i < l; ++i) { 8065 selectedValue['' + value[i]] = true; 8066 } 8067 } else { 8068 selectedValue = '' + value; 8069 } 8070 for (i = 0, l = options.length; i < l; i++) { 8071 var selected = multiple ? 8072 selectedValue.hasOwnProperty(options[i].value) : 8073 options[i].value === selectedValue; 8074 8075 if (selected !== options[i].selected) { 8076 options[i].selected = selected; 8077 } 8078 } 8079 } 8080 8081 /** 8082 * Implements a <select> native component that allows optionally setting the 8083 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a 8084 * string. If `multiple` is true, the prop must be an array of strings. 8085 * 8086 * If `value` is not supplied (or null/undefined), user actions that change the 8087 * selected option will trigger updates to the rendered options. 8088 * 8089 * If it is supplied (and not null/undefined), the rendered options will not 8090 * update in response to user actions. Instead, the `value` prop must change in 8091 * order for the rendered options to update. 8092 * 8093 * If `defaultValue` is provided, any options with the supplied values will be 8094 * selected. 8095 */ 8096 var ReactDOMSelect = ReactCompositeComponent.createClass({ 8097 displayName: 'ReactDOMSelect', 8098 8099 mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], 8100 8101 propTypes: { 8102 defaultValue: selectValueType, 8103 value: selectValueType 8104 }, 8105 8106 getInitialState: function() { 8107 return {value: this.props.defaultValue || (this.props.multiple ? [] : '')}; 8108 }, 8109 8110 componentWillReceiveProps: function(nextProps) { 8111 if (!this.props.multiple && nextProps.multiple) { 8112 this.setState({value: [this.state.value]}); 8113 } else if (this.props.multiple && !nextProps.multiple) { 8114 this.setState({value: this.state.value[0]}); 8115 } 8116 }, 8117 8118 shouldComponentUpdate: function() { 8119 // Defer any updates to this component during the `onChange` handler. 8120 return !this._isChanging; 8121 }, 8122 8123 render: function() { 8124 // Clone `this.props` so we don't mutate the input. 8125 var props = merge(this.props); 8126 8127 props.onChange = this._handleChange; 8128 props.value = null; 8129 8130 return select(props, this.props.children); 8131 }, 8132 8133 componentDidMount: function() { 8134 updateOptions(this, LinkedValueUtils.getValue(this)); 8135 }, 8136 8137 componentDidUpdate: function() { 8138 var value = LinkedValueUtils.getValue(this); 8139 if (value != null) { 8140 updateOptions(this, value); 8141 } 8142 }, 8143 8144 _handleChange: function(event) { 8145 var returnValue; 8146 var onChange = LinkedValueUtils.getOnChange(this); 8147 if (onChange) { 8148 this._isChanging = true; 8149 returnValue = onChange.call(this, event); 8150 this._isChanging = false; 8151 } 8152 8153 var selectedValue; 8154 if (this.props.multiple) { 8155 selectedValue = []; 8156 var options = event.target.options; 8157 for (var i = 0, l = options.length; i < l; i++) { 8158 if (options[i].selected) { 8159 selectedValue.push(options[i].value); 8160 } 8161 } 8162 } else { 8163 selectedValue = event.target.value; 8164 } 8165 8166 this.setState({value: selectedValue}); 8167 return returnValue; 8168 } 8169 8170 }); 8171 8172 module.exports = ReactDOMSelect; 8173 8174 },{"./AutoFocusMixin":1,"./LinkedValueUtils":23,"./ReactBrowserComponentMixin":27,"./ReactCompositeComponent":33,"./ReactDOM":36,"./invariant":125,"./merge":134}],45:[function(_dereq_,module,exports){ 8175 /** 8176 * Copyright 2013-2014 Facebook, Inc. 8177 * 8178 * Licensed under the Apache License, Version 2.0 (the "License"); 8179 * you may not use this file except in compliance with the License. 8180 * You may obtain a copy of the License at 8181 * 8182 * http://www.apache.org/licenses/LICENSE-2.0 8183 * 8184 * Unless required by applicable law or agreed to in writing, software 8185 * distributed under the License is distributed on an "AS IS" BASIS, 8186 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 8187 * See the License for the specific language governing permissions and 8188 * limitations under the License. 8189 * 8190 * @providesModule ReactDOMSelection 8191 */ 8192 8193 "use strict"; 8194 8195 var getNodeForCharacterOffset = _dereq_("./getNodeForCharacterOffset"); 8196 var getTextContentAccessor = _dereq_("./getTextContentAccessor"); 8197 8198 /** 8199 * Get the appropriate anchor and focus node/offset pairs for IE. 8200 * 8201 * The catch here is that IE's selection API doesn't provide information 8202 * about whether the selection is forward or backward, so we have to 8203 * behave as though it's always forward. 8204 * 8205 * IE text differs from modern selection in that it behaves as though 8206 * block elements end with a new line. This means character offsets will 8207 * differ between the two APIs. 8208 * 8209 * @param {DOMElement} node 8210 * @return {object} 8211 */ 8212 function getIEOffsets(node) { 8213 var selection = document.selection; 8214 var selectedRange = selection.createRange(); 8215 var selectedLength = selectedRange.text.length; 8216 8217 // Duplicate selection so we can move range without breaking user selection. 8218 var fromStart = selectedRange.duplicate(); 8219 fromStart.moveToElementText(node); 8220 fromStart.setEndPoint('EndToStart', selectedRange); 8221 8222 var startOffset = fromStart.text.length; 8223 var endOffset = startOffset + selectedLength; 8224 8225 return { 8226 start: startOffset, 8227 end: endOffset 8228 }; 8229 } 8230 8231 /** 8232 * @param {DOMElement} node 8233 * @return {?object} 8234 */ 8235 function getModernOffsets(node) { 8236 var selection = window.getSelection(); 8237 8238 if (selection.rangeCount === 0) { 8239 return null; 8240 } 8241 8242 var anchorNode = selection.anchorNode; 8243 var anchorOffset = selection.anchorOffset; 8244 var focusNode = selection.focusNode; 8245 var focusOffset = selection.focusOffset; 8246 8247 var currentRange = selection.getRangeAt(0); 8248 var rangeLength = currentRange.toString().length; 8249 8250 var tempRange = currentRange.cloneRange(); 8251 tempRange.selectNodeContents(node); 8252 tempRange.setEnd(currentRange.startContainer, currentRange.startOffset); 8253 8254 var start = tempRange.toString().length; 8255 var end = start + rangeLength; 8256 8257 // Detect whether the selection is backward. 8258 var detectionRange = document.createRange(); 8259 detectionRange.setStart(anchorNode, anchorOffset); 8260 detectionRange.setEnd(focusNode, focusOffset); 8261 var isBackward = detectionRange.collapsed; 8262 detectionRange.detach(); 8263 8264 return { 8265 start: isBackward ? end : start, 8266 end: isBackward ? start : end 8267 }; 8268 } 8269 8270 /** 8271 * @param {DOMElement|DOMTextNode} node 8272 * @param {object} offsets 8273 */ 8274 function setIEOffsets(node, offsets) { 8275 var range = document.selection.createRange().duplicate(); 8276 var start, end; 8277 8278 if (typeof offsets.end === 'undefined') { 8279 start = offsets.start; 8280 end = start; 8281 } else if (offsets.start > offsets.end) { 8282 start = offsets.end; 8283 end = offsets.start; 8284 } else { 8285 start = offsets.start; 8286 end = offsets.end; 8287 } 8288 8289 range.moveToElementText(node); 8290 range.moveStart('character', start); 8291 range.setEndPoint('EndToStart', range); 8292 range.moveEnd('character', end - start); 8293 range.select(); 8294 } 8295 8296 /** 8297 * In modern non-IE browsers, we can support both forward and backward 8298 * selections. 8299 * 8300 * Note: IE10+ supports the Selection object, but it does not support 8301 * the `extend` method, which means that even in modern IE, it's not possible 8302 * to programatically create a backward selection. Thus, for all IE 8303 * versions, we use the old IE API to create our selections. 8304 * 8305 * @param {DOMElement|DOMTextNode} node 8306 * @param {object} offsets 8307 */ 8308 function setModernOffsets(node, offsets) { 8309 var selection = window.getSelection(); 8310 8311 var length = node[getTextContentAccessor()].length; 8312 var start = Math.min(offsets.start, length); 8313 var end = typeof offsets.end === 'undefined' ? 8314 start : Math.min(offsets.end, length); 8315 8316 // IE 11 uses modern selection, but doesn't support the extend method. 8317 // Flip backward selections, so we can set with a single range. 8318 if (!selection.extend && start > end) { 8319 var temp = end; 8320 end = start; 8321 start = temp; 8322 } 8323 8324 var startMarker = getNodeForCharacterOffset(node, start); 8325 var endMarker = getNodeForCharacterOffset(node, end); 8326 8327 if (startMarker && endMarker) { 8328 var range = document.createRange(); 8329 range.setStart(startMarker.node, startMarker.offset); 8330 selection.removeAllRanges(); 8331 8332 if (start > end) { 8333 selection.addRange(range); 8334 selection.extend(endMarker.node, endMarker.offset); 8335 } else { 8336 range.setEnd(endMarker.node, endMarker.offset); 8337 selection.addRange(range); 8338 } 8339 8340 range.detach(); 8341 } 8342 } 8343 8344 var ReactDOMSelection = { 8345 /** 8346 * @param {DOMElement} node 8347 */ 8348 getOffsets: function(node) { 8349 var getOffsets = document.selection ? getIEOffsets : getModernOffsets; 8350 return getOffsets(node); 8351 }, 8352 8353 /** 8354 * @param {DOMElement|DOMTextNode} node 8355 * @param {object} offsets 8356 */ 8357 setOffsets: function(node, offsets) { 8358 var setOffsets = document.selection ? setIEOffsets : setModernOffsets; 8359 setOffsets(node, offsets); 8360 } 8361 }; 8362 8363 module.exports = ReactDOMSelection; 8364 8365 },{"./getNodeForCharacterOffset":119,"./getTextContentAccessor":121}],46:[function(_dereq_,module,exports){ 8366 /** 8367 * Copyright 2013-2014 Facebook, Inc. 8368 * 8369 * Licensed under the Apache License, Version 2.0 (the "License"); 8370 * you may not use this file except in compliance with the License. 8371 * You may obtain a copy of the License at 8372 * 8373 * http://www.apache.org/licenses/LICENSE-2.0 8374 * 8375 * Unless required by applicable law or agreed to in writing, software 8376 * distributed under the License is distributed on an "AS IS" BASIS, 8377 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 8378 * See the License for the specific language governing permissions and 8379 * limitations under the License. 8380 * 8381 * @providesModule ReactDOMTextarea 8382 */ 8383 8384 "use strict"; 8385 8386 var AutoFocusMixin = _dereq_("./AutoFocusMixin"); 8387 var DOMPropertyOperations = _dereq_("./DOMPropertyOperations"); 8388 var LinkedValueUtils = _dereq_("./LinkedValueUtils"); 8389 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 8390 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 8391 var ReactDOM = _dereq_("./ReactDOM"); 8392 8393 var invariant = _dereq_("./invariant"); 8394 var merge = _dereq_("./merge"); 8395 8396 var warning = _dereq_("./warning"); 8397 8398 // Store a reference to the <textarea> `ReactDOMComponent`. 8399 var textarea = ReactDOM.textarea; 8400 8401 /** 8402 * Implements a <textarea> native component that allows setting `value`, and 8403 * `defaultValue`. This differs from the traditional DOM API because value is 8404 * usually set as PCDATA children. 8405 * 8406 * If `value` is not supplied (or null/undefined), user actions that affect the 8407 * value will trigger updates to the element. 8408 * 8409 * If `value` is supplied (and not null/undefined), the rendered element will 8410 * not trigger updates to the element. Instead, the `value` prop must change in 8411 * order for the rendered element to be updated. 8412 * 8413 * The rendered element will be initialized with an empty value, the prop 8414 * `defaultValue` if specified, or the children content (deprecated). 8415 */ 8416 var ReactDOMTextarea = ReactCompositeComponent.createClass({ 8417 displayName: 'ReactDOMTextarea', 8418 8419 mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], 8420 8421 getInitialState: function() { 8422 var defaultValue = this.props.defaultValue; 8423 // TODO (yungsters): Remove support for children content in <textarea>. 8424 var children = this.props.children; 8425 if (children != null) { 8426 if ("production" !== "development") { 8427 ("production" !== "development" ? warning( 8428 false, 8429 'Use the `defaultValue` or `value` props instead of setting ' + 8430 'children on <textarea>.' 8431 ) : null); 8432 } 8433 ("production" !== "development" ? invariant( 8434 defaultValue == null, 8435 'If you supply `defaultValue` on a <textarea>, do not pass children.' 8436 ) : invariant(defaultValue == null)); 8437 if (Array.isArray(children)) { 8438 ("production" !== "development" ? invariant( 8439 children.length <= 1, 8440 '<textarea> can only have at most one child.' 8441 ) : invariant(children.length <= 1)); 8442 children = children[0]; 8443 } 8444 8445 defaultValue = '' + children; 8446 } 8447 if (defaultValue == null) { 8448 defaultValue = ''; 8449 } 8450 var value = LinkedValueUtils.getValue(this); 8451 return { 8452 // We save the initial value so that `ReactDOMComponent` doesn't update 8453 // `textContent` (unnecessary since we update value). 8454 // The initial value can be a boolean or object so that's why it's 8455 // forced to be a string. 8456 initialValue: '' + (value != null ? value : defaultValue), 8457 value: defaultValue 8458 }; 8459 }, 8460 8461 shouldComponentUpdate: function() { 8462 // Defer any updates to this component during the `onChange` handler. 8463 return !this._isChanging; 8464 }, 8465 8466 render: function() { 8467 // Clone `this.props` so we don't mutate the input. 8468 var props = merge(this.props); 8469 var value = LinkedValueUtils.getValue(this); 8470 8471 ("production" !== "development" ? invariant( 8472 props.dangerouslySetInnerHTML == null, 8473 '`dangerouslySetInnerHTML` does not make sense on <textarea>.' 8474 ) : invariant(props.dangerouslySetInnerHTML == null)); 8475 8476 props.defaultValue = null; 8477 props.value = value != null ? value : this.state.value; 8478 props.onChange = this._handleChange; 8479 8480 // Always set children to the same thing. In IE9, the selection range will 8481 // get reset if `textContent` is mutated. 8482 return textarea(props, this.state.initialValue); 8483 }, 8484 8485 componentDidUpdate: function(prevProps, prevState, prevContext) { 8486 var value = LinkedValueUtils.getValue(this); 8487 if (value != null) { 8488 var rootNode = this.getDOMNode(); 8489 // Cast `value` to a string to ensure the value is set correctly. While 8490 // browsers typically do this as necessary, jsdom doesn't. 8491 DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); 8492 } 8493 }, 8494 8495 _handleChange: function(event) { 8496 var returnValue; 8497 var onChange = LinkedValueUtils.getOnChange(this); 8498 if (onChange) { 8499 this._isChanging = true; 8500 returnValue = onChange.call(this, event); 8501 this._isChanging = false; 8502 } 8503 this.setState({value: event.target.value}); 8504 return returnValue; 8505 } 8506 8507 }); 8508 8509 module.exports = ReactDOMTextarea; 8510 8511 },{"./AutoFocusMixin":1,"./DOMPropertyOperations":10,"./LinkedValueUtils":23,"./ReactBrowserComponentMixin":27,"./ReactCompositeComponent":33,"./ReactDOM":36,"./invariant":125,"./merge":134,"./warning":148}],47:[function(_dereq_,module,exports){ 8512 /** 8513 * Copyright 2013-2014 Facebook, Inc. 8514 * 8515 * Licensed under the Apache License, Version 2.0 (the "License"); 8516 * you may not use this file except in compliance with the License. 8517 * You may obtain a copy of the License at 8518 * 8519 * http://www.apache.org/licenses/LICENSE-2.0 8520 * 8521 * Unless required by applicable law or agreed to in writing, software 8522 * distributed under the License is distributed on an "AS IS" BASIS, 8523 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 8524 * See the License for the specific language governing permissions and 8525 * limitations under the License. 8526 * 8527 * @providesModule ReactDefaultBatchingStrategy 8528 */ 8529 8530 "use strict"; 8531 8532 var ReactUpdates = _dereq_("./ReactUpdates"); 8533 var Transaction = _dereq_("./Transaction"); 8534 8535 var emptyFunction = _dereq_("./emptyFunction"); 8536 var mixInto = _dereq_("./mixInto"); 8537 8538 var RESET_BATCHED_UPDATES = { 8539 initialize: emptyFunction, 8540 close: function() { 8541 ReactDefaultBatchingStrategy.isBatchingUpdates = false; 8542 } 8543 }; 8544 8545 var FLUSH_BATCHED_UPDATES = { 8546 initialize: emptyFunction, 8547 close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates) 8548 }; 8549 8550 var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES]; 8551 8552 function ReactDefaultBatchingStrategyTransaction() { 8553 this.reinitializeTransaction(); 8554 } 8555 8556 mixInto(ReactDefaultBatchingStrategyTransaction, Transaction.Mixin); 8557 mixInto(ReactDefaultBatchingStrategyTransaction, { 8558 getTransactionWrappers: function() { 8559 return TRANSACTION_WRAPPERS; 8560 } 8561 }); 8562 8563 var transaction = new ReactDefaultBatchingStrategyTransaction(); 8564 8565 var ReactDefaultBatchingStrategy = { 8566 isBatchingUpdates: false, 8567 8568 /** 8569 * Call the provided function in a context within which calls to `setState` 8570 * and friends are batched such that components aren't updated unnecessarily. 8571 */ 8572 batchedUpdates: function(callback, param) { 8573 var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; 8574 8575 ReactDefaultBatchingStrategy.isBatchingUpdates = true; 8576 8577 // The code is written this way to avoid extra allocations 8578 if (alreadyBatchingUpdates) { 8579 callback(param); 8580 } else { 8581 transaction.perform(callback, null, param); 8582 } 8583 } 8584 }; 8585 8586 module.exports = ReactDefaultBatchingStrategy; 8587 8588 },{"./ReactUpdates":81,"./Transaction":96,"./emptyFunction":109,"./mixInto":137}],48:[function(_dereq_,module,exports){ 8589 /** 8590 * Copyright 2013-2014 Facebook, Inc. 8591 * 8592 * Licensed under the Apache License, Version 2.0 (the "License"); 8593 * you may not use this file except in compliance with the License. 8594 * You may obtain a copy of the License at 8595 * 8596 * http://www.apache.org/licenses/LICENSE-2.0 8597 * 8598 * Unless required by applicable law or agreed to in writing, software 8599 * distributed under the License is distributed on an "AS IS" BASIS, 8600 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 8601 * See the License for the specific language governing permissions and 8602 * limitations under the License. 8603 * 8604 * @providesModule ReactDefaultInjection 8605 */ 8606 8607 "use strict"; 8608 8609 var ReactInjection = _dereq_("./ReactInjection"); 8610 8611 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 8612 8613 var DefaultDOMPropertyConfig = _dereq_("./DefaultDOMPropertyConfig"); 8614 8615 var ChangeEventPlugin = _dereq_("./ChangeEventPlugin"); 8616 var ClientReactRootIndex = _dereq_("./ClientReactRootIndex"); 8617 var CompositionEventPlugin = _dereq_("./CompositionEventPlugin"); 8618 var DefaultEventPluginOrder = _dereq_("./DefaultEventPluginOrder"); 8619 var EnterLeaveEventPlugin = _dereq_("./EnterLeaveEventPlugin"); 8620 var MobileSafariClickEventPlugin = _dereq_("./MobileSafariClickEventPlugin"); 8621 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 8622 var ReactComponentBrowserEnvironment = 8623 _dereq_("./ReactComponentBrowserEnvironment"); 8624 var ReactEventTopLevelCallback = _dereq_("./ReactEventTopLevelCallback"); 8625 var ReactDOM = _dereq_("./ReactDOM"); 8626 var ReactDOMButton = _dereq_("./ReactDOMButton"); 8627 var ReactDOMForm = _dereq_("./ReactDOMForm"); 8628 var ReactDOMImg = _dereq_("./ReactDOMImg"); 8629 var ReactDOMInput = _dereq_("./ReactDOMInput"); 8630 var ReactDOMOption = _dereq_("./ReactDOMOption"); 8631 var ReactDOMSelect = _dereq_("./ReactDOMSelect"); 8632 var ReactDOMTextarea = _dereq_("./ReactDOMTextarea"); 8633 var ReactInstanceHandles = _dereq_("./ReactInstanceHandles"); 8634 var ReactMount = _dereq_("./ReactMount"); 8635 var SelectEventPlugin = _dereq_("./SelectEventPlugin"); 8636 var ServerReactRootIndex = _dereq_("./ServerReactRootIndex"); 8637 var SimpleEventPlugin = _dereq_("./SimpleEventPlugin"); 8638 8639 var ReactDefaultBatchingStrategy = _dereq_("./ReactDefaultBatchingStrategy"); 8640 8641 var createFullPageComponent = _dereq_("./createFullPageComponent"); 8642 8643 function inject() { 8644 ReactInjection.EventEmitter.injectTopLevelCallbackCreator( 8645 ReactEventTopLevelCallback 8646 ); 8647 8648 /** 8649 * Inject modules for resolving DOM hierarchy and plugin ordering. 8650 */ 8651 ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder); 8652 ReactInjection.EventPluginHub.injectInstanceHandle(ReactInstanceHandles); 8653 ReactInjection.EventPluginHub.injectMount(ReactMount); 8654 8655 /** 8656 * Some important event plugins included by default (without having to require 8657 * them). 8658 */ 8659 ReactInjection.EventPluginHub.injectEventPluginsByName({ 8660 SimpleEventPlugin: SimpleEventPlugin, 8661 EnterLeaveEventPlugin: EnterLeaveEventPlugin, 8662 ChangeEventPlugin: ChangeEventPlugin, 8663 CompositionEventPlugin: CompositionEventPlugin, 8664 MobileSafariClickEventPlugin: MobileSafariClickEventPlugin, 8665 SelectEventPlugin: SelectEventPlugin 8666 }); 8667 8668 ReactInjection.DOM.injectComponentClasses({ 8669 button: ReactDOMButton, 8670 form: ReactDOMForm, 8671 img: ReactDOMImg, 8672 input: ReactDOMInput, 8673 option: ReactDOMOption, 8674 select: ReactDOMSelect, 8675 textarea: ReactDOMTextarea, 8676 8677 html: createFullPageComponent(ReactDOM.html), 8678 head: createFullPageComponent(ReactDOM.head), 8679 title: createFullPageComponent(ReactDOM.title), 8680 body: createFullPageComponent(ReactDOM.body) 8681 }); 8682 8683 8684 // This needs to happen after createFullPageComponent() otherwise the mixin 8685 // gets double injected. 8686 ReactInjection.CompositeComponent.injectMixin(ReactBrowserComponentMixin); 8687 8688 ReactInjection.DOMProperty.injectDOMPropertyConfig(DefaultDOMPropertyConfig); 8689 8690 ReactInjection.Updates.injectBatchingStrategy( 8691 ReactDefaultBatchingStrategy 8692 ); 8693 8694 ReactInjection.RootIndex.injectCreateReactRootIndex( 8695 ExecutionEnvironment.canUseDOM ? 8696 ClientReactRootIndex.createReactRootIndex : 8697 ServerReactRootIndex.createReactRootIndex 8698 ); 8699 8700 ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment); 8701 8702 if ("production" !== "development") { 8703 var url = (ExecutionEnvironment.canUseDOM && window.location.href) || ''; 8704 if ((/[?&]react_perf\b/).test(url)) { 8705 var ReactDefaultPerf = _dereq_("./ReactDefaultPerf"); 8706 ReactDefaultPerf.start(); 8707 } 8708 } 8709 } 8710 8711 module.exports = { 8712 inject: inject 8713 }; 8714 8715 },{"./ChangeEventPlugin":5,"./ClientReactRootIndex":6,"./CompositionEventPlugin":7,"./DefaultDOMPropertyConfig":12,"./DefaultEventPluginOrder":13,"./EnterLeaveEventPlugin":14,"./ExecutionEnvironment":21,"./MobileSafariClickEventPlugin":24,"./ReactBrowserComponentMixin":27,"./ReactComponentBrowserEnvironment":32,"./ReactDOM":36,"./ReactDOMButton":37,"./ReactDOMForm":39,"./ReactDOMImg":41,"./ReactDOMInput":42,"./ReactDOMOption":43,"./ReactDOMSelect":44,"./ReactDOMTextarea":46,"./ReactDefaultBatchingStrategy":47,"./ReactDefaultPerf":49,"./ReactEventTopLevelCallback":54,"./ReactInjection":55,"./ReactInstanceHandles":57,"./ReactMount":60,"./SelectEventPlugin":83,"./ServerReactRootIndex":84,"./SimpleEventPlugin":85,"./createFullPageComponent":104}],49:[function(_dereq_,module,exports){ 8716 /** 8717 * Copyright 2013-2014 Facebook, Inc. 8718 * 8719 * Licensed under the Apache License, Version 2.0 (the "License"); 8720 * you may not use this file except in compliance with the License. 8721 * You may obtain a copy of the License at 8722 * 8723 * http://www.apache.org/licenses/LICENSE-2.0 8724 * 8725 * Unless required by applicable law or agreed to in writing, software 8726 * distributed under the License is distributed on an "AS IS" BASIS, 8727 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 8728 * See the License for the specific language governing permissions and 8729 * limitations under the License. 8730 * 8731 * @providesModule ReactDefaultPerf 8732 * @typechecks static-only 8733 */ 8734 8735 "use strict"; 8736 8737 var DOMProperty = _dereq_("./DOMProperty"); 8738 var ReactDefaultPerfAnalysis = _dereq_("./ReactDefaultPerfAnalysis"); 8739 var ReactMount = _dereq_("./ReactMount"); 8740 var ReactPerf = _dereq_("./ReactPerf"); 8741 8742 var performanceNow = _dereq_("./performanceNow"); 8743 8744 function roundFloat(val) { 8745 return Math.floor(val * 100) / 100; 8746 } 8747 8748 var ReactDefaultPerf = { 8749 _allMeasurements: [], // last item in the list is the current one 8750 _injected: false, 8751 8752 start: function() { 8753 if (!ReactDefaultPerf._injected) { 8754 ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure); 8755 } 8756 8757 ReactDefaultPerf._allMeasurements.length = 0; 8758 ReactPerf.enableMeasure = true; 8759 }, 8760 8761 stop: function() { 8762 ReactPerf.enableMeasure = false; 8763 }, 8764 8765 getLastMeasurements: function() { 8766 return ReactDefaultPerf._allMeasurements; 8767 }, 8768 8769 printExclusive: function(measurements) { 8770 measurements = measurements || ReactDefaultPerf._allMeasurements; 8771 var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements); 8772 console.table(summary.map(function(item) { 8773 return { 8774 'Component class name': item.componentName, 8775 'Total inclusive time (ms)': roundFloat(item.inclusive), 8776 'Total exclusive time (ms)': roundFloat(item.exclusive), 8777 'Exclusive time per instance (ms)': roundFloat(item.exclusive / item.count), 8778 'Instances': item.count 8779 }; 8780 })); 8781 console.log( 8782 'Total time:', 8783 ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' 8784 ); 8785 }, 8786 8787 printInclusive: function(measurements) { 8788 measurements = measurements || ReactDefaultPerf._allMeasurements; 8789 var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements); 8790 console.table(summary.map(function(item) { 8791 return { 8792 'Owner > component': item.componentName, 8793 'Inclusive time (ms)': roundFloat(item.time), 8794 'Instances': item.count 8795 }; 8796 })); 8797 console.log( 8798 'Total time:', 8799 ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' 8800 ); 8801 }, 8802 8803 printWasted: function(measurements) { 8804 measurements = measurements || ReactDefaultPerf._allMeasurements; 8805 var summary = ReactDefaultPerfAnalysis.getInclusiveSummary( 8806 measurements, 8807 true 8808 ); 8809 console.table(summary.map(function(item) { 8810 return { 8811 'Owner > component': item.componentName, 8812 'Wasted time (ms)': item.time, 8813 'Instances': item.count 8814 }; 8815 })); 8816 console.log( 8817 'Total time:', 8818 ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' 8819 ); 8820 }, 8821 8822 printDOM: function(measurements) { 8823 measurements = measurements || ReactDefaultPerf._allMeasurements; 8824 var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements); 8825 console.table(summary.map(function(item) { 8826 var result = {}; 8827 result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id; 8828 result['type'] = item.type; 8829 result['args'] = JSON.stringify(item.args); 8830 return result; 8831 })); 8832 console.log( 8833 'Total time:', 8834 ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' 8835 ); 8836 }, 8837 8838 _recordWrite: function(id, fnName, totalTime, args) { 8839 // TODO: totalTime isn't that useful since it doesn't count paints/reflows 8840 var writes = 8841 ReactDefaultPerf 8842 ._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1] 8843 .writes; 8844 writes[id] = writes[id] || []; 8845 writes[id].push({ 8846 type: fnName, 8847 time: totalTime, 8848 args: args 8849 }); 8850 }, 8851 8852 measure: function(moduleName, fnName, func) { 8853 return function() {var args=Array.prototype.slice.call(arguments,0); 8854 var totalTime; 8855 var rv; 8856 var start; 8857 8858 if (fnName === '_renderNewRootComponent' || 8859 fnName === 'flushBatchedUpdates') { 8860 // A "measurement" is a set of metrics recorded for each flush. We want 8861 // to group the metrics for a given flush together so we can look at the 8862 // components that rendered and the DOM operations that actually 8863 // happened to determine the amount of "wasted work" performed. 8864 ReactDefaultPerf._allMeasurements.push({ 8865 exclusive: {}, 8866 inclusive: {}, 8867 counts: {}, 8868 writes: {}, 8869 displayNames: {}, 8870 totalTime: 0 8871 }); 8872 start = performanceNow(); 8873 rv = func.apply(this, args); 8874 ReactDefaultPerf._allMeasurements[ 8875 ReactDefaultPerf._allMeasurements.length - 1 8876 ].totalTime = performanceNow() - start; 8877 return rv; 8878 } else if (moduleName === 'ReactDOMIDOperations' || 8879 moduleName === 'ReactComponentBrowserEnvironment') { 8880 start = performanceNow(); 8881 rv = func.apply(this, args); 8882 totalTime = performanceNow() - start; 8883 8884 if (fnName === 'mountImageIntoNode') { 8885 var mountID = ReactMount.getID(args[1]); 8886 ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]); 8887 } else if (fnName === 'dangerouslyProcessChildrenUpdates') { 8888 // special format 8889 args[0].forEach(function(update) { 8890 var writeArgs = {}; 8891 if (update.fromIndex !== null) { 8892 writeArgs.fromIndex = update.fromIndex; 8893 } 8894 if (update.toIndex !== null) { 8895 writeArgs.toIndex = update.toIndex; 8896 } 8897 if (update.textContent !== null) { 8898 writeArgs.textContent = update.textContent; 8899 } 8900 if (update.markupIndex !== null) { 8901 writeArgs.markup = args[1][update.markupIndex]; 8902 } 8903 ReactDefaultPerf._recordWrite( 8904 update.parentID, 8905 update.type, 8906 totalTime, 8907 writeArgs 8908 ); 8909 }); 8910 } else { 8911 // basic format 8912 ReactDefaultPerf._recordWrite( 8913 args[0], 8914 fnName, 8915 totalTime, 8916 Array.prototype.slice.call(args, 1) 8917 ); 8918 } 8919 return rv; 8920 } else if (moduleName === 'ReactCompositeComponent' && ( 8921 fnName === 'mountComponent' || 8922 fnName === 'updateComponent' || // TODO: receiveComponent()? 8923 fnName === '_renderValidatedComponent')) { 8924 8925 var rootNodeID = fnName === 'mountComponent' ? 8926 args[0] : 8927 this._rootNodeID; 8928 var isRender = fnName === '_renderValidatedComponent'; 8929 var entry = ReactDefaultPerf._allMeasurements[ 8930 ReactDefaultPerf._allMeasurements.length - 1 8931 ]; 8932 8933 if (isRender) { 8934 entry.counts[rootNodeID] = entry.counts[rootNodeID] || 0; 8935 entry.counts[rootNodeID] += 1; 8936 } 8937 8938 start = performanceNow(); 8939 rv = func.apply(this, args); 8940 totalTime = performanceNow() - start; 8941 8942 var typeOfLog = isRender ? entry.exclusive : entry.inclusive; 8943 typeOfLog[rootNodeID] = typeOfLog[rootNodeID] || 0; 8944 typeOfLog[rootNodeID] += totalTime; 8945 8946 entry.displayNames[rootNodeID] = { 8947 current: this.constructor.displayName, 8948 owner: this._owner ? this._owner.constructor.displayName : '<root>' 8949 }; 8950 8951 return rv; 8952 } else { 8953 return func.apply(this, args); 8954 } 8955 }; 8956 } 8957 }; 8958 8959 module.exports = ReactDefaultPerf; 8960 8961 },{"./DOMProperty":9,"./ReactDefaultPerfAnalysis":50,"./ReactMount":60,"./ReactPerf":65,"./performanceNow":142}],50:[function(_dereq_,module,exports){ 8962 /** 8963 * Copyright 2013-2014 Facebook, Inc. 8964 * 8965 * Licensed under the Apache License, Version 2.0 (the "License"); 8966 * you may not use this file except in compliance with the License. 8967 * You may obtain a copy of the License at 8968 * 8969 * http://www.apache.org/licenses/LICENSE-2.0 8970 * 8971 * Unless required by applicable law or agreed to in writing, software 8972 * distributed under the License is distributed on an "AS IS" BASIS, 8973 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 8974 * See the License for the specific language governing permissions and 8975 * limitations under the License. 8976 * 8977 * @providesModule ReactDefaultPerfAnalysis 8978 */ 8979 8980 var merge = _dereq_("./merge"); 8981 8982 // Don't try to save users less than 1.2ms (a number I made up) 8983 var DONT_CARE_THRESHOLD = 1.2; 8984 var DOM_OPERATION_TYPES = { 8985 'mountImageIntoNode': 'set innerHTML', 8986 INSERT_MARKUP: 'set innerHTML', 8987 MOVE_EXISTING: 'move', 8988 REMOVE_NODE: 'remove', 8989 TEXT_CONTENT: 'set textContent', 8990 'updatePropertyByID': 'update attribute', 8991 'deletePropertyByID': 'delete attribute', 8992 'updateStylesByID': 'update styles', 8993 'updateInnerHTMLByID': 'set innerHTML', 8994 'dangerouslyReplaceNodeWithMarkupByID': 'replace' 8995 }; 8996 8997 function getTotalTime(measurements) { 8998 // TODO: return number of DOM ops? could be misleading. 8999 // TODO: measure dropped frames after reconcile? 9000 // TODO: log total time of each reconcile and the top-level component 9001 // class that triggered it. 9002 var totalTime = 0; 9003 for (var i = 0; i < measurements.length; i++) { 9004 var measurement = measurements[i]; 9005 totalTime += measurement.totalTime; 9006 } 9007 return totalTime; 9008 } 9009 9010 function getDOMSummary(measurements) { 9011 var items = []; 9012 for (var i = 0; i < measurements.length; i++) { 9013 var measurement = measurements[i]; 9014 var id; 9015 9016 for (id in measurement.writes) { 9017 measurement.writes[id].forEach(function(write) { 9018 items.push({ 9019 id: id, 9020 type: DOM_OPERATION_TYPES[write.type] || write.type, 9021 args: write.args 9022 }); 9023 }); 9024 } 9025 } 9026 return items; 9027 } 9028 9029 function getExclusiveSummary(measurements) { 9030 var candidates = {}; 9031 var displayName; 9032 9033 for (var i = 0; i < measurements.length; i++) { 9034 var measurement = measurements[i]; 9035 var allIDs = merge(measurement.exclusive, measurement.inclusive); 9036 9037 for (var id in allIDs) { 9038 displayName = measurement.displayNames[id].current; 9039 9040 candidates[displayName] = candidates[displayName] || { 9041 componentName: displayName, 9042 inclusive: 0, 9043 exclusive: 0, 9044 count: 0 9045 }; 9046 if (measurement.exclusive[id]) { 9047 candidates[displayName].exclusive += measurement.exclusive[id]; 9048 } 9049 if (measurement.inclusive[id]) { 9050 candidates[displayName].inclusive += measurement.inclusive[id]; 9051 } 9052 if (measurement.counts[id]) { 9053 candidates[displayName].count += measurement.counts[id]; 9054 } 9055 } 9056 } 9057 9058 // Now make a sorted array with the results. 9059 var arr = []; 9060 for (displayName in candidates) { 9061 if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) { 9062 arr.push(candidates[displayName]); 9063 } 9064 } 9065 9066 arr.sort(function(a, b) { 9067 return b.exclusive - a.exclusive; 9068 }); 9069 9070 return arr; 9071 } 9072 9073 function getInclusiveSummary(measurements, onlyClean) { 9074 var candidates = {}; 9075 var inclusiveKey; 9076 9077 for (var i = 0; i < measurements.length; i++) { 9078 var measurement = measurements[i]; 9079 var allIDs = merge(measurement.exclusive, measurement.inclusive); 9080 var cleanComponents; 9081 9082 if (onlyClean) { 9083 cleanComponents = getUnchangedComponents(measurement); 9084 } 9085 9086 for (var id in allIDs) { 9087 if (onlyClean && !cleanComponents[id]) { 9088 continue; 9089 } 9090 9091 var displayName = measurement.displayNames[id]; 9092 9093 // Inclusive time is not useful for many components without knowing where 9094 // they are instantiated. So we aggregate inclusive time with both the 9095 // owner and current displayName as the key. 9096 inclusiveKey = displayName.owner + ' > ' + displayName.current; 9097 9098 candidates[inclusiveKey] = candidates[inclusiveKey] || { 9099 componentName: inclusiveKey, 9100 time: 0, 9101 count: 0 9102 }; 9103 9104 if (measurement.inclusive[id]) { 9105 candidates[inclusiveKey].time += measurement.inclusive[id]; 9106 } 9107 if (measurement.counts[id]) { 9108 candidates[inclusiveKey].count += measurement.counts[id]; 9109 } 9110 } 9111 } 9112 9113 // Now make a sorted array with the results. 9114 var arr = []; 9115 for (inclusiveKey in candidates) { 9116 if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) { 9117 arr.push(candidates[inclusiveKey]); 9118 } 9119 } 9120 9121 arr.sort(function(a, b) { 9122 return b.time - a.time; 9123 }); 9124 9125 return arr; 9126 } 9127 9128 function getUnchangedComponents(measurement) { 9129 // For a given reconcile, look at which components did not actually 9130 // render anything to the DOM and return a mapping of their ID to 9131 // the amount of time it took to render the entire subtree. 9132 var cleanComponents = {}; 9133 var dirtyLeafIDs = Object.keys(measurement.writes); 9134 var allIDs = merge(measurement.exclusive, measurement.inclusive); 9135 9136 for (var id in allIDs) { 9137 var isDirty = false; 9138 // For each component that rendered, see if a component that triggerd 9139 // a DOM op is in its subtree. 9140 for (var i = 0; i < dirtyLeafIDs.length; i++) { 9141 if (dirtyLeafIDs[i].indexOf(id) === 0) { 9142 isDirty = true; 9143 break; 9144 } 9145 } 9146 if (!isDirty && measurement.counts[id] > 0) { 9147 cleanComponents[id] = true; 9148 } 9149 } 9150 return cleanComponents; 9151 } 9152 9153 var ReactDefaultPerfAnalysis = { 9154 getExclusiveSummary: getExclusiveSummary, 9155 getInclusiveSummary: getInclusiveSummary, 9156 getDOMSummary: getDOMSummary, 9157 getTotalTime: getTotalTime 9158 }; 9159 9160 module.exports = ReactDefaultPerfAnalysis; 9161 9162 },{"./merge":134}],51:[function(_dereq_,module,exports){ 9163 /** 9164 * Copyright 2013-2014 Facebook, Inc. 9165 * 9166 * Licensed under the Apache License, Version 2.0 (the "License"); 9167 * you may not use this file except in compliance with the License. 9168 * You may obtain a copy of the License at 9169 * 9170 * http://www.apache.org/licenses/LICENSE-2.0 9171 * 9172 * Unless required by applicable law or agreed to in writing, software 9173 * distributed under the License is distributed on an "AS IS" BASIS, 9174 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9175 * See the License for the specific language governing permissions and 9176 * limitations under the License. 9177 * 9178 * @providesModule ReactErrorUtils 9179 * @typechecks 9180 */ 9181 9182 "use strict"; 9183 9184 var ReactErrorUtils = { 9185 /** 9186 * Creates a guarded version of a function. This is supposed to make debugging 9187 * of event handlers easier. To aid debugging with the browser's debugger, 9188 * this currently simply returns the original function. 9189 * 9190 * @param {function} func Function to be executed 9191 * @param {string} name The name of the guard 9192 * @return {function} 9193 */ 9194 guard: function(func, name) { 9195 return func; 9196 } 9197 }; 9198 9199 module.exports = ReactErrorUtils; 9200 9201 },{}],52:[function(_dereq_,module,exports){ 9202 /** 9203 * Copyright 2013-2014 Facebook, Inc. 9204 * 9205 * Licensed under the Apache License, Version 2.0 (the "License"); 9206 * you may not use this file except in compliance with the License. 9207 * You may obtain a copy of the License at 9208 * 9209 * http://www.apache.org/licenses/LICENSE-2.0 9210 * 9211 * Unless required by applicable law or agreed to in writing, software 9212 * distributed under the License is distributed on an "AS IS" BASIS, 9213 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9214 * See the License for the specific language governing permissions and 9215 * limitations under the License. 9216 * 9217 * @providesModule ReactEventEmitter 9218 * @typechecks static-only 9219 */ 9220 9221 "use strict"; 9222 9223 var EventConstants = _dereq_("./EventConstants"); 9224 var EventListener = _dereq_("./EventListener"); 9225 var EventPluginHub = _dereq_("./EventPluginHub"); 9226 var EventPluginRegistry = _dereq_("./EventPluginRegistry"); 9227 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 9228 var ReactEventEmitterMixin = _dereq_("./ReactEventEmitterMixin"); 9229 var ViewportMetrics = _dereq_("./ViewportMetrics"); 9230 9231 var invariant = _dereq_("./invariant"); 9232 var isEventSupported = _dereq_("./isEventSupported"); 9233 var merge = _dereq_("./merge"); 9234 9235 /** 9236 * Summary of `ReactEventEmitter` event handling: 9237 * 9238 * - Top-level delegation is used to trap native browser events. We normalize 9239 * and de-duplicate events to account for browser quirks. 9240 * 9241 * - Forward these native events (with the associated top-level type used to 9242 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want 9243 * to extract any synthetic events. 9244 * 9245 * - The `EventPluginHub` will then process each event by annotating them with 9246 * "dispatches", a sequence of listeners and IDs that care about that event. 9247 * 9248 * - The `EventPluginHub` then dispatches the events. 9249 * 9250 * Overview of React and the event system: 9251 * 9252 * . 9253 * +------------+ . 9254 * | DOM | . 9255 * +------------+ . +-----------+ 9256 * + . +--------+|SimpleEvent| 9257 * | . | |Plugin | 9258 * +-----|------+ . v +-----------+ 9259 * | | | . +--------------+ +------------+ 9260 * | +-----------.--->|EventPluginHub| | Event | 9261 * | | . | | +-----------+ | Propagators| 9262 * | ReactEvent | . | | |TapEvent | |------------| 9263 * | Emitter | . | |<---+|Plugin | |other plugin| 9264 * | | . | | +-----------+ | utilities | 9265 * | +-----------.--->| | +------------+ 9266 * | | | . +--------------+ 9267 * +-----|------+ . ^ +-----------+ 9268 * | . | |Enter/Leave| 9269 * + . +-------+|Plugin | 9270 * +-------------+ . +-----------+ 9271 * | application | . 9272 * |-------------| . 9273 * | | . 9274 * | | . 9275 * +-------------+ . 9276 * . 9277 * React Core . General Purpose Event Plugin System 9278 */ 9279 9280 var alreadyListeningTo = {}; 9281 var isMonitoringScrollValue = false; 9282 var reactTopListenersCounter = 0; 9283 9284 // For events like 'submit' which don't consistently bubble (which we trap at a 9285 // lower node than `document`), binding at `document` would cause duplicate 9286 // events so we don't include them here 9287 var topEventMapping = { 9288 topBlur: 'blur', 9289 topChange: 'change', 9290 topClick: 'click', 9291 topCompositionEnd: 'compositionend', 9292 topCompositionStart: 'compositionstart', 9293 topCompositionUpdate: 'compositionupdate', 9294 topContextMenu: 'contextmenu', 9295 topCopy: 'copy', 9296 topCut: 'cut', 9297 topDoubleClick: 'dblclick', 9298 topDrag: 'drag', 9299 topDragEnd: 'dragend', 9300 topDragEnter: 'dragenter', 9301 topDragExit: 'dragexit', 9302 topDragLeave: 'dragleave', 9303 topDragOver: 'dragover', 9304 topDragStart: 'dragstart', 9305 topDrop: 'drop', 9306 topFocus: 'focus', 9307 topInput: 'input', 9308 topKeyDown: 'keydown', 9309 topKeyPress: 'keypress', 9310 topKeyUp: 'keyup', 9311 topMouseDown: 'mousedown', 9312 topMouseMove: 'mousemove', 9313 topMouseOut: 'mouseout', 9314 topMouseOver: 'mouseover', 9315 topMouseUp: 'mouseup', 9316 topPaste: 'paste', 9317 topScroll: 'scroll', 9318 topSelectionChange: 'selectionchange', 9319 topTouchCancel: 'touchcancel', 9320 topTouchEnd: 'touchend', 9321 topTouchMove: 'touchmove', 9322 topTouchStart: 'touchstart', 9323 topWheel: 'wheel' 9324 }; 9325 9326 /** 9327 * To ensure no conflicts with other potential React instances on the page 9328 */ 9329 var topListenersIDKey = "_reactListenersID" + String(Math.random()).slice(2); 9330 9331 function getListeningForDocument(mountAt) { 9332 if (mountAt[topListenersIDKey] == null) { 9333 mountAt[topListenersIDKey] = reactTopListenersCounter++; 9334 alreadyListeningTo[mountAt[topListenersIDKey]] = {}; 9335 } 9336 return alreadyListeningTo[mountAt[topListenersIDKey]]; 9337 } 9338 9339 /** 9340 * Traps top-level events by using event bubbling. 9341 * 9342 * @param {string} topLevelType Record from `EventConstants`. 9343 * @param {string} handlerBaseName Event name (e.g. "click"). 9344 * @param {DOMEventTarget} element Element on which to attach listener. 9345 * @internal 9346 */ 9347 function trapBubbledEvent(topLevelType, handlerBaseName, element) { 9348 EventListener.listen( 9349 element, 9350 handlerBaseName, 9351 ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback( 9352 topLevelType 9353 ) 9354 ); 9355 } 9356 9357 /** 9358 * Traps a top-level event by using event capturing. 9359 * 9360 * @param {string} topLevelType Record from `EventConstants`. 9361 * @param {string} handlerBaseName Event name (e.g. "click"). 9362 * @param {DOMEventTarget} element Element on which to attach listener. 9363 * @internal 9364 */ 9365 function trapCapturedEvent(topLevelType, handlerBaseName, element) { 9366 EventListener.capture( 9367 element, 9368 handlerBaseName, 9369 ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback( 9370 topLevelType 9371 ) 9372 ); 9373 } 9374 9375 /** 9376 * `ReactEventEmitter` is used to attach top-level event listeners. For example: 9377 * 9378 * ReactEventEmitter.putListener('myID', 'onClick', myFunction); 9379 * 9380 * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. 9381 * 9382 * @internal 9383 */ 9384 var ReactEventEmitter = merge(ReactEventEmitterMixin, { 9385 9386 /** 9387 * React references `ReactEventTopLevelCallback` using this property in order 9388 * to allow dependency injection. 9389 */ 9390 TopLevelCallbackCreator: null, 9391 9392 injection: { 9393 /** 9394 * @param {function} TopLevelCallbackCreator 9395 */ 9396 injectTopLevelCallbackCreator: function(TopLevelCallbackCreator) { 9397 ReactEventEmitter.TopLevelCallbackCreator = TopLevelCallbackCreator; 9398 } 9399 }, 9400 9401 /** 9402 * Sets whether or not any created callbacks should be enabled. 9403 * 9404 * @param {boolean} enabled True if callbacks should be enabled. 9405 */ 9406 setEnabled: function(enabled) { 9407 ("production" !== "development" ? invariant( 9408 ExecutionEnvironment.canUseDOM, 9409 'setEnabled(...): Cannot toggle event listening in a Worker thread. ' + 9410 'This is likely a bug in the framework. Please report immediately.' 9411 ) : invariant(ExecutionEnvironment.canUseDOM)); 9412 if (ReactEventEmitter.TopLevelCallbackCreator) { 9413 ReactEventEmitter.TopLevelCallbackCreator.setEnabled(enabled); 9414 } 9415 }, 9416 9417 /** 9418 * @return {boolean} True if callbacks are enabled. 9419 */ 9420 isEnabled: function() { 9421 return !!( 9422 ReactEventEmitter.TopLevelCallbackCreator && 9423 ReactEventEmitter.TopLevelCallbackCreator.isEnabled() 9424 ); 9425 }, 9426 9427 /** 9428 * We listen for bubbled touch events on the document object. 9429 * 9430 * Firefox v8.01 (and possibly others) exhibited strange behavior when 9431 * mounting `onmousemove` events at some node that was not the document 9432 * element. The symptoms were that if your mouse is not moving over something 9433 * contained within that mount point (for example on the background) the 9434 * top-level listeners for `onmousemove` won't be called. However, if you 9435 * register the `mousemove` on the document object, then it will of course 9436 * catch all `mousemove`s. This along with iOS quirks, justifies restricting 9437 * top-level listeners to the document object only, at least for these 9438 * movement types of events and possibly all events. 9439 * 9440 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html 9441 * 9442 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but 9443 * they bubble to document. 9444 * 9445 * @param {string} registrationName Name of listener (e.g. `onClick`). 9446 * @param {DOMDocument} contentDocument Document which owns the container 9447 */ 9448 listenTo: function(registrationName, contentDocument) { 9449 var mountAt = contentDocument; 9450 var isListening = getListeningForDocument(mountAt); 9451 var dependencies = EventPluginRegistry. 9452 registrationNameDependencies[registrationName]; 9453 9454 var topLevelTypes = EventConstants.topLevelTypes; 9455 for (var i = 0, l = dependencies.length; i < l; i++) { 9456 var dependency = dependencies[i]; 9457 if (!isListening[dependency]) { 9458 var topLevelType = topLevelTypes[dependency]; 9459 9460 if (topLevelType === topLevelTypes.topWheel) { 9461 if (isEventSupported('wheel')) { 9462 trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt); 9463 } else if (isEventSupported('mousewheel')) { 9464 trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt); 9465 } else { 9466 // Firefox needs to capture a different mouse scroll event. 9467 // @see http://www.quirksmode.org/dom/events/tests/scroll.html 9468 trapBubbledEvent( 9469 topLevelTypes.topWheel, 9470 'DOMMouseScroll', 9471 mountAt); 9472 } 9473 } else if (topLevelType === topLevelTypes.topScroll) { 9474 9475 if (isEventSupported('scroll', true)) { 9476 trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt); 9477 } else { 9478 trapBubbledEvent(topLevelTypes.topScroll, 'scroll', window); 9479 } 9480 } else if (topLevelType === topLevelTypes.topFocus || 9481 topLevelType === topLevelTypes.topBlur) { 9482 9483 if (isEventSupported('focus', true)) { 9484 trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt); 9485 trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt); 9486 } else if (isEventSupported('focusin')) { 9487 // IE has `focusin` and `focusout` events which bubble. 9488 // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html 9489 trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt); 9490 trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt); 9491 } 9492 9493 // to make sure blur and focus event listeners are only attached once 9494 isListening[topLevelTypes.topBlur] = true; 9495 isListening[topLevelTypes.topFocus] = true; 9496 } else if (topEventMapping[dependency]) { 9497 trapBubbledEvent(topLevelType, topEventMapping[dependency], mountAt); 9498 } 9499 9500 isListening[dependency] = true; 9501 } 9502 } 9503 }, 9504 9505 /** 9506 * Listens to window scroll and resize events. We cache scroll values so that 9507 * application code can access them without triggering reflows. 9508 * 9509 * NOTE: Scroll events do not bubble. 9510 * 9511 * @see http://www.quirksmode.org/dom/events/scroll.html 9512 */ 9513 ensureScrollValueMonitoring: function(){ 9514 if (!isMonitoringScrollValue) { 9515 var refresh = ViewportMetrics.refreshScrollValues; 9516 EventListener.listen(window, 'scroll', refresh); 9517 EventListener.listen(window, 'resize', refresh); 9518 isMonitoringScrollValue = true; 9519 } 9520 }, 9521 9522 eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs, 9523 9524 registrationNameModules: EventPluginHub.registrationNameModules, 9525 9526 putListener: EventPluginHub.putListener, 9527 9528 getListener: EventPluginHub.getListener, 9529 9530 deleteListener: EventPluginHub.deleteListener, 9531 9532 deleteAllListeners: EventPluginHub.deleteAllListeners, 9533 9534 trapBubbledEvent: trapBubbledEvent, 9535 9536 trapCapturedEvent: trapCapturedEvent 9537 9538 }); 9539 9540 module.exports = ReactEventEmitter; 9541 9542 },{"./EventConstants":15,"./EventListener":16,"./EventPluginHub":17,"./EventPluginRegistry":18,"./ExecutionEnvironment":21,"./ReactEventEmitterMixin":53,"./ViewportMetrics":97,"./invariant":125,"./isEventSupported":126,"./merge":134}],53:[function(_dereq_,module,exports){ 9543 /** 9544 * Copyright 2013-2014 Facebook, Inc. 9545 * 9546 * Licensed under the Apache License, Version 2.0 (the "License"); 9547 * you may not use this file except in compliance with the License. 9548 * You may obtain a copy of the License at 9549 * 9550 * http://www.apache.org/licenses/LICENSE-2.0 9551 * 9552 * Unless required by applicable law or agreed to in writing, software 9553 * distributed under the License is distributed on an "AS IS" BASIS, 9554 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9555 * See the License for the specific language governing permissions and 9556 * limitations under the License. 9557 * 9558 * @providesModule ReactEventEmitterMixin 9559 */ 9560 9561 "use strict"; 9562 9563 var EventPluginHub = _dereq_("./EventPluginHub"); 9564 var ReactUpdates = _dereq_("./ReactUpdates"); 9565 9566 function runEventQueueInBatch(events) { 9567 EventPluginHub.enqueueEvents(events); 9568 EventPluginHub.processEventQueue(); 9569 } 9570 9571 var ReactEventEmitterMixin = { 9572 9573 /** 9574 * Streams a fired top-level event to `EventPluginHub` where plugins have the 9575 * opportunity to create `ReactEvent`s to be dispatched. 9576 * 9577 * @param {string} topLevelType Record from `EventConstants`. 9578 * @param {object} topLevelTarget The listening component root node. 9579 * @param {string} topLevelTargetID ID of `topLevelTarget`. 9580 * @param {object} nativeEvent Native environment event. 9581 */ 9582 handleTopLevel: function( 9583 topLevelType, 9584 topLevelTarget, 9585 topLevelTargetID, 9586 nativeEvent) { 9587 var events = EventPluginHub.extractEvents( 9588 topLevelType, 9589 topLevelTarget, 9590 topLevelTargetID, 9591 nativeEvent 9592 ); 9593 9594 // Event queue being processed in the same cycle allows `preventDefault`. 9595 ReactUpdates.batchedUpdates(runEventQueueInBatch, events); 9596 } 9597 }; 9598 9599 module.exports = ReactEventEmitterMixin; 9600 9601 },{"./EventPluginHub":17,"./ReactUpdates":81}],54:[function(_dereq_,module,exports){ 9602 /** 9603 * Copyright 2013-2014 Facebook, Inc. 9604 * 9605 * Licensed under the Apache License, Version 2.0 (the "License"); 9606 * you may not use this file except in compliance with the License. 9607 * You may obtain a copy of the License at 9608 * 9609 * http://www.apache.org/licenses/LICENSE-2.0 9610 * 9611 * Unless required by applicable law or agreed to in writing, software 9612 * distributed under the License is distributed on an "AS IS" BASIS, 9613 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9614 * See the License for the specific language governing permissions and 9615 * limitations under the License. 9616 * 9617 * @providesModule ReactEventTopLevelCallback 9618 * @typechecks static-only 9619 */ 9620 9621 "use strict"; 9622 9623 var PooledClass = _dereq_("./PooledClass"); 9624 var ReactEventEmitter = _dereq_("./ReactEventEmitter"); 9625 var ReactInstanceHandles = _dereq_("./ReactInstanceHandles"); 9626 var ReactMount = _dereq_("./ReactMount"); 9627 9628 var getEventTarget = _dereq_("./getEventTarget"); 9629 var mixInto = _dereq_("./mixInto"); 9630 9631 /** 9632 * @type {boolean} 9633 * @private 9634 */ 9635 var _topLevelListenersEnabled = true; 9636 9637 /** 9638 * Finds the parent React component of `node`. 9639 * 9640 * @param {*} node 9641 * @return {?DOMEventTarget} Parent container, or `null` if the specified node 9642 * is not nested. 9643 */ 9644 function findParent(node) { 9645 // TODO: It may be a good idea to cache this to prevent unnecessary DOM 9646 // traversal, but caching is difficult to do correctly without using a 9647 // mutation observer to listen for all DOM changes. 9648 var nodeID = ReactMount.getID(node); 9649 var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID); 9650 var container = ReactMount.findReactContainerForID(rootID); 9651 var parent = ReactMount.getFirstReactDOM(container); 9652 return parent; 9653 } 9654 9655 /** 9656 * Calls ReactEventEmitter.handleTopLevel for each node stored in bookKeeping's 9657 * ancestor list. Separated from createTopLevelCallback to avoid try/finally 9658 * deoptimization. 9659 * 9660 * @param {string} topLevelType 9661 * @param {DOMEvent} nativeEvent 9662 * @param {TopLevelCallbackBookKeeping} bookKeeping 9663 */ 9664 function handleTopLevelImpl(topLevelType, nativeEvent, bookKeeping) { 9665 var topLevelTarget = ReactMount.getFirstReactDOM( 9666 getEventTarget(nativeEvent) 9667 ) || window; 9668 9669 // Loop through the hierarchy, in case there's any nested components. 9670 // It's important that we build the array of ancestors before calling any 9671 // event handlers, because event handlers can modify the DOM, leading to 9672 // inconsistencies with ReactMount's node cache. See #1105. 9673 var ancestor = topLevelTarget; 9674 while (ancestor) { 9675 bookKeeping.ancestors.push(ancestor); 9676 ancestor = findParent(ancestor); 9677 } 9678 9679 for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) { 9680 topLevelTarget = bookKeeping.ancestors[i]; 9681 var topLevelTargetID = ReactMount.getID(topLevelTarget) || ''; 9682 ReactEventEmitter.handleTopLevel( 9683 topLevelType, 9684 topLevelTarget, 9685 topLevelTargetID, 9686 nativeEvent 9687 ); 9688 } 9689 } 9690 9691 // Used to store ancestor hierarchy in top level callback 9692 function TopLevelCallbackBookKeeping() { 9693 this.ancestors = []; 9694 } 9695 mixInto(TopLevelCallbackBookKeeping, { 9696 destructor: function() { 9697 this.ancestors.length = 0; 9698 } 9699 }); 9700 PooledClass.addPoolingTo(TopLevelCallbackBookKeeping); 9701 9702 /** 9703 * Top-level callback creator used to implement event handling using delegation. 9704 * This is used via dependency injection. 9705 */ 9706 var ReactEventTopLevelCallback = { 9707 9708 /** 9709 * Sets whether or not any created callbacks should be enabled. 9710 * 9711 * @param {boolean} enabled True if callbacks should be enabled. 9712 */ 9713 setEnabled: function(enabled) { 9714 _topLevelListenersEnabled = !!enabled; 9715 }, 9716 9717 /** 9718 * @return {boolean} True if callbacks are enabled. 9719 */ 9720 isEnabled: function() { 9721 return _topLevelListenersEnabled; 9722 }, 9723 9724 /** 9725 * Creates a callback for the supplied `topLevelType` that could be added as 9726 * a listener to the document. The callback computes a `topLevelTarget` which 9727 * should be the root node of a mounted React component where the listener 9728 * is attached. 9729 * 9730 * @param {string} topLevelType Record from `EventConstants`. 9731 * @return {function} Callback for handling top-level events. 9732 */ 9733 createTopLevelCallback: function(topLevelType) { 9734 return function(nativeEvent) { 9735 if (!_topLevelListenersEnabled) { 9736 return; 9737 } 9738 9739 var bookKeeping = TopLevelCallbackBookKeeping.getPooled(); 9740 try { 9741 handleTopLevelImpl(topLevelType, nativeEvent, bookKeeping); 9742 } finally { 9743 TopLevelCallbackBookKeeping.release(bookKeeping); 9744 } 9745 }; 9746 } 9747 9748 }; 9749 9750 module.exports = ReactEventTopLevelCallback; 9751 9752 },{"./PooledClass":25,"./ReactEventEmitter":52,"./ReactInstanceHandles":57,"./ReactMount":60,"./getEventTarget":117,"./mixInto":137}],55:[function(_dereq_,module,exports){ 9753 /** 9754 * Copyright 2013-2014 Facebook, Inc. 9755 * 9756 * Licensed under the Apache License, Version 2.0 (the "License"); 9757 * you may not use this file except in compliance with the License. 9758 * You may obtain a copy of the License at 9759 * 9760 * http://www.apache.org/licenses/LICENSE-2.0 9761 * 9762 * Unless required by applicable law or agreed to in writing, software 9763 * distributed under the License is distributed on an "AS IS" BASIS, 9764 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9765 * See the License for the specific language governing permissions and 9766 * limitations under the License. 9767 * 9768 * @providesModule ReactInjection 9769 */ 9770 9771 "use strict"; 9772 9773 var DOMProperty = _dereq_("./DOMProperty"); 9774 var EventPluginHub = _dereq_("./EventPluginHub"); 9775 var ReactComponent = _dereq_("./ReactComponent"); 9776 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 9777 var ReactDOM = _dereq_("./ReactDOM"); 9778 var ReactEventEmitter = _dereq_("./ReactEventEmitter"); 9779 var ReactPerf = _dereq_("./ReactPerf"); 9780 var ReactRootIndex = _dereq_("./ReactRootIndex"); 9781 var ReactUpdates = _dereq_("./ReactUpdates"); 9782 9783 var ReactInjection = { 9784 Component: ReactComponent.injection, 9785 CompositeComponent: ReactCompositeComponent.injection, 9786 DOMProperty: DOMProperty.injection, 9787 EventPluginHub: EventPluginHub.injection, 9788 DOM: ReactDOM.injection, 9789 EventEmitter: ReactEventEmitter.injection, 9790 Perf: ReactPerf.injection, 9791 RootIndex: ReactRootIndex.injection, 9792 Updates: ReactUpdates.injection 9793 }; 9794 9795 module.exports = ReactInjection; 9796 9797 },{"./DOMProperty":9,"./EventPluginHub":17,"./ReactComponent":31,"./ReactCompositeComponent":33,"./ReactDOM":36,"./ReactEventEmitter":52,"./ReactPerf":65,"./ReactRootIndex":72,"./ReactUpdates":81}],56:[function(_dereq_,module,exports){ 9798 /** 9799 * Copyright 2013-2014 Facebook, Inc. 9800 * 9801 * Licensed under the Apache License, Version 2.0 (the "License"); 9802 * you may not use this file except in compliance with the License. 9803 * You may obtain a copy of the License at 9804 * 9805 * http://www.apache.org/licenses/LICENSE-2.0 9806 * 9807 * Unless required by applicable law or agreed to in writing, software 9808 * distributed under the License is distributed on an "AS IS" BASIS, 9809 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9810 * See the License for the specific language governing permissions and 9811 * limitations under the License. 9812 * 9813 * @providesModule ReactInputSelection 9814 */ 9815 9816 "use strict"; 9817 9818 var ReactDOMSelection = _dereq_("./ReactDOMSelection"); 9819 9820 var containsNode = _dereq_("./containsNode"); 9821 var focusNode = _dereq_("./focusNode"); 9822 var getActiveElement = _dereq_("./getActiveElement"); 9823 9824 function isInDocument(node) { 9825 return containsNode(document.documentElement, node); 9826 } 9827 9828 /** 9829 * @ReactInputSelection: React input selection module. Based on Selection.js, 9830 * but modified to be suitable for react and has a couple of bug fixes (doesn't 9831 * assume buttons have range selections allowed). 9832 * Input selection module for React. 9833 */ 9834 var ReactInputSelection = { 9835 9836 hasSelectionCapabilities: function(elem) { 9837 return elem && ( 9838 (elem.nodeName === 'INPUT' && elem.type === 'text') || 9839 elem.nodeName === 'TEXTAREA' || 9840 elem.contentEditable === 'true' 9841 ); 9842 }, 9843 9844 getSelectionInformation: function() { 9845 var focusedElem = getActiveElement(); 9846 return { 9847 focusedElem: focusedElem, 9848 selectionRange: 9849 ReactInputSelection.hasSelectionCapabilities(focusedElem) ? 9850 ReactInputSelection.getSelection(focusedElem) : 9851 null 9852 }; 9853 }, 9854 9855 /** 9856 * @restoreSelection: If any selection information was potentially lost, 9857 * restore it. This is useful when performing operations that could remove dom 9858 * nodes and place them back in, resulting in focus being lost. 9859 */ 9860 restoreSelection: function(priorSelectionInformation) { 9861 var curFocusedElem = getActiveElement(); 9862 var priorFocusedElem = priorSelectionInformation.focusedElem; 9863 var priorSelectionRange = priorSelectionInformation.selectionRange; 9864 if (curFocusedElem !== priorFocusedElem && 9865 isInDocument(priorFocusedElem)) { 9866 if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) { 9867 ReactInputSelection.setSelection( 9868 priorFocusedElem, 9869 priorSelectionRange 9870 ); 9871 } 9872 focusNode(priorFocusedElem); 9873 } 9874 }, 9875 9876 /** 9877 * @getSelection: Gets the selection bounds of a focused textarea, input or 9878 * contentEditable node. 9879 * -@input: Look up selection bounds of this input 9880 * -@return {start: selectionStart, end: selectionEnd} 9881 */ 9882 getSelection: function(input) { 9883 var selection; 9884 9885 if ('selectionStart' in input) { 9886 // Modern browser with input or textarea. 9887 selection = { 9888 start: input.selectionStart, 9889 end: input.selectionEnd 9890 }; 9891 } else if (document.selection && input.nodeName === 'INPUT') { 9892 // IE8 input. 9893 var range = document.selection.createRange(); 9894 // There can only be one selection per document in IE, so it must 9895 // be in our element. 9896 if (range.parentElement() === input) { 9897 selection = { 9898 start: -range.moveStart('character', -input.value.length), 9899 end: -range.moveEnd('character', -input.value.length) 9900 }; 9901 } 9902 } else { 9903 // Content editable or old IE textarea. 9904 selection = ReactDOMSelection.getOffsets(input); 9905 } 9906 9907 return selection || {start: 0, end: 0}; 9908 }, 9909 9910 /** 9911 * @setSelection: Sets the selection bounds of a textarea or input and focuses 9912 * the input. 9913 * -@input Set selection bounds of this input or textarea 9914 * -@offsets Object of same form that is returned from get* 9915 */ 9916 setSelection: function(input, offsets) { 9917 var start = offsets.start; 9918 var end = offsets.end; 9919 if (typeof end === 'undefined') { 9920 end = start; 9921 } 9922 9923 if ('selectionStart' in input) { 9924 input.selectionStart = start; 9925 input.selectionEnd = Math.min(end, input.value.length); 9926 } else if (document.selection && input.nodeName === 'INPUT') { 9927 var range = input.createTextRange(); 9928 range.collapse(true); 9929 range.moveStart('character', start); 9930 range.moveEnd('character', end - start); 9931 range.select(); 9932 } else { 9933 ReactDOMSelection.setOffsets(input, offsets); 9934 } 9935 } 9936 }; 9937 9938 module.exports = ReactInputSelection; 9939 9940 },{"./ReactDOMSelection":45,"./containsNode":101,"./focusNode":113,"./getActiveElement":115}],57:[function(_dereq_,module,exports){ 9941 /** 9942 * Copyright 2013-2014 Facebook, Inc. 9943 * 9944 * Licensed under the Apache License, Version 2.0 (the "License"); 9945 * you may not use this file except in compliance with the License. 9946 * You may obtain a copy of the License at 9947 * 9948 * http://www.apache.org/licenses/LICENSE-2.0 9949 * 9950 * Unless required by applicable law or agreed to in writing, software 9951 * distributed under the License is distributed on an "AS IS" BASIS, 9952 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9953 * See the License for the specific language governing permissions and 9954 * limitations under the License. 9955 * 9956 * @providesModule ReactInstanceHandles 9957 * @typechecks static-only 9958 */ 9959 9960 "use strict"; 9961 9962 var ReactRootIndex = _dereq_("./ReactRootIndex"); 9963 9964 var invariant = _dereq_("./invariant"); 9965 9966 var SEPARATOR = '.'; 9967 var SEPARATOR_LENGTH = SEPARATOR.length; 9968 9969 /** 9970 * Maximum depth of traversals before we consider the possibility of a bad ID. 9971 */ 9972 var MAX_TREE_DEPTH = 100; 9973 9974 /** 9975 * Creates a DOM ID prefix to use when mounting React components. 9976 * 9977 * @param {number} index A unique integer 9978 * @return {string} React root ID. 9979 * @internal 9980 */ 9981 function getReactRootIDString(index) { 9982 return SEPARATOR + index.toString(36); 9983 } 9984 9985 /** 9986 * Checks if a character in the supplied ID is a separator or the end. 9987 * 9988 * @param {string} id A React DOM ID. 9989 * @param {number} index Index of the character to check. 9990 * @return {boolean} True if the character is a separator or end of the ID. 9991 * @private 9992 */ 9993 function isBoundary(id, index) { 9994 return id.charAt(index) === SEPARATOR || index === id.length; 9995 } 9996 9997 /** 9998 * Checks if the supplied string is a valid React DOM ID. 9999 * 10000 * @param {string} id A React DOM ID, maybe. 10001 * @return {boolean} True if the string is a valid React DOM ID. 10002 * @private 10003 */ 10004 function isValidID(id) { 10005 return id === '' || ( 10006 id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR 10007 ); 10008 } 10009 10010 /** 10011 * Checks if the first ID is an ancestor of or equal to the second ID. 10012 * 10013 * @param {string} ancestorID 10014 * @param {string} descendantID 10015 * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`. 10016 * @internal 10017 */ 10018 function isAncestorIDOf(ancestorID, descendantID) { 10019 return ( 10020 descendantID.indexOf(ancestorID) === 0 && 10021 isBoundary(descendantID, ancestorID.length) 10022 ); 10023 } 10024 10025 /** 10026 * Gets the parent ID of the supplied React DOM ID, `id`. 10027 * 10028 * @param {string} id ID of a component. 10029 * @return {string} ID of the parent, or an empty string. 10030 * @private 10031 */ 10032 function getParentID(id) { 10033 return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : ''; 10034 } 10035 10036 /** 10037 * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the 10038 * supplied `destinationID`. If they are equal, the ID is returned. 10039 * 10040 * @param {string} ancestorID ID of an ancestor node of `destinationID`. 10041 * @param {string} destinationID ID of the destination node. 10042 * @return {string} Next ID on the path from `ancestorID` to `destinationID`. 10043 * @private 10044 */ 10045 function getNextDescendantID(ancestorID, destinationID) { 10046 ("production" !== "development" ? invariant( 10047 isValidID(ancestorID) && isValidID(destinationID), 10048 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', 10049 ancestorID, 10050 destinationID 10051 ) : invariant(isValidID(ancestorID) && isValidID(destinationID))); 10052 ("production" !== "development" ? invariant( 10053 isAncestorIDOf(ancestorID, destinationID), 10054 'getNextDescendantID(...): React has made an invalid assumption about ' + 10055 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', 10056 ancestorID, 10057 destinationID 10058 ) : invariant(isAncestorIDOf(ancestorID, destinationID))); 10059 if (ancestorID === destinationID) { 10060 return ancestorID; 10061 } 10062 // Skip over the ancestor and the immediate separator. Traverse until we hit 10063 // another separator or we reach the end of `destinationID`. 10064 var start = ancestorID.length + SEPARATOR_LENGTH; 10065 for (var i = start; i < destinationID.length; i++) { 10066 if (isBoundary(destinationID, i)) { 10067 break; 10068 } 10069 } 10070 return destinationID.substr(0, i); 10071 } 10072 10073 /** 10074 * Gets the nearest common ancestor ID of two IDs. 10075 * 10076 * Using this ID scheme, the nearest common ancestor ID is the longest common 10077 * prefix of the two IDs that immediately preceded a "marker" in both strings. 10078 * 10079 * @param {string} oneID 10080 * @param {string} twoID 10081 * @return {string} Nearest common ancestor ID, or the empty string if none. 10082 * @private 10083 */ 10084 function getFirstCommonAncestorID(oneID, twoID) { 10085 var minLength = Math.min(oneID.length, twoID.length); 10086 if (minLength === 0) { 10087 return ''; 10088 } 10089 var lastCommonMarkerIndex = 0; 10090 // Use `<=` to traverse until the "EOL" of the shorter string. 10091 for (var i = 0; i <= minLength; i++) { 10092 if (isBoundary(oneID, i) && isBoundary(twoID, i)) { 10093 lastCommonMarkerIndex = i; 10094 } else if (oneID.charAt(i) !== twoID.charAt(i)) { 10095 break; 10096 } 10097 } 10098 var longestCommonID = oneID.substr(0, lastCommonMarkerIndex); 10099 ("production" !== "development" ? invariant( 10100 isValidID(longestCommonID), 10101 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', 10102 oneID, 10103 twoID, 10104 longestCommonID 10105 ) : invariant(isValidID(longestCommonID))); 10106 return longestCommonID; 10107 } 10108 10109 /** 10110 * Traverses the parent path between two IDs (either up or down). The IDs must 10111 * not be the same, and there must exist a parent path between them. If the 10112 * callback returns `false`, traversal is stopped. 10113 * 10114 * @param {?string} start ID at which to start traversal. 10115 * @param {?string} stop ID at which to end traversal. 10116 * @param {function} cb Callback to invoke each ID with. 10117 * @param {?boolean} skipFirst Whether or not to skip the first node. 10118 * @param {?boolean} skipLast Whether or not to skip the last node. 10119 * @private 10120 */ 10121 function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) { 10122 start = start || ''; 10123 stop = stop || ''; 10124 ("production" !== "development" ? invariant( 10125 start !== stop, 10126 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', 10127 start 10128 ) : invariant(start !== stop)); 10129 var traverseUp = isAncestorIDOf(stop, start); 10130 ("production" !== "development" ? invariant( 10131 traverseUp || isAncestorIDOf(start, stop), 10132 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + 10133 'not have a parent path.', 10134 start, 10135 stop 10136 ) : invariant(traverseUp || isAncestorIDOf(start, stop))); 10137 // Traverse from `start` to `stop` one depth at a time. 10138 var depth = 0; 10139 var traverse = traverseUp ? getParentID : getNextDescendantID; 10140 for (var id = start; /* until break */; id = traverse(id, stop)) { 10141 var ret; 10142 if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) { 10143 ret = cb(id, traverseUp, arg); 10144 } 10145 if (ret === false || id === stop) { 10146 // Only break //after// visiting `stop`. 10147 break; 10148 } 10149 ("production" !== "development" ? invariant( 10150 depth++ < MAX_TREE_DEPTH, 10151 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + 10152 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', 10153 start, stop 10154 ) : invariant(depth++ < MAX_TREE_DEPTH)); 10155 } 10156 } 10157 10158 /** 10159 * Manages the IDs assigned to DOM representations of React components. This 10160 * uses a specific scheme in order to traverse the DOM efficiently (e.g. in 10161 * order to simulate events). 10162 * 10163 * @internal 10164 */ 10165 var ReactInstanceHandles = { 10166 10167 /** 10168 * Constructs a React root ID 10169 * @return {string} A React root ID. 10170 */ 10171 createReactRootID: function() { 10172 return getReactRootIDString(ReactRootIndex.createReactRootIndex()); 10173 }, 10174 10175 /** 10176 * Constructs a React ID by joining a root ID with a name. 10177 * 10178 * @param {string} rootID Root ID of a parent component. 10179 * @param {string} name A component's name (as flattened children). 10180 * @return {string} A React ID. 10181 * @internal 10182 */ 10183 createReactID: function(rootID, name) { 10184 return rootID + name; 10185 }, 10186 10187 /** 10188 * Gets the DOM ID of the React component that is the root of the tree that 10189 * contains the React component with the supplied DOM ID. 10190 * 10191 * @param {string} id DOM ID of a React component. 10192 * @return {?string} DOM ID of the React component that is the root. 10193 * @internal 10194 */ 10195 getReactRootIDFromNodeID: function(id) { 10196 if (id && id.charAt(0) === SEPARATOR && id.length > 1) { 10197 var index = id.indexOf(SEPARATOR, 1); 10198 return index > -1 ? id.substr(0, index) : id; 10199 } 10200 return null; 10201 }, 10202 10203 /** 10204 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that 10205 * should would receive a `mouseEnter` or `mouseLeave` event. 10206 * 10207 * NOTE: Does not invoke the callback on the nearest common ancestor because 10208 * nothing "entered" or "left" that element. 10209 * 10210 * @param {string} leaveID ID being left. 10211 * @param {string} enterID ID being entered. 10212 * @param {function} cb Callback to invoke on each entered/left ID. 10213 * @param {*} upArg Argument to invoke the callback with on left IDs. 10214 * @param {*} downArg Argument to invoke the callback with on entered IDs. 10215 * @internal 10216 */ 10217 traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) { 10218 var ancestorID = getFirstCommonAncestorID(leaveID, enterID); 10219 if (ancestorID !== leaveID) { 10220 traverseParentPath(leaveID, ancestorID, cb, upArg, false, true); 10221 } 10222 if (ancestorID !== enterID) { 10223 traverseParentPath(ancestorID, enterID, cb, downArg, true, false); 10224 } 10225 }, 10226 10227 /** 10228 * Simulates the traversal of a two-phase, capture/bubble event dispatch. 10229 * 10230 * NOTE: This traversal happens on IDs without touching the DOM. 10231 * 10232 * @param {string} targetID ID of the target node. 10233 * @param {function} cb Callback to invoke. 10234 * @param {*} arg Argument to invoke the callback with. 10235 * @internal 10236 */ 10237 traverseTwoPhase: function(targetID, cb, arg) { 10238 if (targetID) { 10239 traverseParentPath('', targetID, cb, arg, true, false); 10240 traverseParentPath(targetID, '', cb, arg, false, true); 10241 } 10242 }, 10243 10244 /** 10245 * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For 10246 * example, passing `.0.$row-0.1` would result in `cb` getting called 10247 * with `.0`, `.0.$row-0`, and `.0.$row-0.1`. 10248 * 10249 * NOTE: This traversal happens on IDs without touching the DOM. 10250 * 10251 * @param {string} targetID ID of the target node. 10252 * @param {function} cb Callback to invoke. 10253 * @param {*} arg Argument to invoke the callback with. 10254 * @internal 10255 */ 10256 traverseAncestors: function(targetID, cb, arg) { 10257 traverseParentPath('', targetID, cb, arg, true, false); 10258 }, 10259 10260 /** 10261 * Exposed for unit testing. 10262 * @private 10263 */ 10264 _getFirstCommonAncestorID: getFirstCommonAncestorID, 10265 10266 /** 10267 * Exposed for unit testing. 10268 * @private 10269 */ 10270 _getNextDescendantID: getNextDescendantID, 10271 10272 isAncestorIDOf: isAncestorIDOf, 10273 10274 SEPARATOR: SEPARATOR 10275 10276 }; 10277 10278 module.exports = ReactInstanceHandles; 10279 10280 },{"./ReactRootIndex":72,"./invariant":125}],58:[function(_dereq_,module,exports){ 10281 /** 10282 * Copyright 2013-2014 Facebook, Inc. 10283 * 10284 * Licensed under the Apache License, Version 2.0 (the "License"); 10285 * you may not use this file except in compliance with the License. 10286 * You may obtain a copy of the License at 10287 * 10288 * http://www.apache.org/licenses/LICENSE-2.0 10289 * 10290 * Unless required by applicable law or agreed to in writing, software 10291 * distributed under the License is distributed on an "AS IS" BASIS, 10292 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10293 * See the License for the specific language governing permissions and 10294 * limitations under the License. 10295 * 10296 * @providesModule ReactLink 10297 * @typechecks static-only 10298 */ 10299 10300 "use strict"; 10301 10302 /** 10303 * ReactLink encapsulates a common pattern in which a component wants to modify 10304 * a prop received from its parent. ReactLink allows the parent to pass down a 10305 * value coupled with a callback that, when invoked, expresses an intent to 10306 * modify that value. For example: 10307 * 10308 * React.createClass({ 10309 * getInitialState: function() { 10310 * return {value: ''}; 10311 * }, 10312 * render: function() { 10313 * var valueLink = new ReactLink(this.state.value, this._handleValueChange); 10314 * return <input valueLink={valueLink} />; 10315 * }, 10316 * this._handleValueChange: function(newValue) { 10317 * this.setState({value: newValue}); 10318 * } 10319 * }); 10320 * 10321 * We have provided some sugary mixins to make the creation and 10322 * consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin. 10323 */ 10324 10325 /** 10326 * @param {*} value current value of the link 10327 * @param {function} requestChange callback to request a change 10328 */ 10329 function ReactLink(value, requestChange) { 10330 this.value = value; 10331 this.requestChange = requestChange; 10332 } 10333 10334 module.exports = ReactLink; 10335 10336 },{}],59:[function(_dereq_,module,exports){ 10337 /** 10338 * Copyright 2013-2014 Facebook, Inc. 10339 * 10340 * Licensed under the Apache License, Version 2.0 (the "License"); 10341 * you may not use this file except in compliance with the License. 10342 * You may obtain a copy of the License at 10343 * 10344 * http://www.apache.org/licenses/LICENSE-2.0 10345 * 10346 * Unless required by applicable law or agreed to in writing, software 10347 * distributed under the License is distributed on an "AS IS" BASIS, 10348 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10349 * See the License for the specific language governing permissions and 10350 * limitations under the License. 10351 * 10352 * @providesModule ReactMarkupChecksum 10353 */ 10354 10355 "use strict"; 10356 10357 var adler32 = _dereq_("./adler32"); 10358 10359 var ReactMarkupChecksum = { 10360 CHECKSUM_ATTR_NAME: 'data-react-checksum', 10361 10362 /** 10363 * @param {string} markup Markup string 10364 * @return {string} Markup string with checksum attribute attached 10365 */ 10366 addChecksumToMarkup: function(markup) { 10367 var checksum = adler32(markup); 10368 return markup.replace( 10369 '>', 10370 ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">' 10371 ); 10372 }, 10373 10374 /** 10375 * @param {string} markup to use 10376 * @param {DOMElement} element root React element 10377 * @returns {boolean} whether or not the markup is the same 10378 */ 10379 canReuseMarkup: function(markup, element) { 10380 var existingChecksum = element.getAttribute( 10381 ReactMarkupChecksum.CHECKSUM_ATTR_NAME 10382 ); 10383 existingChecksum = existingChecksum && parseInt(existingChecksum, 10); 10384 var markupChecksum = adler32(markup); 10385 return markupChecksum === existingChecksum; 10386 } 10387 }; 10388 10389 module.exports = ReactMarkupChecksum; 10390 10391 },{"./adler32":99}],60:[function(_dereq_,module,exports){ 10392 /** 10393 * Copyright 2013-2014 Facebook, Inc. 10394 * 10395 * Licensed under the Apache License, Version 2.0 (the "License"); 10396 * you may not use this file except in compliance with the License. 10397 * You may obtain a copy of the License at 10398 * 10399 * http://www.apache.org/licenses/LICENSE-2.0 10400 * 10401 * Unless required by applicable law or agreed to in writing, software 10402 * distributed under the License is distributed on an "AS IS" BASIS, 10403 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10404 * See the License for the specific language governing permissions and 10405 * limitations under the License. 10406 * 10407 * @providesModule ReactMount 10408 */ 10409 10410 "use strict"; 10411 10412 var DOMProperty = _dereq_("./DOMProperty"); 10413 var ReactEventEmitter = _dereq_("./ReactEventEmitter"); 10414 var ReactInstanceHandles = _dereq_("./ReactInstanceHandles"); 10415 var ReactPerf = _dereq_("./ReactPerf"); 10416 10417 var containsNode = _dereq_("./containsNode"); 10418 var getReactRootElementInContainer = _dereq_("./getReactRootElementInContainer"); 10419 var instantiateReactComponent = _dereq_("./instantiateReactComponent"); 10420 var invariant = _dereq_("./invariant"); 10421 var shouldUpdateReactComponent = _dereq_("./shouldUpdateReactComponent"); 10422 10423 var SEPARATOR = ReactInstanceHandles.SEPARATOR; 10424 10425 var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; 10426 var nodeCache = {}; 10427 10428 var ELEMENT_NODE_TYPE = 1; 10429 var DOC_NODE_TYPE = 9; 10430 10431 /** Mapping from reactRootID to React component instance. */ 10432 var instancesByReactRootID = {}; 10433 10434 /** Mapping from reactRootID to `container` nodes. */ 10435 var containersByReactRootID = {}; 10436 10437 if ("production" !== "development") { 10438 /** __DEV__-only mapping from reactRootID to root elements. */ 10439 var rootElementsByReactRootID = {}; 10440 } 10441 10442 // Used to store breadth-first search state in findComponentRoot. 10443 var findComponentRootReusableArray = []; 10444 10445 /** 10446 * @param {DOMElement} container DOM element that may contain a React component. 10447 * @return {?string} A "reactRoot" ID, if a React component is rendered. 10448 */ 10449 function getReactRootID(container) { 10450 var rootElement = getReactRootElementInContainer(container); 10451 return rootElement && ReactMount.getID(rootElement); 10452 } 10453 10454 /** 10455 * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form 10456 * element can return its control whose name or ID equals ATTR_NAME. All 10457 * DOM nodes support `getAttributeNode` but this can also get called on 10458 * other objects so just return '' if we're given something other than a 10459 * DOM node (such as window). 10460 * 10461 * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node. 10462 * @return {string} ID of the supplied `domNode`. 10463 */ 10464 function getID(node) { 10465 var id = internalGetID(node); 10466 if (id) { 10467 if (nodeCache.hasOwnProperty(id)) { 10468 var cached = nodeCache[id]; 10469 if (cached !== node) { 10470 ("production" !== "development" ? invariant( 10471 !isValid(cached, id), 10472 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', 10473 ATTR_NAME, id 10474 ) : invariant(!isValid(cached, id))); 10475 10476 nodeCache[id] = node; 10477 } 10478 } else { 10479 nodeCache[id] = node; 10480 } 10481 } 10482 10483 return id; 10484 } 10485 10486 function internalGetID(node) { 10487 // If node is something like a window, document, or text node, none of 10488 // which support attributes or a .getAttribute method, gracefully return 10489 // the empty string, as if the attribute were missing. 10490 return node && node.getAttribute && node.getAttribute(ATTR_NAME) || ''; 10491 } 10492 10493 /** 10494 * Sets the React-specific ID of the given node. 10495 * 10496 * @param {DOMElement} node The DOM node whose ID will be set. 10497 * @param {string} id The value of the ID attribute. 10498 */ 10499 function setID(node, id) { 10500 var oldID = internalGetID(node); 10501 if (oldID !== id) { 10502 delete nodeCache[oldID]; 10503 } 10504 node.setAttribute(ATTR_NAME, id); 10505 nodeCache[id] = node; 10506 } 10507 10508 /** 10509 * Finds the node with the supplied React-generated DOM ID. 10510 * 10511 * @param {string} id A React-generated DOM ID. 10512 * @return {DOMElement} DOM node with the suppled `id`. 10513 * @internal 10514 */ 10515 function getNode(id) { 10516 if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { 10517 nodeCache[id] = ReactMount.findReactNodeByID(id); 10518 } 10519 return nodeCache[id]; 10520 } 10521 10522 /** 10523 * A node is "valid" if it is contained by a currently mounted container. 10524 * 10525 * This means that the node does not have to be contained by a document in 10526 * order to be considered valid. 10527 * 10528 * @param {?DOMElement} node The candidate DOM node. 10529 * @param {string} id The expected ID of the node. 10530 * @return {boolean} Whether the node is contained by a mounted container. 10531 */ 10532 function isValid(node, id) { 10533 if (node) { 10534 ("production" !== "development" ? invariant( 10535 internalGetID(node) === id, 10536 'ReactMount: Unexpected modification of `%s`', 10537 ATTR_NAME 10538 ) : invariant(internalGetID(node) === id)); 10539 10540 var container = ReactMount.findReactContainerForID(id); 10541 if (container && containsNode(container, node)) { 10542 return true; 10543 } 10544 } 10545 10546 return false; 10547 } 10548 10549 /** 10550 * Causes the cache to forget about one React-specific ID. 10551 * 10552 * @param {string} id The ID to forget. 10553 */ 10554 function purgeID(id) { 10555 delete nodeCache[id]; 10556 } 10557 10558 var deepestNodeSoFar = null; 10559 function findDeepestCachedAncestorImpl(ancestorID) { 10560 var ancestor = nodeCache[ancestorID]; 10561 if (ancestor && isValid(ancestor, ancestorID)) { 10562 deepestNodeSoFar = ancestor; 10563 } else { 10564 // This node isn't populated in the cache, so presumably none of its 10565 // descendants are. Break out of the loop. 10566 return false; 10567 } 10568 } 10569 10570 /** 10571 * Return the deepest cached node whose ID is a prefix of `targetID`. 10572 */ 10573 function findDeepestCachedAncestor(targetID) { 10574 deepestNodeSoFar = null; 10575 ReactInstanceHandles.traverseAncestors( 10576 targetID, 10577 findDeepestCachedAncestorImpl 10578 ); 10579 10580 var foundNode = deepestNodeSoFar; 10581 deepestNodeSoFar = null; 10582 return foundNode; 10583 } 10584 10585 /** 10586 * Mounting is the process of initializing a React component by creatings its 10587 * representative DOM elements and inserting them into a supplied `container`. 10588 * Any prior content inside `container` is destroyed in the process. 10589 * 10590 * ReactMount.renderComponent( 10591 * component, 10592 * document.getElementById('container') 10593 * ); 10594 * 10595 * <div id="container"> <-- Supplied `container`. 10596 * <div data-reactid=".3"> <-- Rendered reactRoot of React 10597 * // ... component. 10598 * </div> 10599 * </div> 10600 * 10601 * Inside of `container`, the first element rendered is the "reactRoot". 10602 */ 10603 var ReactMount = { 10604 /** Time spent generating markup. */ 10605 totalInstantiationTime: 0, 10606 10607 /** Time spent inserting markup into the DOM. */ 10608 totalInjectionTime: 0, 10609 10610 /** Whether support for touch events should be initialized. */ 10611 useTouchEvents: false, 10612 10613 /** Exposed for debugging purposes **/ 10614 _instancesByReactRootID: instancesByReactRootID, 10615 10616 /** 10617 * This is a hook provided to support rendering React components while 10618 * ensuring that the apparent scroll position of its `container` does not 10619 * change. 10620 * 10621 * @param {DOMElement} container The `container` being rendered into. 10622 * @param {function} renderCallback This must be called once to do the render. 10623 */ 10624 scrollMonitor: function(container, renderCallback) { 10625 renderCallback(); 10626 }, 10627 10628 /** 10629 * Take a component that's already mounted into the DOM and replace its props 10630 * @param {ReactComponent} prevComponent component instance already in the DOM 10631 * @param {ReactComponent} nextComponent component instance to render 10632 * @param {DOMElement} container container to render into 10633 * @param {?function} callback function triggered on completion 10634 */ 10635 _updateRootComponent: function( 10636 prevComponent, 10637 nextComponent, 10638 container, 10639 callback) { 10640 var nextProps = nextComponent.props; 10641 ReactMount.scrollMonitor(container, function() { 10642 prevComponent.replaceProps(nextProps, callback); 10643 }); 10644 10645 if ("production" !== "development") { 10646 // Record the root element in case it later gets transplanted. 10647 rootElementsByReactRootID[getReactRootID(container)] = 10648 getReactRootElementInContainer(container); 10649 } 10650 10651 return prevComponent; 10652 }, 10653 10654 /** 10655 * Register a component into the instance map and starts scroll value 10656 * monitoring 10657 * @param {ReactComponent} nextComponent component instance to render 10658 * @param {DOMElement} container container to render into 10659 * @return {string} reactRoot ID prefix 10660 */ 10661 _registerComponent: function(nextComponent, container) { 10662 ("production" !== "development" ? invariant( 10663 container && ( 10664 container.nodeType === ELEMENT_NODE_TYPE || 10665 container.nodeType === DOC_NODE_TYPE 10666 ), 10667 '_registerComponent(...): Target container is not a DOM element.' 10668 ) : invariant(container && ( 10669 container.nodeType === ELEMENT_NODE_TYPE || 10670 container.nodeType === DOC_NODE_TYPE 10671 ))); 10672 10673 ReactEventEmitter.ensureScrollValueMonitoring(); 10674 10675 var reactRootID = ReactMount.registerContainer(container); 10676 instancesByReactRootID[reactRootID] = nextComponent; 10677 return reactRootID; 10678 }, 10679 10680 /** 10681 * Render a new component into the DOM. 10682 * @param {ReactComponent} nextComponent component instance to render 10683 * @param {DOMElement} container container to render into 10684 * @param {boolean} shouldReuseMarkup if we should skip the markup insertion 10685 * @return {ReactComponent} nextComponent 10686 */ 10687 _renderNewRootComponent: ReactPerf.measure( 10688 'ReactMount', 10689 '_renderNewRootComponent', 10690 function( 10691 nextComponent, 10692 container, 10693 shouldReuseMarkup) { 10694 10695 var componentInstance = instantiateReactComponent(nextComponent); 10696 var reactRootID = ReactMount._registerComponent( 10697 componentInstance, 10698 container 10699 ); 10700 componentInstance.mountComponentIntoNode( 10701 reactRootID, 10702 container, 10703 shouldReuseMarkup 10704 ); 10705 10706 if ("production" !== "development") { 10707 // Record the root element in case it later gets transplanted. 10708 rootElementsByReactRootID[reactRootID] = 10709 getReactRootElementInContainer(container); 10710 } 10711 10712 return componentInstance; 10713 } 10714 ), 10715 10716 /** 10717 * Renders a React component into the DOM in the supplied `container`. 10718 * 10719 * If the React component was previously rendered into `container`, this will 10720 * perform an update on it and only mutate the DOM as necessary to reflect the 10721 * latest React component. 10722 * 10723 * @param {ReactComponent} nextComponent Component instance to render. 10724 * @param {DOMElement} container DOM element to render into. 10725 * @param {?function} callback function triggered on completion 10726 * @return {ReactComponent} Component instance rendered in `container`. 10727 */ 10728 renderComponent: function(nextComponent, container, callback) { 10729 var prevComponent = instancesByReactRootID[getReactRootID(container)]; 10730 10731 if (prevComponent) { 10732 if (shouldUpdateReactComponent(prevComponent, nextComponent)) { 10733 return ReactMount._updateRootComponent( 10734 prevComponent, 10735 nextComponent, 10736 container, 10737 callback 10738 ); 10739 } else { 10740 ReactMount.unmountComponentAtNode(container); 10741 } 10742 } 10743 10744 var reactRootElement = getReactRootElementInContainer(container); 10745 var containerHasReactMarkup = 10746 reactRootElement && ReactMount.isRenderedByReact(reactRootElement); 10747 10748 var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; 10749 10750 var component = ReactMount._renderNewRootComponent( 10751 nextComponent, 10752 container, 10753 shouldReuseMarkup 10754 ); 10755 callback && callback.call(component); 10756 return component; 10757 }, 10758 10759 /** 10760 * Constructs a component instance of `constructor` with `initialProps` and 10761 * renders it into the supplied `container`. 10762 * 10763 * @param {function} constructor React component constructor. 10764 * @param {?object} props Initial props of the component instance. 10765 * @param {DOMElement} container DOM element to render into. 10766 * @return {ReactComponent} Component instance rendered in `container`. 10767 */ 10768 constructAndRenderComponent: function(constructor, props, container) { 10769 return ReactMount.renderComponent(constructor(props), container); 10770 }, 10771 10772 /** 10773 * Constructs a component instance of `constructor` with `initialProps` and 10774 * renders it into a container node identified by supplied `id`. 10775 * 10776 * @param {function} componentConstructor React component constructor 10777 * @param {?object} props Initial props of the component instance. 10778 * @param {string} id ID of the DOM element to render into. 10779 * @return {ReactComponent} Component instance rendered in the container node. 10780 */ 10781 constructAndRenderComponentByID: function(constructor, props, id) { 10782 var domNode = document.getElementById(id); 10783 ("production" !== "development" ? invariant( 10784 domNode, 10785 'Tried to get element with id of "%s" but it is not present on the page.', 10786 id 10787 ) : invariant(domNode)); 10788 return ReactMount.constructAndRenderComponent(constructor, props, domNode); 10789 }, 10790 10791 /** 10792 * Registers a container node into which React components will be rendered. 10793 * This also creates the "reactRoot" ID that will be assigned to the element 10794 * rendered within. 10795 * 10796 * @param {DOMElement} container DOM element to register as a container. 10797 * @return {string} The "reactRoot" ID of elements rendered within. 10798 */ 10799 registerContainer: function(container) { 10800 var reactRootID = getReactRootID(container); 10801 if (reactRootID) { 10802 // If one exists, make sure it is a valid "reactRoot" ID. 10803 reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID); 10804 } 10805 if (!reactRootID) { 10806 // No valid "reactRoot" ID found, create one. 10807 reactRootID = ReactInstanceHandles.createReactRootID(); 10808 } 10809 containersByReactRootID[reactRootID] = container; 10810 return reactRootID; 10811 }, 10812 10813 /** 10814 * Unmounts and destroys the React component rendered in the `container`. 10815 * 10816 * @param {DOMElement} container DOM element containing a React component. 10817 * @return {boolean} True if a component was found in and unmounted from 10818 * `container` 10819 */ 10820 unmountComponentAtNode: function(container) { 10821 var reactRootID = getReactRootID(container); 10822 var component = instancesByReactRootID[reactRootID]; 10823 if (!component) { 10824 return false; 10825 } 10826 ReactMount.unmountComponentFromNode(component, container); 10827 delete instancesByReactRootID[reactRootID]; 10828 delete containersByReactRootID[reactRootID]; 10829 if ("production" !== "development") { 10830 delete rootElementsByReactRootID[reactRootID]; 10831 } 10832 return true; 10833 }, 10834 10835 /** 10836 * Unmounts a component and removes it from the DOM. 10837 * 10838 * @param {ReactComponent} instance React component instance. 10839 * @param {DOMElement} container DOM element to unmount from. 10840 * @final 10841 * @internal 10842 * @see {ReactMount.unmountComponentAtNode} 10843 */ 10844 unmountComponentFromNode: function(instance, container) { 10845 instance.unmountComponent(); 10846 10847 if (container.nodeType === DOC_NODE_TYPE) { 10848 container = container.documentElement; 10849 } 10850 10851 // http://jsperf.com/emptying-a-node 10852 while (container.lastChild) { 10853 container.removeChild(container.lastChild); 10854 } 10855 }, 10856 10857 /** 10858 * Finds the container DOM element that contains React component to which the 10859 * supplied DOM `id` belongs. 10860 * 10861 * @param {string} id The ID of an element rendered by a React component. 10862 * @return {?DOMElement} DOM element that contains the `id`. 10863 */ 10864 findReactContainerForID: function(id) { 10865 var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id); 10866 var container = containersByReactRootID[reactRootID]; 10867 10868 if ("production" !== "development") { 10869 var rootElement = rootElementsByReactRootID[reactRootID]; 10870 if (rootElement && rootElement.parentNode !== container) { 10871 ("production" !== "development" ? invariant( 10872 // Call internalGetID here because getID calls isValid which calls 10873 // findReactContainerForID (this function). 10874 internalGetID(rootElement) === reactRootID, 10875 'ReactMount: Root element ID differed from reactRootID.' 10876 ) : invariant(// Call internalGetID here because getID calls isValid which calls 10877 // findReactContainerForID (this function). 10878 internalGetID(rootElement) === reactRootID)); 10879 10880 var containerChild = container.firstChild; 10881 if (containerChild && 10882 reactRootID === internalGetID(containerChild)) { 10883 // If the container has a new child with the same ID as the old 10884 // root element, then rootElementsByReactRootID[reactRootID] is 10885 // just stale and needs to be updated. The case that deserves a 10886 // warning is when the container is empty. 10887 rootElementsByReactRootID[reactRootID] = containerChild; 10888 } else { 10889 console.warn( 10890 'ReactMount: Root element has been removed from its original ' + 10891 'container. New container:', rootElement.parentNode 10892 ); 10893 } 10894 } 10895 } 10896 10897 return container; 10898 }, 10899 10900 /** 10901 * Finds an element rendered by React with the supplied ID. 10902 * 10903 * @param {string} id ID of a DOM node in the React component. 10904 * @return {DOMElement} Root DOM node of the React component. 10905 */ 10906 findReactNodeByID: function(id) { 10907 var reactRoot = ReactMount.findReactContainerForID(id); 10908 return ReactMount.findComponentRoot(reactRoot, id); 10909 }, 10910 10911 /** 10912 * True if the supplied `node` is rendered by React. 10913 * 10914 * @param {*} node DOM Element to check. 10915 * @return {boolean} True if the DOM Element appears to be rendered by React. 10916 * @internal 10917 */ 10918 isRenderedByReact: function(node) { 10919 if (node.nodeType !== 1) { 10920 // Not a DOMElement, therefore not a React component 10921 return false; 10922 } 10923 var id = ReactMount.getID(node); 10924 return id ? id.charAt(0) === SEPARATOR : false; 10925 }, 10926 10927 /** 10928 * Traverses up the ancestors of the supplied node to find a node that is a 10929 * DOM representation of a React component. 10930 * 10931 * @param {*} node 10932 * @return {?DOMEventTarget} 10933 * @internal 10934 */ 10935 getFirstReactDOM: function(node) { 10936 var current = node; 10937 while (current && current.parentNode !== current) { 10938 if (ReactMount.isRenderedByReact(current)) { 10939 return current; 10940 } 10941 current = current.parentNode; 10942 } 10943 return null; 10944 }, 10945 10946 /** 10947 * Finds a node with the supplied `targetID` inside of the supplied 10948 * `ancestorNode`. Exploits the ID naming scheme to perform the search 10949 * quickly. 10950 * 10951 * @param {DOMEventTarget} ancestorNode Search from this root. 10952 * @pararm {string} targetID ID of the DOM representation of the component. 10953 * @return {DOMEventTarget} DOM node with the supplied `targetID`. 10954 * @internal 10955 */ 10956 findComponentRoot: function(ancestorNode, targetID) { 10957 var firstChildren = findComponentRootReusableArray; 10958 var childIndex = 0; 10959 10960 var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode; 10961 10962 firstChildren[0] = deepestAncestor.firstChild; 10963 firstChildren.length = 1; 10964 10965 while (childIndex < firstChildren.length) { 10966 var child = firstChildren[childIndex++]; 10967 var targetChild; 10968 10969 while (child) { 10970 var childID = ReactMount.getID(child); 10971 if (childID) { 10972 // Even if we find the node we're looking for, we finish looping 10973 // through its siblings to ensure they're cached so that we don't have 10974 // to revisit this node again. Otherwise, we make n^2 calls to getID 10975 // when visiting the many children of a single node in order. 10976 10977 if (targetID === childID) { 10978 targetChild = child; 10979 } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) { 10980 // If we find a child whose ID is an ancestor of the given ID, 10981 // then we can be sure that we only want to search the subtree 10982 // rooted at this child, so we can throw out the rest of the 10983 // search state. 10984 firstChildren.length = childIndex = 0; 10985 firstChildren.push(child.firstChild); 10986 } 10987 10988 } else { 10989 // If this child had no ID, then there's a chance that it was 10990 // injected automatically by the browser, as when a `<table>` 10991 // element sprouts an extra `<tbody>` child as a side effect of 10992 // `.innerHTML` parsing. Optimistically continue down this 10993 // branch, but not before examining the other siblings. 10994 firstChildren.push(child.firstChild); 10995 } 10996 10997 child = child.nextSibling; 10998 } 10999 11000 if (targetChild) { 11001 // Emptying firstChildren/findComponentRootReusableArray is 11002 // not necessary for correctness, but it helps the GC reclaim 11003 // any nodes that were left at the end of the search. 11004 firstChildren.length = 0; 11005 11006 return targetChild; 11007 } 11008 } 11009 11010 firstChildren.length = 0; 11011 11012 ("production" !== "development" ? invariant( 11013 false, 11014 'findComponentRoot(..., %s): Unable to find element. This probably ' + 11015 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + 11016 'usually due to forgetting a <tbody> when using tables or nesting <p> ' + 11017 'or <a> tags. Try inspecting the child nodes of the element with React ' + 11018 'ID `%s`.', 11019 targetID, 11020 ReactMount.getID(ancestorNode) 11021 ) : invariant(false)); 11022 }, 11023 11024 11025 /** 11026 * React ID utilities. 11027 */ 11028 11029 getReactRootID: getReactRootID, 11030 11031 getID: getID, 11032 11033 setID: setID, 11034 11035 getNode: getNode, 11036 11037 purgeID: purgeID 11038 }; 11039 11040 module.exports = ReactMount; 11041 11042 },{"./DOMProperty":9,"./ReactEventEmitter":52,"./ReactInstanceHandles":57,"./ReactPerf":65,"./containsNode":101,"./getReactRootElementInContainer":120,"./instantiateReactComponent":124,"./invariant":125,"./shouldUpdateReactComponent":144}],61:[function(_dereq_,module,exports){ 11043 /** 11044 * Copyright 2013-2014 Facebook, Inc. 11045 * 11046 * Licensed under the Apache License, Version 2.0 (the "License"); 11047 * you may not use this file except in compliance with the License. 11048 * You may obtain a copy of the License at 11049 * 11050 * http://www.apache.org/licenses/LICENSE-2.0 11051 * 11052 * Unless required by applicable law or agreed to in writing, software 11053 * distributed under the License is distributed on an "AS IS" BASIS, 11054 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11055 * See the License for the specific language governing permissions and 11056 * limitations under the License. 11057 * 11058 * @providesModule ReactMountReady 11059 */ 11060 11061 "use strict"; 11062 11063 var PooledClass = _dereq_("./PooledClass"); 11064 11065 var mixInto = _dereq_("./mixInto"); 11066 11067 /** 11068 * A specialized pseudo-event module to help keep track of components waiting to 11069 * be notified when their DOM representations are available for use. 11070 * 11071 * This implements `PooledClass`, so you should never need to instantiate this. 11072 * Instead, use `ReactMountReady.getPooled()`. 11073 * 11074 * @param {?array<function>} initialCollection 11075 * @class ReactMountReady 11076 * @implements PooledClass 11077 * @internal 11078 */ 11079 function ReactMountReady(initialCollection) { 11080 this._queue = initialCollection || null; 11081 } 11082 11083 mixInto(ReactMountReady, { 11084 11085 /** 11086 * Enqueues a callback to be invoked when `notifyAll` is invoked. This is used 11087 * to enqueue calls to `componentDidMount` and `componentDidUpdate`. 11088 * 11089 * @param {ReactComponent} component Component being rendered. 11090 * @param {function(DOMElement)} callback Invoked when `notifyAll` is invoked. 11091 * @internal 11092 */ 11093 enqueue: function(component, callback) { 11094 this._queue = this._queue || []; 11095 this._queue.push({component: component, callback: callback}); 11096 }, 11097 11098 /** 11099 * Invokes all enqueued callbacks and clears the queue. This is invoked after 11100 * the DOM representation of a component has been created or updated. 11101 * 11102 * @internal 11103 */ 11104 notifyAll: function() { 11105 var queue = this._queue; 11106 if (queue) { 11107 this._queue = null; 11108 for (var i = 0, l = queue.length; i < l; i++) { 11109 var component = queue[i].component; 11110 var callback = queue[i].callback; 11111 callback.call(component); 11112 } 11113 queue.length = 0; 11114 } 11115 }, 11116 11117 /** 11118 * Resets the internal queue. 11119 * 11120 * @internal 11121 */ 11122 reset: function() { 11123 this._queue = null; 11124 }, 11125 11126 /** 11127 * `PooledClass` looks for this. 11128 */ 11129 destructor: function() { 11130 this.reset(); 11131 } 11132 11133 }); 11134 11135 PooledClass.addPoolingTo(ReactMountReady); 11136 11137 module.exports = ReactMountReady; 11138 11139 },{"./PooledClass":25,"./mixInto":137}],62:[function(_dereq_,module,exports){ 11140 /** 11141 * Copyright 2013-2014 Facebook, Inc. 11142 * 11143 * Licensed under the Apache License, Version 2.0 (the "License"); 11144 * you may not use this file except in compliance with the License. 11145 * You may obtain a copy of the License at 11146 * 11147 * http://www.apache.org/licenses/LICENSE-2.0 11148 * 11149 * Unless required by applicable law or agreed to in writing, software 11150 * distributed under the License is distributed on an "AS IS" BASIS, 11151 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11152 * See the License for the specific language governing permissions and 11153 * limitations under the License. 11154 * 11155 * @providesModule ReactMultiChild 11156 * @typechecks static-only 11157 */ 11158 11159 "use strict"; 11160 11161 var ReactComponent = _dereq_("./ReactComponent"); 11162 var ReactMultiChildUpdateTypes = _dereq_("./ReactMultiChildUpdateTypes"); 11163 11164 var flattenChildren = _dereq_("./flattenChildren"); 11165 var instantiateReactComponent = _dereq_("./instantiateReactComponent"); 11166 var shouldUpdateReactComponent = _dereq_("./shouldUpdateReactComponent"); 11167 11168 /** 11169 * Updating children of a component may trigger recursive updates. The depth is 11170 * used to batch recursive updates to render markup more efficiently. 11171 * 11172 * @type {number} 11173 * @private 11174 */ 11175 var updateDepth = 0; 11176 11177 /** 11178 * Queue of update configuration objects. 11179 * 11180 * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`. 11181 * 11182 * @type {array<object>} 11183 * @private 11184 */ 11185 var updateQueue = []; 11186 11187 /** 11188 * Queue of markup to be rendered. 11189 * 11190 * @type {array<string>} 11191 * @private 11192 */ 11193 var markupQueue = []; 11194 11195 /** 11196 * Enqueues markup to be rendered and inserted at a supplied index. 11197 * 11198 * @param {string} parentID ID of the parent component. 11199 * @param {string} markup Markup that renders into an element. 11200 * @param {number} toIndex Destination index. 11201 * @private 11202 */ 11203 function enqueueMarkup(parentID, markup, toIndex) { 11204 // NOTE: Null values reduce hidden classes. 11205 updateQueue.push({ 11206 parentID: parentID, 11207 parentNode: null, 11208 type: ReactMultiChildUpdateTypes.INSERT_MARKUP, 11209 markupIndex: markupQueue.push(markup) - 1, 11210 textContent: null, 11211 fromIndex: null, 11212 toIndex: toIndex 11213 }); 11214 } 11215 11216 /** 11217 * Enqueues moving an existing element to another index. 11218 * 11219 * @param {string} parentID ID of the parent component. 11220 * @param {number} fromIndex Source index of the existing element. 11221 * @param {number} toIndex Destination index of the element. 11222 * @private 11223 */ 11224 function enqueueMove(parentID, fromIndex, toIndex) { 11225 // NOTE: Null values reduce hidden classes. 11226 updateQueue.push({ 11227 parentID: parentID, 11228 parentNode: null, 11229 type: ReactMultiChildUpdateTypes.MOVE_EXISTING, 11230 markupIndex: null, 11231 textContent: null, 11232 fromIndex: fromIndex, 11233 toIndex: toIndex 11234 }); 11235 } 11236 11237 /** 11238 * Enqueues removing an element at an index. 11239 * 11240 * @param {string} parentID ID of the parent component. 11241 * @param {number} fromIndex Index of the element to remove. 11242 * @private 11243 */ 11244 function enqueueRemove(parentID, fromIndex) { 11245 // NOTE: Null values reduce hidden classes. 11246 updateQueue.push({ 11247 parentID: parentID, 11248 parentNode: null, 11249 type: ReactMultiChildUpdateTypes.REMOVE_NODE, 11250 markupIndex: null, 11251 textContent: null, 11252 fromIndex: fromIndex, 11253 toIndex: null 11254 }); 11255 } 11256 11257 /** 11258 * Enqueues setting the text content. 11259 * 11260 * @param {string} parentID ID of the parent component. 11261 * @param {string} textContent Text content to set. 11262 * @private 11263 */ 11264 function enqueueTextContent(parentID, textContent) { 11265 // NOTE: Null values reduce hidden classes. 11266 updateQueue.push({ 11267 parentID: parentID, 11268 parentNode: null, 11269 type: ReactMultiChildUpdateTypes.TEXT_CONTENT, 11270 markupIndex: null, 11271 textContent: textContent, 11272 fromIndex: null, 11273 toIndex: null 11274 }); 11275 } 11276 11277 /** 11278 * Processes any enqueued updates. 11279 * 11280 * @private 11281 */ 11282 function processQueue() { 11283 if (updateQueue.length) { 11284 ReactComponent.BackendIDOperations.dangerouslyProcessChildrenUpdates( 11285 updateQueue, 11286 markupQueue 11287 ); 11288 clearQueue(); 11289 } 11290 } 11291 11292 /** 11293 * Clears any enqueued updates. 11294 * 11295 * @private 11296 */ 11297 function clearQueue() { 11298 updateQueue.length = 0; 11299 markupQueue.length = 0; 11300 } 11301 11302 /** 11303 * ReactMultiChild are capable of reconciling multiple children. 11304 * 11305 * @class ReactMultiChild 11306 * @internal 11307 */ 11308 var ReactMultiChild = { 11309 11310 /** 11311 * Provides common functionality for components that must reconcile multiple 11312 * children. This is used by `ReactDOMComponent` to mount, update, and 11313 * unmount child components. 11314 * 11315 * @lends {ReactMultiChild.prototype} 11316 */ 11317 Mixin: { 11318 11319 /** 11320 * Generates a "mount image" for each of the supplied children. In the case 11321 * of `ReactDOMComponent`, a mount image is a string of markup. 11322 * 11323 * @param {?object} nestedChildren Nested child maps. 11324 * @return {array} An array of mounted representations. 11325 * @internal 11326 */ 11327 mountChildren: function(nestedChildren, transaction) { 11328 var children = flattenChildren(nestedChildren); 11329 var mountImages = []; 11330 var index = 0; 11331 this._renderedChildren = children; 11332 for (var name in children) { 11333 var child = children[name]; 11334 if (children.hasOwnProperty(name)) { 11335 // The rendered children must be turned into instances as they're 11336 // mounted. 11337 var childInstance = instantiateReactComponent(child); 11338 children[name] = childInstance; 11339 // Inlined for performance, see `ReactInstanceHandles.createReactID`. 11340 var rootID = this._rootNodeID + name; 11341 var mountImage = childInstance.mountComponent( 11342 rootID, 11343 transaction, 11344 this._mountDepth + 1 11345 ); 11346 childInstance._mountIndex = index; 11347 mountImages.push(mountImage); 11348 index++; 11349 } 11350 } 11351 return mountImages; 11352 }, 11353 11354 /** 11355 * Replaces any rendered children with a text content string. 11356 * 11357 * @param {string} nextContent String of content. 11358 * @internal 11359 */ 11360 updateTextContent: function(nextContent) { 11361 updateDepth++; 11362 var errorThrown = true; 11363 try { 11364 var prevChildren = this._renderedChildren; 11365 // Remove any rendered children. 11366 for (var name in prevChildren) { 11367 if (prevChildren.hasOwnProperty(name)) { 11368 this._unmountChildByName(prevChildren[name], name); 11369 } 11370 } 11371 // Set new text content. 11372 this.setTextContent(nextContent); 11373 errorThrown = false; 11374 } finally { 11375 updateDepth--; 11376 if (!updateDepth) { 11377 errorThrown ? clearQueue() : processQueue(); 11378 } 11379 } 11380 }, 11381 11382 /** 11383 * Updates the rendered children with new children. 11384 * 11385 * @param {?object} nextNestedChildren Nested child maps. 11386 * @param {ReactReconcileTransaction} transaction 11387 * @internal 11388 */ 11389 updateChildren: function(nextNestedChildren, transaction) { 11390 updateDepth++; 11391 var errorThrown = true; 11392 try { 11393 this._updateChildren(nextNestedChildren, transaction); 11394 errorThrown = false; 11395 } finally { 11396 updateDepth--; 11397 if (!updateDepth) { 11398 errorThrown ? clearQueue() : processQueue(); 11399 } 11400 } 11401 }, 11402 11403 /** 11404 * Improve performance by isolating this hot code path from the try/catch 11405 * block in `updateChildren`. 11406 * 11407 * @param {?object} nextNestedChildren Nested child maps. 11408 * @param {ReactReconcileTransaction} transaction 11409 * @final 11410 * @protected 11411 */ 11412 _updateChildren: function(nextNestedChildren, transaction) { 11413 var nextChildren = flattenChildren(nextNestedChildren); 11414 var prevChildren = this._renderedChildren; 11415 if (!nextChildren && !prevChildren) { 11416 return; 11417 } 11418 var name; 11419 // `nextIndex` will increment for each child in `nextChildren`, but 11420 // `lastIndex` will be the last index visited in `prevChildren`. 11421 var lastIndex = 0; 11422 var nextIndex = 0; 11423 for (name in nextChildren) { 11424 if (!nextChildren.hasOwnProperty(name)) { 11425 continue; 11426 } 11427 var prevChild = prevChildren && prevChildren[name]; 11428 var nextChild = nextChildren[name]; 11429 if (shouldUpdateReactComponent(prevChild, nextChild)) { 11430 this.moveChild(prevChild, nextIndex, lastIndex); 11431 lastIndex = Math.max(prevChild._mountIndex, lastIndex); 11432 prevChild.receiveComponent(nextChild, transaction); 11433 prevChild._mountIndex = nextIndex; 11434 } else { 11435 if (prevChild) { 11436 // Update `lastIndex` before `_mountIndex` gets unset by unmounting. 11437 lastIndex = Math.max(prevChild._mountIndex, lastIndex); 11438 this._unmountChildByName(prevChild, name); 11439 } 11440 // The child must be instantiated before it's mounted. 11441 var nextChildInstance = instantiateReactComponent(nextChild); 11442 this._mountChildByNameAtIndex( 11443 nextChildInstance, name, nextIndex, transaction 11444 ); 11445 } 11446 nextIndex++; 11447 } 11448 // Remove children that are no longer present. 11449 for (name in prevChildren) { 11450 if (prevChildren.hasOwnProperty(name) && 11451 !(nextChildren && nextChildren[name])) { 11452 this._unmountChildByName(prevChildren[name], name); 11453 } 11454 } 11455 }, 11456 11457 /** 11458 * Unmounts all rendered children. This should be used to clean up children 11459 * when this component is unmounted. 11460 * 11461 * @internal 11462 */ 11463 unmountChildren: function() { 11464 var renderedChildren = this._renderedChildren; 11465 for (var name in renderedChildren) { 11466 var renderedChild = renderedChildren[name]; 11467 // TODO: When is this not true? 11468 if (renderedChild.unmountComponent) { 11469 renderedChild.unmountComponent(); 11470 } 11471 } 11472 this._renderedChildren = null; 11473 }, 11474 11475 /** 11476 * Moves a child component to the supplied index. 11477 * 11478 * @param {ReactComponent} child Component to move. 11479 * @param {number} toIndex Destination index of the element. 11480 * @param {number} lastIndex Last index visited of the siblings of `child`. 11481 * @protected 11482 */ 11483 moveChild: function(child, toIndex, lastIndex) { 11484 // If the index of `child` is less than `lastIndex`, then it needs to 11485 // be moved. Otherwise, we do not need to move it because a child will be 11486 // inserted or moved before `child`. 11487 if (child._mountIndex < lastIndex) { 11488 enqueueMove(this._rootNodeID, child._mountIndex, toIndex); 11489 } 11490 }, 11491 11492 /** 11493 * Creates a child component. 11494 * 11495 * @param {ReactComponent} child Component to create. 11496 * @param {string} mountImage Markup to insert. 11497 * @protected 11498 */ 11499 createChild: function(child, mountImage) { 11500 enqueueMarkup(this._rootNodeID, mountImage, child._mountIndex); 11501 }, 11502 11503 /** 11504 * Removes a child component. 11505 * 11506 * @param {ReactComponent} child Child to remove. 11507 * @protected 11508 */ 11509 removeChild: function(child) { 11510 enqueueRemove(this._rootNodeID, child._mountIndex); 11511 }, 11512 11513 /** 11514 * Sets this text content string. 11515 * 11516 * @param {string} textContent Text content to set. 11517 * @protected 11518 */ 11519 setTextContent: function(textContent) { 11520 enqueueTextContent(this._rootNodeID, textContent); 11521 }, 11522 11523 /** 11524 * Mounts a child with the supplied name. 11525 * 11526 * NOTE: This is part of `updateChildren` and is here for readability. 11527 * 11528 * @param {ReactComponent} child Component to mount. 11529 * @param {string} name Name of the child. 11530 * @param {number} index Index at which to insert the child. 11531 * @param {ReactReconcileTransaction} transaction 11532 * @private 11533 */ 11534 _mountChildByNameAtIndex: function(child, name, index, transaction) { 11535 // Inlined for performance, see `ReactInstanceHandles.createReactID`. 11536 var rootID = this._rootNodeID + name; 11537 var mountImage = child.mountComponent( 11538 rootID, 11539 transaction, 11540 this._mountDepth + 1 11541 ); 11542 child._mountIndex = index; 11543 this.createChild(child, mountImage); 11544 this._renderedChildren = this._renderedChildren || {}; 11545 this._renderedChildren[name] = child; 11546 }, 11547 11548 /** 11549 * Unmounts a rendered child by name. 11550 * 11551 * NOTE: This is part of `updateChildren` and is here for readability. 11552 * 11553 * @param {ReactComponent} child Component to unmount. 11554 * @param {string} name Name of the child in `this._renderedChildren`. 11555 * @private 11556 */ 11557 _unmountChildByName: function(child, name) { 11558 // TODO: When is this not true? 11559 if (ReactComponent.isValidComponent(child)) { 11560 this.removeChild(child); 11561 child._mountIndex = null; 11562 child.unmountComponent(); 11563 delete this._renderedChildren[name]; 11564 } 11565 } 11566 11567 } 11568 11569 }; 11570 11571 module.exports = ReactMultiChild; 11572 11573 },{"./ReactComponent":31,"./ReactMultiChildUpdateTypes":63,"./flattenChildren":112,"./instantiateReactComponent":124,"./shouldUpdateReactComponent":144}],63:[function(_dereq_,module,exports){ 11574 /** 11575 * Copyright 2013-2014 Facebook, Inc. 11576 * 11577 * Licensed under the Apache License, Version 2.0 (the "License"); 11578 * you may not use this file except in compliance with the License. 11579 * You may obtain a copy of the License at 11580 * 11581 * http://www.apache.org/licenses/LICENSE-2.0 11582 * 11583 * Unless required by applicable law or agreed to in writing, software 11584 * distributed under the License is distributed on an "AS IS" BASIS, 11585 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11586 * See the License for the specific language governing permissions and 11587 * limitations under the License. 11588 * 11589 * @providesModule ReactMultiChildUpdateTypes 11590 */ 11591 11592 "use strict"; 11593 11594 var keyMirror = _dereq_("./keyMirror"); 11595 11596 /** 11597 * When a component's children are updated, a series of update configuration 11598 * objects are created in order to batch and serialize the required changes. 11599 * 11600 * Enumerates all the possible types of update configurations. 11601 * 11602 * @internal 11603 */ 11604 var ReactMultiChildUpdateTypes = keyMirror({ 11605 INSERT_MARKUP: null, 11606 MOVE_EXISTING: null, 11607 REMOVE_NODE: null, 11608 TEXT_CONTENT: null 11609 }); 11610 11611 module.exports = ReactMultiChildUpdateTypes; 11612 11613 },{"./keyMirror":131}],64:[function(_dereq_,module,exports){ 11614 /** 11615 * Copyright 2013-2014 Facebook, Inc. 11616 * 11617 * Licensed under the Apache License, Version 2.0 (the "License"); 11618 * you may not use this file except in compliance with the License. 11619 * You may obtain a copy of the License at 11620 * 11621 * http://www.apache.org/licenses/LICENSE-2.0 11622 * 11623 * Unless required by applicable law or agreed to in writing, software 11624 * distributed under the License is distributed on an "AS IS" BASIS, 11625 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11626 * See the License for the specific language governing permissions and 11627 * limitations under the License. 11628 * 11629 * @providesModule ReactOwner 11630 */ 11631 11632 "use strict"; 11633 11634 var emptyObject = _dereq_("./emptyObject"); 11635 var invariant = _dereq_("./invariant"); 11636 11637 /** 11638 * ReactOwners are capable of storing references to owned components. 11639 * 11640 * All components are capable of //being// referenced by owner components, but 11641 * only ReactOwner components are capable of //referencing// owned components. 11642 * The named reference is known as a "ref". 11643 * 11644 * Refs are available when mounted and updated during reconciliation. 11645 * 11646 * var MyComponent = React.createClass({ 11647 * render: function() { 11648 * return ( 11649 * <div onClick={this.handleClick}> 11650 * <CustomComponent ref="custom" /> 11651 * </div> 11652 * ); 11653 * }, 11654 * handleClick: function() { 11655 * this.refs.custom.handleClick(); 11656 * }, 11657 * componentDidMount: function() { 11658 * this.refs.custom.initialize(); 11659 * } 11660 * }); 11661 * 11662 * Refs should rarely be used. When refs are used, they should only be done to 11663 * control data that is not handled by React's data flow. 11664 * 11665 * @class ReactOwner 11666 */ 11667 var ReactOwner = { 11668 11669 /** 11670 * @param {?object} object 11671 * @return {boolean} True if `object` is a valid owner. 11672 * @final 11673 */ 11674 isValidOwner: function(object) { 11675 return !!( 11676 object && 11677 typeof object.attachRef === 'function' && 11678 typeof object.detachRef === 'function' 11679 ); 11680 }, 11681 11682 /** 11683 * Adds a component by ref to an owner component. 11684 * 11685 * @param {ReactComponent} component Component to reference. 11686 * @param {string} ref Name by which to refer to the component. 11687 * @param {ReactOwner} owner Component on which to record the ref. 11688 * @final 11689 * @internal 11690 */ 11691 addComponentAsRefTo: function(component, ref, owner) { 11692 ("production" !== "development" ? invariant( 11693 ReactOwner.isValidOwner(owner), 11694 'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' + 11695 'usually means that you\'re trying to add a ref to a component that ' + 11696 'doesn\'t have an owner (that is, was not created inside of another ' + 11697 'component\'s `render` method). Try rendering this component inside of ' + 11698 'a new top-level component which will hold the ref.' 11699 ) : invariant(ReactOwner.isValidOwner(owner))); 11700 owner.attachRef(ref, component); 11701 }, 11702 11703 /** 11704 * Removes a component by ref from an owner component. 11705 * 11706 * @param {ReactComponent} component Component to dereference. 11707 * @param {string} ref Name of the ref to remove. 11708 * @param {ReactOwner} owner Component on which the ref is recorded. 11709 * @final 11710 * @internal 11711 */ 11712 removeComponentAsRefFrom: function(component, ref, owner) { 11713 ("production" !== "development" ? invariant( 11714 ReactOwner.isValidOwner(owner), 11715 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' + 11716 'usually means that you\'re trying to remove a ref to a component that ' + 11717 'doesn\'t have an owner (that is, was not created inside of another ' + 11718 'component\'s `render` method). Try rendering this component inside of ' + 11719 'a new top-level component which will hold the ref.' 11720 ) : invariant(ReactOwner.isValidOwner(owner))); 11721 // Check that `component` is still the current ref because we do not want to 11722 // detach the ref if another component stole it. 11723 if (owner.refs[ref] === component) { 11724 owner.detachRef(ref); 11725 } 11726 }, 11727 11728 /** 11729 * A ReactComponent must mix this in to have refs. 11730 * 11731 * @lends {ReactOwner.prototype} 11732 */ 11733 Mixin: { 11734 11735 construct: function() { 11736 this.refs = emptyObject; 11737 }, 11738 11739 /** 11740 * Lazily allocates the refs object and stores `component` as `ref`. 11741 * 11742 * @param {string} ref Reference name. 11743 * @param {component} component Component to store as `ref`. 11744 * @final 11745 * @private 11746 */ 11747 attachRef: function(ref, component) { 11748 ("production" !== "development" ? invariant( 11749 component.isOwnedBy(this), 11750 'attachRef(%s, ...): Only a component\'s owner can store a ref to it.', 11751 ref 11752 ) : invariant(component.isOwnedBy(this))); 11753 var refs = this.refs === emptyObject ? (this.refs = {}) : this.refs; 11754 refs[ref] = component; 11755 }, 11756 11757 /** 11758 * Detaches a reference name. 11759 * 11760 * @param {string} ref Name to dereference. 11761 * @final 11762 * @private 11763 */ 11764 detachRef: function(ref) { 11765 delete this.refs[ref]; 11766 } 11767 11768 } 11769 11770 }; 11771 11772 module.exports = ReactOwner; 11773 11774 },{"./emptyObject":110,"./invariant":125}],65:[function(_dereq_,module,exports){ 11775 /** 11776 * Copyright 2013-2014 Facebook, Inc. 11777 * 11778 * Licensed under the Apache License, Version 2.0 (the "License"); 11779 * you may not use this file except in compliance with the License. 11780 * You may obtain a copy of the License at 11781 * 11782 * http://www.apache.org/licenses/LICENSE-2.0 11783 * 11784 * Unless required by applicable law or agreed to in writing, software 11785 * distributed under the License is distributed on an "AS IS" BASIS, 11786 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11787 * See the License for the specific language governing permissions and 11788 * limitations under the License. 11789 * 11790 * @providesModule ReactPerf 11791 * @typechecks static-only 11792 */ 11793 11794 "use strict"; 11795 11796 /** 11797 * ReactPerf is a general AOP system designed to measure performance. This 11798 * module only has the hooks: see ReactDefaultPerf for the analysis tool. 11799 */ 11800 var ReactPerf = { 11801 /** 11802 * Boolean to enable/disable measurement. Set to false by default to prevent 11803 * accidental logging and perf loss. 11804 */ 11805 enableMeasure: false, 11806 11807 /** 11808 * Holds onto the measure function in use. By default, don't measure 11809 * anything, but we'll override this if we inject a measure function. 11810 */ 11811 storedMeasure: _noMeasure, 11812 11813 /** 11814 * Use this to wrap methods you want to measure. Zero overhead in production. 11815 * 11816 * @param {string} objName 11817 * @param {string} fnName 11818 * @param {function} func 11819 * @return {function} 11820 */ 11821 measure: function(objName, fnName, func) { 11822 if ("production" !== "development") { 11823 var measuredFunc = null; 11824 return function() { 11825 if (ReactPerf.enableMeasure) { 11826 if (!measuredFunc) { 11827 measuredFunc = ReactPerf.storedMeasure(objName, fnName, func); 11828 } 11829 return measuredFunc.apply(this, arguments); 11830 } 11831 return func.apply(this, arguments); 11832 }; 11833 } 11834 return func; 11835 }, 11836 11837 injection: { 11838 /** 11839 * @param {function} measure 11840 */ 11841 injectMeasure: function(measure) { 11842 ReactPerf.storedMeasure = measure; 11843 } 11844 } 11845 }; 11846 11847 /** 11848 * Simply passes through the measured function, without measuring it. 11849 * 11850 * @param {string} objName 11851 * @param {string} fnName 11852 * @param {function} func 11853 * @return {function} 11854 */ 11855 function _noMeasure(objName, fnName, func) { 11856 return func; 11857 } 11858 11859 module.exports = ReactPerf; 11860 11861 },{}],66:[function(_dereq_,module,exports){ 11862 /** 11863 * Copyright 2013-2014 Facebook, Inc. 11864 * 11865 * Licensed under the Apache License, Version 2.0 (the "License"); 11866 * you may not use this file except in compliance with the License. 11867 * You may obtain a copy of the License at 11868 * 11869 * http://www.apache.org/licenses/LICENSE-2.0 11870 * 11871 * Unless required by applicable law or agreed to in writing, software 11872 * distributed under the License is distributed on an "AS IS" BASIS, 11873 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11874 * See the License for the specific language governing permissions and 11875 * limitations under the License. 11876 * 11877 * @providesModule ReactPropTransferer 11878 */ 11879 11880 "use strict"; 11881 11882 var emptyFunction = _dereq_("./emptyFunction"); 11883 var invariant = _dereq_("./invariant"); 11884 var joinClasses = _dereq_("./joinClasses"); 11885 var merge = _dereq_("./merge"); 11886 11887 /** 11888 * Creates a transfer strategy that will merge prop values using the supplied 11889 * `mergeStrategy`. If a prop was previously unset, this just sets it. 11890 * 11891 * @param {function} mergeStrategy 11892 * @return {function} 11893 */ 11894 function createTransferStrategy(mergeStrategy) { 11895 return function(props, key, value) { 11896 if (!props.hasOwnProperty(key)) { 11897 props[key] = value; 11898 } else { 11899 props[key] = mergeStrategy(props[key], value); 11900 } 11901 }; 11902 } 11903 11904 /** 11905 * Transfer strategies dictate how props are transferred by `transferPropsTo`. 11906 * NOTE: if you add any more exceptions to this list you should be sure to 11907 * update `cloneWithProps()` accordingly. 11908 */ 11909 var TransferStrategies = { 11910 /** 11911 * Never transfer `children`. 11912 */ 11913 children: emptyFunction, 11914 /** 11915 * Transfer the `className` prop by merging them. 11916 */ 11917 className: createTransferStrategy(joinClasses), 11918 /** 11919 * Never transfer the `key` prop. 11920 */ 11921 key: emptyFunction, 11922 /** 11923 * Never transfer the `ref` prop. 11924 */ 11925 ref: emptyFunction, 11926 /** 11927 * Transfer the `style` prop (which is an object) by merging them. 11928 */ 11929 style: createTransferStrategy(merge) 11930 }; 11931 11932 /** 11933 * ReactPropTransferer are capable of transferring props to another component 11934 * using a `transferPropsTo` method. 11935 * 11936 * @class ReactPropTransferer 11937 */ 11938 var ReactPropTransferer = { 11939 11940 TransferStrategies: TransferStrategies, 11941 11942 /** 11943 * Merge two props objects using TransferStrategies. 11944 * 11945 * @param {object} oldProps original props (they take precedence) 11946 * @param {object} newProps new props to merge in 11947 * @return {object} a new object containing both sets of props merged. 11948 */ 11949 mergeProps: function(oldProps, newProps) { 11950 var props = merge(oldProps); 11951 11952 for (var thisKey in newProps) { 11953 if (!newProps.hasOwnProperty(thisKey)) { 11954 continue; 11955 } 11956 11957 var transferStrategy = TransferStrategies[thisKey]; 11958 11959 if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { 11960 transferStrategy(props, thisKey, newProps[thisKey]); 11961 } else if (!props.hasOwnProperty(thisKey)) { 11962 props[thisKey] = newProps[thisKey]; 11963 } 11964 } 11965 11966 return props; 11967 }, 11968 11969 /** 11970 * @lends {ReactPropTransferer.prototype} 11971 */ 11972 Mixin: { 11973 11974 /** 11975 * Transfer props from this component to a target component. 11976 * 11977 * Props that do not have an explicit transfer strategy will be transferred 11978 * only if the target component does not already have the prop set. 11979 * 11980 * This is usually used to pass down props to a returned root component. 11981 * 11982 * @param {ReactComponent} component Component receiving the properties. 11983 * @return {ReactComponent} The supplied `component`. 11984 * @final 11985 * @protected 11986 */ 11987 transferPropsTo: function(component) { 11988 ("production" !== "development" ? invariant( 11989 component._owner === this, 11990 '%s: You can\'t call transferPropsTo() on a component that you ' + 11991 'don\'t own, %s. This usually means you are calling ' + 11992 'transferPropsTo() on a component passed in as props or children.', 11993 this.constructor.displayName, 11994 component.constructor.displayName 11995 ) : invariant(component._owner === this)); 11996 11997 component.props = ReactPropTransferer.mergeProps( 11998 component.props, 11999 this.props 12000 ); 12001 12002 return component; 12003 } 12004 12005 } 12006 }; 12007 12008 module.exports = ReactPropTransferer; 12009 12010 },{"./emptyFunction":109,"./invariant":125,"./joinClasses":130,"./merge":134}],67:[function(_dereq_,module,exports){ 12011 /** 12012 * Copyright 2013-2014 Facebook, Inc. 12013 * 12014 * Licensed under the Apache License, Version 2.0 (the "License"); 12015 * you may not use this file except in compliance with the License. 12016 * You may obtain a copy of the License at 12017 * 12018 * http://www.apache.org/licenses/LICENSE-2.0 12019 * 12020 * Unless required by applicable law or agreed to in writing, software 12021 * distributed under the License is distributed on an "AS IS" BASIS, 12022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12023 * See the License for the specific language governing permissions and 12024 * limitations under the License. 12025 * 12026 * @providesModule ReactPropTypeLocationNames 12027 */ 12028 12029 "use strict"; 12030 12031 var ReactPropTypeLocationNames = {}; 12032 12033 if ("production" !== "development") { 12034 ReactPropTypeLocationNames = { 12035 prop: 'prop', 12036 context: 'context', 12037 childContext: 'child context' 12038 }; 12039 } 12040 12041 module.exports = ReactPropTypeLocationNames; 12042 12043 },{}],68:[function(_dereq_,module,exports){ 12044 /** 12045 * Copyright 2013-2014 Facebook, Inc. 12046 * 12047 * Licensed under the Apache License, Version 2.0 (the "License"); 12048 * you may not use this file except in compliance with the License. 12049 * You may obtain a copy of the License at 12050 * 12051 * http://www.apache.org/licenses/LICENSE-2.0 12052 * 12053 * Unless required by applicable law or agreed to in writing, software 12054 * distributed under the License is distributed on an "AS IS" BASIS, 12055 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12056 * See the License for the specific language governing permissions and 12057 * limitations under the License. 12058 * 12059 * @providesModule ReactPropTypeLocations 12060 */ 12061 12062 "use strict"; 12063 12064 var keyMirror = _dereq_("./keyMirror"); 12065 12066 var ReactPropTypeLocations = keyMirror({ 12067 prop: null, 12068 context: null, 12069 childContext: null 12070 }); 12071 12072 module.exports = ReactPropTypeLocations; 12073 12074 },{"./keyMirror":131}],69:[function(_dereq_,module,exports){ 12075 /** 12076 * Copyright 2013-2014 Facebook, Inc. 12077 * 12078 * Licensed under the Apache License, Version 2.0 (the "License"); 12079 * you may not use this file except in compliance with the License. 12080 * You may obtain a copy of the License at 12081 * 12082 * http://www.apache.org/licenses/LICENSE-2.0 12083 * 12084 * Unless required by applicable law or agreed to in writing, software 12085 * distributed under the License is distributed on an "AS IS" BASIS, 12086 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12087 * See the License for the specific language governing permissions and 12088 * limitations under the License. 12089 * 12090 * @providesModule ReactPropTypes 12091 */ 12092 12093 "use strict"; 12094 12095 var ReactComponent = _dereq_("./ReactComponent"); 12096 var ReactPropTypeLocationNames = _dereq_("./ReactPropTypeLocationNames"); 12097 12098 var warning = _dereq_("./warning"); 12099 var createObjectFrom = _dereq_("./createObjectFrom"); 12100 12101 /** 12102 * Collection of methods that allow declaration and validation of props that are 12103 * supplied to React components. Example usage: 12104 * 12105 * var Props = require('ReactPropTypes'); 12106 * var MyArticle = React.createClass({ 12107 * propTypes: { 12108 * // An optional string prop named "description". 12109 * description: Props.string, 12110 * 12111 * // A required enum prop named "category". 12112 * category: Props.oneOf(['News','Photos']).isRequired, 12113 * 12114 * // A prop named "dialog" that requires an instance of Dialog. 12115 * dialog: Props.instanceOf(Dialog).isRequired 12116 * }, 12117 * render: function() { ... } 12118 * }); 12119 * 12120 * A more formal specification of how these methods are used: 12121 * 12122 * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) 12123 * decl := ReactPropTypes.{type}(.isRequired)? 12124 * 12125 * Each and every declaration produces a function with the same signature. This 12126 * allows the creation of custom validation functions. For example: 12127 * 12128 * var Props = require('ReactPropTypes'); 12129 * var MyLink = React.createClass({ 12130 * propTypes: { 12131 * // An optional string or URI prop named "href". 12132 * href: function(props, propName, componentName) { 12133 * var propValue = props[propName]; 12134 * warning( 12135 * propValue == null || 12136 * typeof propValue === 'string' || 12137 * propValue instanceof URI, 12138 * 'Invalid `%s` supplied to `%s`, expected string or URI.', 12139 * propName, 12140 * componentName 12141 * ); 12142 * } 12143 * }, 12144 * render: function() { ... } 12145 * }); 12146 * 12147 * @internal 12148 */ 12149 var Props = { 12150 12151 array: createPrimitiveTypeChecker('array'), 12152 bool: createPrimitiveTypeChecker('boolean'), 12153 func: createPrimitiveTypeChecker('function'), 12154 number: createPrimitiveTypeChecker('number'), 12155 object: createPrimitiveTypeChecker('object'), 12156 string: createPrimitiveTypeChecker('string'), 12157 12158 shape: createShapeTypeChecker, 12159 oneOf: createEnumTypeChecker, 12160 oneOfType: createUnionTypeChecker, 12161 arrayOf: createArrayOfTypeChecker, 12162 12163 instanceOf: createInstanceTypeChecker, 12164 12165 renderable: createRenderableTypeChecker(), 12166 12167 component: createComponentTypeChecker(), 12168 12169 any: createAnyTypeChecker() 12170 }; 12171 12172 var ANONYMOUS = '<<anonymous>>'; 12173 12174 function isRenderable(propValue) { 12175 switch(typeof propValue) { 12176 case 'number': 12177 case 'string': 12178 return true; 12179 case 'object': 12180 if (Array.isArray(propValue)) { 12181 return propValue.every(isRenderable); 12182 } 12183 if (ReactComponent.isValidComponent(propValue)) { 12184 return true; 12185 } 12186 for (var k in propValue) { 12187 if (!isRenderable(propValue[k])) { 12188 return false; 12189 } 12190 } 12191 return true; 12192 default: 12193 return false; 12194 } 12195 } 12196 12197 // Equivalent of typeof but with special handling for arrays 12198 function getPropType(propValue) { 12199 var propType = typeof propValue; 12200 if (propType === 'object' && Array.isArray(propValue)) { 12201 return 'array'; 12202 } 12203 return propType; 12204 } 12205 12206 function createAnyTypeChecker() { 12207 function validateAnyType( 12208 shouldWarn, propValue, propName, componentName, location 12209 ) { 12210 return true; // is always valid 12211 } 12212 return createChainableTypeChecker(validateAnyType); 12213 } 12214 12215 function createPrimitiveTypeChecker(expectedType) { 12216 function validatePrimitiveType( 12217 shouldWarn, propValue, propName, componentName, location 12218 ) { 12219 var propType = getPropType(propValue); 12220 var isValid = propType === expectedType; 12221 if (shouldWarn) { 12222 ("production" !== "development" ? warning( 12223 isValid, 12224 'Invalid %s `%s` of type `%s` supplied to `%s`, expected `%s`.', 12225 ReactPropTypeLocationNames[location], 12226 propName, 12227 propType, 12228 componentName, 12229 expectedType 12230 ) : null); 12231 } 12232 return isValid; 12233 } 12234 return createChainableTypeChecker(validatePrimitiveType); 12235 } 12236 12237 function createEnumTypeChecker(expectedValues) { 12238 var expectedEnum = createObjectFrom(expectedValues); 12239 function validateEnumType( 12240 shouldWarn, propValue, propName, componentName, location 12241 ) { 12242 var isValid = expectedEnum[propValue]; 12243 if (shouldWarn) { 12244 ("production" !== "development" ? warning( 12245 isValid, 12246 'Invalid %s `%s` supplied to `%s`, expected one of %s.', 12247 ReactPropTypeLocationNames[location], 12248 propName, 12249 componentName, 12250 JSON.stringify(Object.keys(expectedEnum)) 12251 ) : null); 12252 } 12253 return isValid; 12254 } 12255 return createChainableTypeChecker(validateEnumType); 12256 } 12257 12258 function createShapeTypeChecker(shapeTypes) { 12259 function validateShapeType( 12260 shouldWarn, propValue, propName, componentName, location 12261 ) { 12262 var propType = getPropType(propValue); 12263 var isValid = propType === 'object'; 12264 if (isValid) { 12265 for (var key in shapeTypes) { 12266 var checker = shapeTypes[key]; 12267 if (checker && !checker(propValue, key, componentName, location)) { 12268 return false; 12269 } 12270 } 12271 } 12272 if (shouldWarn) { 12273 ("production" !== "development" ? warning( 12274 isValid, 12275 'Invalid %s `%s` of type `%s` supplied to `%s`, expected `object`.', 12276 ReactPropTypeLocationNames[location], 12277 propName, 12278 propType, 12279 componentName 12280 ) : null); 12281 } 12282 return isValid; 12283 } 12284 return createChainableTypeChecker(validateShapeType); 12285 } 12286 12287 function createInstanceTypeChecker(expectedClass) { 12288 function validateInstanceType( 12289 shouldWarn, propValue, propName, componentName, location 12290 ) { 12291 var isValid = propValue instanceof expectedClass; 12292 if (shouldWarn) { 12293 ("production" !== "development" ? warning( 12294 isValid, 12295 'Invalid %s `%s` supplied to `%s`, expected instance of `%s`.', 12296 ReactPropTypeLocationNames[location], 12297 propName, 12298 componentName, 12299 expectedClass.name || ANONYMOUS 12300 ) : null); 12301 } 12302 return isValid; 12303 } 12304 return createChainableTypeChecker(validateInstanceType); 12305 } 12306 12307 function createArrayOfTypeChecker(propTypeChecker) { 12308 function validateArrayType( 12309 shouldWarn, propValue, propName, componentName, location 12310 ) { 12311 var isValid = Array.isArray(propValue); 12312 if (isValid) { 12313 for (var i = 0; i < propValue.length; i++) { 12314 if (!propTypeChecker(propValue, i, componentName, location)) { 12315 return false; 12316 } 12317 } 12318 } 12319 if (shouldWarn) { 12320 ("production" !== "development" ? warning( 12321 isValid, 12322 'Invalid %s `%s` supplied to `%s`, expected an array.', 12323 ReactPropTypeLocationNames[location], 12324 propName, 12325 componentName 12326 ) : null); 12327 } 12328 return isValid; 12329 } 12330 return createChainableTypeChecker(validateArrayType); 12331 } 12332 12333 function createRenderableTypeChecker() { 12334 function validateRenderableType( 12335 shouldWarn, propValue, propName, componentName, location 12336 ) { 12337 var isValid = isRenderable(propValue); 12338 if (shouldWarn) { 12339 ("production" !== "development" ? warning( 12340 isValid, 12341 'Invalid %s `%s` supplied to `%s`, expected a renderable prop.', 12342 ReactPropTypeLocationNames[location], 12343 propName, 12344 componentName 12345 ) : null); 12346 } 12347 return isValid; 12348 } 12349 return createChainableTypeChecker(validateRenderableType); 12350 } 12351 12352 function createComponentTypeChecker() { 12353 function validateComponentType( 12354 shouldWarn, propValue, propName, componentName, location 12355 ) { 12356 var isValid = ReactComponent.isValidComponent(propValue); 12357 if (shouldWarn) { 12358 ("production" !== "development" ? warning( 12359 isValid, 12360 'Invalid %s `%s` supplied to `%s`, expected a React component.', 12361 ReactPropTypeLocationNames[location], 12362 propName, 12363 componentName 12364 ) : null); 12365 } 12366 return isValid; 12367 } 12368 return createChainableTypeChecker(validateComponentType); 12369 } 12370 12371 function createUnionTypeChecker(arrayOfValidators) { 12372 return function(props, propName, componentName, location) { 12373 var isValid = false; 12374 for (var ii = 0; ii < arrayOfValidators.length; ii++) { 12375 var validate = arrayOfValidators[ii]; 12376 if (typeof validate.weak === 'function') { 12377 validate = validate.weak; 12378 } 12379 if (validate(props, propName, componentName, location)) { 12380 isValid = true; 12381 break; 12382 } 12383 } 12384 ("production" !== "development" ? warning( 12385 isValid, 12386 'Invalid %s `%s` supplied to `%s`.', 12387 ReactPropTypeLocationNames[location], 12388 propName, 12389 componentName || ANONYMOUS 12390 ) : null); 12391 return isValid; 12392 }; 12393 } 12394 12395 function createChainableTypeChecker(validate) { 12396 function checkType( 12397 isRequired, shouldWarn, props, propName, componentName, location 12398 ) { 12399 var propValue = props[propName]; 12400 if (propValue != null) { 12401 // Only validate if there is a value to check. 12402 return validate( 12403 shouldWarn, 12404 propValue, 12405 propName, 12406 componentName || ANONYMOUS, 12407 location 12408 ); 12409 } else { 12410 var isValid = !isRequired; 12411 if (shouldWarn) { 12412 ("production" !== "development" ? warning( 12413 isValid, 12414 'Required %s `%s` was not specified in `%s`.', 12415 ReactPropTypeLocationNames[location], 12416 propName, 12417 componentName || ANONYMOUS 12418 ) : null); 12419 } 12420 return isValid; 12421 } 12422 } 12423 12424 var checker = checkType.bind(null, false, true); 12425 checker.weak = checkType.bind(null, false, false); 12426 checker.isRequired = checkType.bind(null, true, true); 12427 checker.weak.isRequired = checkType.bind(null, true, false); 12428 checker.isRequired.weak = checker.weak.isRequired; 12429 12430 return checker; 12431 } 12432 12433 module.exports = Props; 12434 12435 },{"./ReactComponent":31,"./ReactPropTypeLocationNames":67,"./createObjectFrom":106,"./warning":148}],70:[function(_dereq_,module,exports){ 12436 /** 12437 * Copyright 2013-2014 Facebook, Inc. 12438 * 12439 * Licensed under the Apache License, Version 2.0 (the "License"); 12440 * you may not use this file except in compliance with the License. 12441 * You may obtain a copy of the License at 12442 * 12443 * http://www.apache.org/licenses/LICENSE-2.0 12444 * 12445 * Unless required by applicable law or agreed to in writing, software 12446 * distributed under the License is distributed on an "AS IS" BASIS, 12447 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12448 * See the License for the specific language governing permissions and 12449 * limitations under the License. 12450 * 12451 * @providesModule ReactPutListenerQueue 12452 */ 12453 12454 "use strict"; 12455 12456 var PooledClass = _dereq_("./PooledClass"); 12457 var ReactEventEmitter = _dereq_("./ReactEventEmitter"); 12458 12459 var mixInto = _dereq_("./mixInto"); 12460 12461 function ReactPutListenerQueue() { 12462 this.listenersToPut = []; 12463 } 12464 12465 mixInto(ReactPutListenerQueue, { 12466 enqueuePutListener: function(rootNodeID, propKey, propValue) { 12467 this.listenersToPut.push({ 12468 rootNodeID: rootNodeID, 12469 propKey: propKey, 12470 propValue: propValue 12471 }); 12472 }, 12473 12474 putListeners: function() { 12475 for (var i = 0; i < this.listenersToPut.length; i++) { 12476 var listenerToPut = this.listenersToPut[i]; 12477 ReactEventEmitter.putListener( 12478 listenerToPut.rootNodeID, 12479 listenerToPut.propKey, 12480 listenerToPut.propValue 12481 ); 12482 } 12483 }, 12484 12485 reset: function() { 12486 this.listenersToPut.length = 0; 12487 }, 12488 12489 destructor: function() { 12490 this.reset(); 12491 } 12492 }); 12493 12494 PooledClass.addPoolingTo(ReactPutListenerQueue); 12495 12496 module.exports = ReactPutListenerQueue; 12497 12498 },{"./PooledClass":25,"./ReactEventEmitter":52,"./mixInto":137}],71:[function(_dereq_,module,exports){ 12499 /** 12500 * Copyright 2013-2014 Facebook, Inc. 12501 * 12502 * Licensed under the Apache License, Version 2.0 (the "License"); 12503 * you may not use this file except in compliance with the License. 12504 * You may obtain a copy of the License at 12505 * 12506 * http://www.apache.org/licenses/LICENSE-2.0 12507 * 12508 * Unless required by applicable law or agreed to in writing, software 12509 * distributed under the License is distributed on an "AS IS" BASIS, 12510 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12511 * See the License for the specific language governing permissions and 12512 * limitations under the License. 12513 * 12514 * @providesModule ReactReconcileTransaction 12515 * @typechecks static-only 12516 */ 12517 12518 "use strict"; 12519 12520 var PooledClass = _dereq_("./PooledClass"); 12521 var ReactEventEmitter = _dereq_("./ReactEventEmitter"); 12522 var ReactInputSelection = _dereq_("./ReactInputSelection"); 12523 var ReactMountReady = _dereq_("./ReactMountReady"); 12524 var ReactPutListenerQueue = _dereq_("./ReactPutListenerQueue"); 12525 var Transaction = _dereq_("./Transaction"); 12526 12527 var mixInto = _dereq_("./mixInto"); 12528 12529 /** 12530 * Ensures that, when possible, the selection range (currently selected text 12531 * input) is not disturbed by performing the transaction. 12532 */ 12533 var SELECTION_RESTORATION = { 12534 /** 12535 * @return {Selection} Selection information. 12536 */ 12537 initialize: ReactInputSelection.getSelectionInformation, 12538 /** 12539 * @param {Selection} sel Selection information returned from `initialize`. 12540 */ 12541 close: ReactInputSelection.restoreSelection 12542 }; 12543 12544 /** 12545 * Suppresses events (blur/focus) that could be inadvertently dispatched due to 12546 * high level DOM manipulations (like temporarily removing a text input from the 12547 * DOM). 12548 */ 12549 var EVENT_SUPPRESSION = { 12550 /** 12551 * @return {boolean} The enabled status of `ReactEventEmitter` before the 12552 * reconciliation. 12553 */ 12554 initialize: function() { 12555 var currentlyEnabled = ReactEventEmitter.isEnabled(); 12556 ReactEventEmitter.setEnabled(false); 12557 return currentlyEnabled; 12558 }, 12559 12560 /** 12561 * @param {boolean} previouslyEnabled Enabled status of `ReactEventEmitter` 12562 * before the reconciliation occured. `close` restores the previous value. 12563 */ 12564 close: function(previouslyEnabled) { 12565 ReactEventEmitter.setEnabled(previouslyEnabled); 12566 } 12567 }; 12568 12569 /** 12570 * Provides a `ReactMountReady` queue for collecting `onDOMReady` callbacks 12571 * during the performing of the transaction. 12572 */ 12573 var ON_DOM_READY_QUEUEING = { 12574 /** 12575 * Initializes the internal `onDOMReady` queue. 12576 */ 12577 initialize: function() { 12578 this.reactMountReady.reset(); 12579 }, 12580 12581 /** 12582 * After DOM is flushed, invoke all registered `onDOMReady` callbacks. 12583 */ 12584 close: function() { 12585 this.reactMountReady.notifyAll(); 12586 } 12587 }; 12588 12589 var PUT_LISTENER_QUEUEING = { 12590 initialize: function() { 12591 this.putListenerQueue.reset(); 12592 }, 12593 12594 close: function() { 12595 this.putListenerQueue.putListeners(); 12596 } 12597 }; 12598 12599 /** 12600 * Executed within the scope of the `Transaction` instance. Consider these as 12601 * being member methods, but with an implied ordering while being isolated from 12602 * each other. 12603 */ 12604 var TRANSACTION_WRAPPERS = [ 12605 PUT_LISTENER_QUEUEING, 12606 SELECTION_RESTORATION, 12607 EVENT_SUPPRESSION, 12608 ON_DOM_READY_QUEUEING 12609 ]; 12610 12611 /** 12612 * Currently: 12613 * - The order that these are listed in the transaction is critical: 12614 * - Suppresses events. 12615 * - Restores selection range. 12616 * 12617 * Future: 12618 * - Restore document/overflow scroll positions that were unintentionally 12619 * modified via DOM insertions above the top viewport boundary. 12620 * - Implement/integrate with customized constraint based layout system and keep 12621 * track of which dimensions must be remeasured. 12622 * 12623 * @class ReactReconcileTransaction 12624 */ 12625 function ReactReconcileTransaction() { 12626 this.reinitializeTransaction(); 12627 // Only server-side rendering really needs this option (see 12628 // `ReactServerRendering`), but server-side uses 12629 // `ReactServerRenderingTransaction` instead. This option is here so that it's 12630 // accessible and defaults to false when `ReactDOMComponent` and 12631 // `ReactTextComponent` checks it in `mountComponent`.` 12632 this.renderToStaticMarkup = false; 12633 this.reactMountReady = ReactMountReady.getPooled(null); 12634 this.putListenerQueue = ReactPutListenerQueue.getPooled(); 12635 } 12636 12637 var Mixin = { 12638 /** 12639 * @see Transaction 12640 * @abstract 12641 * @final 12642 * @return {array<object>} List of operation wrap proceedures. 12643 * TODO: convert to array<TransactionWrapper> 12644 */ 12645 getTransactionWrappers: function() { 12646 return TRANSACTION_WRAPPERS; 12647 }, 12648 12649 /** 12650 * @return {object} The queue to collect `onDOMReady` callbacks with. 12651 * TODO: convert to ReactMountReady 12652 */ 12653 getReactMountReady: function() { 12654 return this.reactMountReady; 12655 }, 12656 12657 getPutListenerQueue: function() { 12658 return this.putListenerQueue; 12659 }, 12660 12661 /** 12662 * `PooledClass` looks for this, and will invoke this before allowing this 12663 * instance to be resused. 12664 */ 12665 destructor: function() { 12666 ReactMountReady.release(this.reactMountReady); 12667 this.reactMountReady = null; 12668 12669 ReactPutListenerQueue.release(this.putListenerQueue); 12670 this.putListenerQueue = null; 12671 } 12672 }; 12673 12674 12675 mixInto(ReactReconcileTransaction, Transaction.Mixin); 12676 mixInto(ReactReconcileTransaction, Mixin); 12677 12678 PooledClass.addPoolingTo(ReactReconcileTransaction); 12679 12680 module.exports = ReactReconcileTransaction; 12681 12682 },{"./PooledClass":25,"./ReactEventEmitter":52,"./ReactInputSelection":56,"./ReactMountReady":61,"./ReactPutListenerQueue":70,"./Transaction":96,"./mixInto":137}],72:[function(_dereq_,module,exports){ 12683 /** 12684 * Copyright 2013-2014 Facebook, Inc. 12685 * 12686 * Licensed under the Apache License, Version 2.0 (the "License"); 12687 * you may not use this file except in compliance with the License. 12688 * You may obtain a copy of the License at 12689 * 12690 * http://www.apache.org/licenses/LICENSE-2.0 12691 * 12692 * Unless required by applicable law or agreed to in writing, software 12693 * distributed under the License is distributed on an "AS IS" BASIS, 12694 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12695 * See the License for the specific language governing permissions and 12696 * limitations under the License. 12697 * 12698 * @providesModule ReactRootIndex 12699 * @typechecks 12700 */ 12701 12702 "use strict"; 12703 12704 var ReactRootIndexInjection = { 12705 /** 12706 * @param {function} _createReactRootIndex 12707 */ 12708 injectCreateReactRootIndex: function(_createReactRootIndex) { 12709 ReactRootIndex.createReactRootIndex = _createReactRootIndex; 12710 } 12711 }; 12712 12713 var ReactRootIndex = { 12714 createReactRootIndex: null, 12715 injection: ReactRootIndexInjection 12716 }; 12717 12718 module.exports = ReactRootIndex; 12719 12720 },{}],73:[function(_dereq_,module,exports){ 12721 /** 12722 * Copyright 2013-2014 Facebook, Inc. 12723 * 12724 * Licensed under the Apache License, Version 2.0 (the "License"); 12725 * you may not use this file except in compliance with the License. 12726 * You may obtain a copy of the License at 12727 * 12728 * http://www.apache.org/licenses/LICENSE-2.0 12729 * 12730 * Unless required by applicable law or agreed to in writing, software 12731 * distributed under the License is distributed on an "AS IS" BASIS, 12732 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12733 * See the License for the specific language governing permissions and 12734 * limitations under the License. 12735 * 12736 * @typechecks static-only 12737 * @providesModule ReactServerRendering 12738 */ 12739 "use strict"; 12740 12741 var ReactComponent = _dereq_("./ReactComponent"); 12742 var ReactInstanceHandles = _dereq_("./ReactInstanceHandles"); 12743 var ReactMarkupChecksum = _dereq_("./ReactMarkupChecksum"); 12744 var ReactServerRenderingTransaction = 12745 _dereq_("./ReactServerRenderingTransaction"); 12746 12747 var instantiateReactComponent = _dereq_("./instantiateReactComponent"); 12748 var invariant = _dereq_("./invariant"); 12749 12750 /** 12751 * @param {ReactComponent} component 12752 * @return {string} the HTML markup 12753 */ 12754 function renderComponentToString(component) { 12755 ("production" !== "development" ? invariant( 12756 ReactComponent.isValidComponent(component), 12757 'renderComponentToString(): You must pass a valid ReactComponent.' 12758 ) : invariant(ReactComponent.isValidComponent(component))); 12759 12760 ("production" !== "development" ? invariant( 12761 !(arguments.length === 2 && typeof arguments[1] === 'function'), 12762 'renderComponentToString(): This function became synchronous and now ' + 12763 'returns the generated markup. Please remove the second parameter.' 12764 ) : invariant(!(arguments.length === 2 && typeof arguments[1] === 'function'))); 12765 12766 var transaction; 12767 try { 12768 var id = ReactInstanceHandles.createReactRootID(); 12769 transaction = ReactServerRenderingTransaction.getPooled(false); 12770 12771 return transaction.perform(function() { 12772 var componentInstance = instantiateReactComponent(component); 12773 var markup = componentInstance.mountComponent(id, transaction, 0); 12774 return ReactMarkupChecksum.addChecksumToMarkup(markup); 12775 }, null); 12776 } finally { 12777 ReactServerRenderingTransaction.release(transaction); 12778 } 12779 } 12780 12781 /** 12782 * @param {ReactComponent} component 12783 * @return {string} the HTML markup, without the extra React ID and checksum 12784 * (for generating static pages) 12785 */ 12786 function renderComponentToStaticMarkup(component) { 12787 ("production" !== "development" ? invariant( 12788 ReactComponent.isValidComponent(component), 12789 'renderComponentToStaticMarkup(): You must pass a valid ReactComponent.' 12790 ) : invariant(ReactComponent.isValidComponent(component))); 12791 12792 var transaction; 12793 try { 12794 var id = ReactInstanceHandles.createReactRootID(); 12795 transaction = ReactServerRenderingTransaction.getPooled(true); 12796 12797 return transaction.perform(function() { 12798 var componentInstance = instantiateReactComponent(component); 12799 return componentInstance.mountComponent(id, transaction, 0); 12800 }, null); 12801 } finally { 12802 ReactServerRenderingTransaction.release(transaction); 12803 } 12804 } 12805 12806 module.exports = { 12807 renderComponentToString: renderComponentToString, 12808 renderComponentToStaticMarkup: renderComponentToStaticMarkup 12809 }; 12810 12811 },{"./ReactComponent":31,"./ReactInstanceHandles":57,"./ReactMarkupChecksum":59,"./ReactServerRenderingTransaction":74,"./instantiateReactComponent":124,"./invariant":125}],74:[function(_dereq_,module,exports){ 12812 /** 12813 * Copyright 2014 Facebook, Inc. 12814 * 12815 * Licensed under the Apache License, Version 2.0 (the "License"); 12816 * you may not use this file except in compliance with the License. 12817 * You may obtain a copy of the License at 12818 * 12819 * http://www.apache.org/licenses/LICENSE-2.0 12820 * 12821 * Unless required by applicable law or agreed to in writing, software 12822 * distributed under the License is distributed on an "AS IS" BASIS, 12823 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12824 * See the License for the specific language governing permissions and 12825 * limitations under the License. 12826 * 12827 * @providesModule ReactServerRenderingTransaction 12828 * @typechecks 12829 */ 12830 12831 "use strict"; 12832 12833 var PooledClass = _dereq_("./PooledClass"); 12834 var ReactMountReady = _dereq_("./ReactMountReady"); 12835 var ReactPutListenerQueue = _dereq_("./ReactPutListenerQueue"); 12836 var Transaction = _dereq_("./Transaction"); 12837 12838 var emptyFunction = _dereq_("./emptyFunction"); 12839 var mixInto = _dereq_("./mixInto"); 12840 12841 /** 12842 * Provides a `ReactMountReady` queue for collecting `onDOMReady` callbacks 12843 * during the performing of the transaction. 12844 */ 12845 var ON_DOM_READY_QUEUEING = { 12846 /** 12847 * Initializes the internal `onDOMReady` queue. 12848 */ 12849 initialize: function() { 12850 this.reactMountReady.reset(); 12851 }, 12852 12853 close: emptyFunction 12854 }; 12855 12856 var PUT_LISTENER_QUEUEING = { 12857 initialize: function() { 12858 this.putListenerQueue.reset(); 12859 }, 12860 12861 close: emptyFunction 12862 }; 12863 12864 /** 12865 * Executed within the scope of the `Transaction` instance. Consider these as 12866 * being member methods, but with an implied ordering while being isolated from 12867 * each other. 12868 */ 12869 var TRANSACTION_WRAPPERS = [ 12870 PUT_LISTENER_QUEUEING, 12871 ON_DOM_READY_QUEUEING 12872 ]; 12873 12874 /** 12875 * @class ReactServerRenderingTransaction 12876 * @param {boolean} renderToStaticMarkup 12877 */ 12878 function ReactServerRenderingTransaction(renderToStaticMarkup) { 12879 this.reinitializeTransaction(); 12880 this.renderToStaticMarkup = renderToStaticMarkup; 12881 this.reactMountReady = ReactMountReady.getPooled(null); 12882 this.putListenerQueue = ReactPutListenerQueue.getPooled(); 12883 } 12884 12885 var Mixin = { 12886 /** 12887 * @see Transaction 12888 * @abstract 12889 * @final 12890 * @return {array} Empty list of operation wrap proceedures. 12891 */ 12892 getTransactionWrappers: function() { 12893 return TRANSACTION_WRAPPERS; 12894 }, 12895 12896 /** 12897 * @return {object} The queue to collect `onDOMReady` callbacks with. 12898 * TODO: convert to ReactMountReady 12899 */ 12900 getReactMountReady: function() { 12901 return this.reactMountReady; 12902 }, 12903 12904 getPutListenerQueue: function() { 12905 return this.putListenerQueue; 12906 }, 12907 12908 /** 12909 * `PooledClass` looks for this, and will invoke this before allowing this 12910 * instance to be resused. 12911 */ 12912 destructor: function() { 12913 ReactMountReady.release(this.reactMountReady); 12914 this.reactMountReady = null; 12915 12916 ReactPutListenerQueue.release(this.putListenerQueue); 12917 this.putListenerQueue = null; 12918 } 12919 }; 12920 12921 12922 mixInto(ReactServerRenderingTransaction, Transaction.Mixin); 12923 mixInto(ReactServerRenderingTransaction, Mixin); 12924 12925 PooledClass.addPoolingTo(ReactServerRenderingTransaction); 12926 12927 module.exports = ReactServerRenderingTransaction; 12928 12929 },{"./PooledClass":25,"./ReactMountReady":61,"./ReactPutListenerQueue":70,"./Transaction":96,"./emptyFunction":109,"./mixInto":137}],75:[function(_dereq_,module,exports){ 12930 /** 12931 * Copyright 2013-2014 Facebook, Inc. 12932 * 12933 * Licensed under the Apache License, Version 2.0 (the "License"); 12934 * you may not use this file except in compliance with the License. 12935 * You may obtain a copy of the License at 12936 * 12937 * http://www.apache.org/licenses/LICENSE-2.0 12938 * 12939 * Unless required by applicable law or agreed to in writing, software 12940 * distributed under the License is distributed on an "AS IS" BASIS, 12941 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12942 * See the License for the specific language governing permissions and 12943 * limitations under the License. 12944 * 12945 * @providesModule ReactStateSetters 12946 */ 12947 12948 "use strict"; 12949 12950 var ReactStateSetters = { 12951 /** 12952 * Returns a function that calls the provided function, and uses the result 12953 * of that to set the component's state. 12954 * 12955 * @param {ReactCompositeComponent} component 12956 * @param {function} funcReturningState Returned callback uses this to 12957 * determine how to update state. 12958 * @return {function} callback that when invoked uses funcReturningState to 12959 * determined the object literal to setState. 12960 */ 12961 createStateSetter: function(component, funcReturningState) { 12962 return function(a, b, c, d, e, f) { 12963 var partialState = funcReturningState.call(component, a, b, c, d, e, f); 12964 if (partialState) { 12965 component.setState(partialState); 12966 } 12967 }; 12968 }, 12969 12970 /** 12971 * Returns a single-argument callback that can be used to update a single 12972 * key in the component's state. 12973 * 12974 * Note: this is memoized function, which makes it inexpensive to call. 12975 * 12976 * @param {ReactCompositeComponent} component 12977 * @param {string} key The key in the state that you should update. 12978 * @return {function} callback of 1 argument which calls setState() with 12979 * the provided keyName and callback argument. 12980 */ 12981 createStateKeySetter: function(component, key) { 12982 // Memoize the setters. 12983 var cache = component.__keySetters || (component.__keySetters = {}); 12984 return cache[key] || (cache[key] = createStateKeySetter(component, key)); 12985 } 12986 }; 12987 12988 function createStateKeySetter(component, key) { 12989 // Partial state is allocated outside of the function closure so it can be 12990 // reused with every call, avoiding memory allocation when this function 12991 // is called. 12992 var partialState = {}; 12993 return function stateKeySetter(value) { 12994 partialState[key] = value; 12995 component.setState(partialState); 12996 }; 12997 } 12998 12999 ReactStateSetters.Mixin = { 13000 /** 13001 * Returns a function that calls the provided function, and uses the result 13002 * of that to set the component's state. 13003 * 13004 * For example, these statements are equivalent: 13005 * 13006 * this.setState({x: 1}); 13007 * this.createStateSetter(function(xValue) { 13008 * return {x: xValue}; 13009 * })(1); 13010 * 13011 * @param {function} funcReturningState Returned callback uses this to 13012 * determine how to update state. 13013 * @return {function} callback that when invoked uses funcReturningState to 13014 * determined the object literal to setState. 13015 */ 13016 createStateSetter: function(funcReturningState) { 13017 return ReactStateSetters.createStateSetter(this, funcReturningState); 13018 }, 13019 13020 /** 13021 * Returns a single-argument callback that can be used to update a single 13022 * key in the component's state. 13023 * 13024 * For example, these statements are equivalent: 13025 * 13026 * this.setState({x: 1}); 13027 * this.createStateKeySetter('x')(1); 13028 * 13029 * Note: this is memoized function, which makes it inexpensive to call. 13030 * 13031 * @param {string} key The key in the state that you should update. 13032 * @return {function} callback of 1 argument which calls setState() with 13033 * the provided keyName and callback argument. 13034 */ 13035 createStateKeySetter: function(key) { 13036 return ReactStateSetters.createStateKeySetter(this, key); 13037 } 13038 }; 13039 13040 module.exports = ReactStateSetters; 13041 13042 },{}],76:[function(_dereq_,module,exports){ 13043 /** 13044 * Copyright 2013-2014 Facebook, Inc. 13045 * 13046 * Licensed under the Apache License, Version 2.0 (the "License"); 13047 * you may not use this file except in compliance with the License. 13048 * You may obtain a copy of the License at 13049 * 13050 * http://www.apache.org/licenses/LICENSE-2.0 13051 * 13052 * Unless required by applicable law or agreed to in writing, software 13053 * distributed under the License is distributed on an "AS IS" BASIS, 13054 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13055 * See the License for the specific language governing permissions and 13056 * limitations under the License. 13057 * 13058 * @providesModule ReactTestUtils 13059 */ 13060 13061 "use strict"; 13062 13063 var EventConstants = _dereq_("./EventConstants"); 13064 var EventPluginHub = _dereq_("./EventPluginHub"); 13065 var EventPropagators = _dereq_("./EventPropagators"); 13066 var React = _dereq_("./React"); 13067 var ReactComponent = _dereq_("./ReactComponent"); 13068 var ReactDOM = _dereq_("./ReactDOM"); 13069 var ReactEventEmitter = _dereq_("./ReactEventEmitter"); 13070 var ReactMount = _dereq_("./ReactMount"); 13071 var ReactTextComponent = _dereq_("./ReactTextComponent"); 13072 var ReactUpdates = _dereq_("./ReactUpdates"); 13073 var SyntheticEvent = _dereq_("./SyntheticEvent"); 13074 13075 var mergeInto = _dereq_("./mergeInto"); 13076 var copyProperties = _dereq_("./copyProperties"); 13077 13078 var topLevelTypes = EventConstants.topLevelTypes; 13079 13080 function Event(suffix) {} 13081 13082 /** 13083 * @class ReactTestUtils 13084 */ 13085 13086 /** 13087 * Todo: Support the entire DOM.scry query syntax. For now, these simple 13088 * utilities will suffice for testing purposes. 13089 * @lends ReactTestUtils 13090 */ 13091 var ReactTestUtils = { 13092 renderIntoDocument: function(instance) { 13093 var div = document.createElement('div'); 13094 // None of our tests actually require attaching the container to the 13095 // DOM, and doing so creates a mess that we rely on test isolation to 13096 // clean up, so we're going to stop honoring the name of this method 13097 // (and probably rename it eventually) if no problems arise. 13098 // document.documentElement.appendChild(div); 13099 return React.renderComponent(instance, div); 13100 }, 13101 13102 isComponentOfType: function(inst, convenienceConstructor) { 13103 return ( 13104 ReactComponent.isValidComponent(inst) && 13105 inst.type === convenienceConstructor.type 13106 ); 13107 }, 13108 13109 isDOMComponent: function(inst) { 13110 return !!(inst && 13111 ReactComponent.isValidComponent(inst) && 13112 !!inst.tagName); 13113 }, 13114 13115 isCompositeComponent: function(inst) { 13116 if (!ReactComponent.isValidComponent(inst)) { 13117 return false; 13118 } 13119 // We check the prototype of the type that will get mounted, not the 13120 // instance itself. This is a future proof way of duck typing. 13121 var prototype = inst.type.prototype; 13122 return ( 13123 typeof prototype.render === 'function' && 13124 typeof prototype.setState === 'function' && 13125 typeof prototype.updateComponent === 'function' 13126 ); 13127 }, 13128 13129 isCompositeComponentWithType: function(inst, type) { 13130 return !!(ReactTestUtils.isCompositeComponent(inst) && 13131 (inst.constructor === type.componentConstructor || 13132 inst.constructor === type)); 13133 }, 13134 13135 isTextComponent: function(inst) { 13136 return inst instanceof ReactTextComponent; 13137 }, 13138 13139 findAllInRenderedTree: function(inst, test) { 13140 if (!inst) { 13141 return []; 13142 } 13143 var ret = test(inst) ? [inst] : []; 13144 if (ReactTestUtils.isDOMComponent(inst)) { 13145 var renderedChildren = inst._renderedChildren; 13146 var key; 13147 for (key in renderedChildren) { 13148 if (!renderedChildren.hasOwnProperty(key)) { 13149 continue; 13150 } 13151 ret = ret.concat( 13152 ReactTestUtils.findAllInRenderedTree(renderedChildren[key], test) 13153 ); 13154 } 13155 } else if (ReactTestUtils.isCompositeComponent(inst)) { 13156 ret = ret.concat( 13157 ReactTestUtils.findAllInRenderedTree(inst._renderedComponent, test) 13158 ); 13159 } 13160 return ret; 13161 }, 13162 13163 /** 13164 * Finds all instance of components in the rendered tree that are DOM 13165 * components with the class name matching `className`. 13166 * @return an array of all the matches. 13167 */ 13168 scryRenderedDOMComponentsWithClass: function(root, className) { 13169 return ReactTestUtils.findAllInRenderedTree(root, function(inst) { 13170 var instClassName = inst.props.className; 13171 return ReactTestUtils.isDOMComponent(inst) && ( 13172 instClassName && 13173 (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1 13174 ); 13175 }); 13176 }, 13177 13178 /** 13179 * Like scryRenderedDOMComponentsWithClass but expects there to be one result, 13180 * and returns that one result, or throws exception if there is any other 13181 * number of matches besides one. 13182 * @return {!ReactDOMComponent} The one match. 13183 */ 13184 findRenderedDOMComponentWithClass: function(root, className) { 13185 var all = 13186 ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className); 13187 if (all.length !== 1) { 13188 throw new Error('Did not find exactly one match for class:' + className); 13189 } 13190 return all[0]; 13191 }, 13192 13193 13194 /** 13195 * Finds all instance of components in the rendered tree that are DOM 13196 * components with the tag name matching `tagName`. 13197 * @return an array of all the matches. 13198 */ 13199 scryRenderedDOMComponentsWithTag: function(root, tagName) { 13200 return ReactTestUtils.findAllInRenderedTree(root, function(inst) { 13201 return ReactTestUtils.isDOMComponent(inst) && 13202 inst.tagName === tagName.toUpperCase(); 13203 }); 13204 }, 13205 13206 /** 13207 * Like scryRenderedDOMComponentsWithTag but expects there to be one result, 13208 * and returns that one result, or throws exception if there is any other 13209 * number of matches besides one. 13210 * @return {!ReactDOMComponent} The one match. 13211 */ 13212 findRenderedDOMComponentWithTag: function(root, tagName) { 13213 var all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName); 13214 if (all.length !== 1) { 13215 throw new Error('Did not find exactly one match for tag:' + tagName); 13216 } 13217 return all[0]; 13218 }, 13219 13220 13221 /** 13222 * Finds all instances of components with type equal to `componentType`. 13223 * @return an array of all the matches. 13224 */ 13225 scryRenderedComponentsWithType: function(root, componentType) { 13226 return ReactTestUtils.findAllInRenderedTree(root, function(inst) { 13227 return ReactTestUtils.isCompositeComponentWithType(inst, componentType); 13228 }); 13229 }, 13230 13231 /** 13232 * Same as `scryRenderedComponentsWithType` but expects there to be one result 13233 * and returns that one result, or throws exception if there is any other 13234 * number of matches besides one. 13235 * @return {!ReactComponent} The one match. 13236 */ 13237 findRenderedComponentWithType: function(root, componentType) { 13238 var all = ReactTestUtils.scryRenderedComponentsWithType( 13239 root, 13240 componentType 13241 ); 13242 if (all.length !== 1) { 13243 throw new Error( 13244 'Did not find exactly one match for componentType:' + componentType 13245 ); 13246 } 13247 return all[0]; 13248 }, 13249 13250 /** 13251 * Pass a mocked component module to this method to augment it with 13252 * useful methods that allow it to be used as a dummy React component. 13253 * Instead of rendering as usual, the component will become a simple 13254 * <div> containing any provided children. 13255 * 13256 * @param {object} module the mock function object exported from a 13257 * module that defines the component to be mocked 13258 * @param {?string} mockTagName optional dummy root tag name to return 13259 * from render method (overrides 13260 * module.mockTagName if provided) 13261 * @return {object} the ReactTestUtils object (for chaining) 13262 */ 13263 mockComponent: function(module, mockTagName) { 13264 var ConvenienceConstructor = React.createClass({ 13265 render: function() { 13266 var mockTagName = mockTagName || module.mockTagName || "div"; 13267 return ReactDOM[mockTagName](null, this.props.children); 13268 } 13269 }); 13270 13271 copyProperties(module, ConvenienceConstructor); 13272 module.mockImplementation(ConvenienceConstructor); 13273 13274 return this; 13275 }, 13276 13277 /** 13278 * Simulates a top level event being dispatched from a raw event that occured 13279 * on an `Element` node. 13280 * @param topLevelType {Object} A type from `EventConstants.topLevelTypes` 13281 * @param {!Element} node The dom to simulate an event occurring on. 13282 * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. 13283 */ 13284 simulateNativeEventOnNode: function(topLevelType, node, fakeNativeEvent) { 13285 var virtualHandler = 13286 ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback( 13287 topLevelType 13288 ); 13289 fakeNativeEvent.target = node; 13290 virtualHandler(fakeNativeEvent); 13291 }, 13292 13293 /** 13294 * Simulates a top level event being dispatched from a raw event that occured 13295 * on the `ReactDOMComponent` `comp`. 13296 * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`. 13297 * @param comp {!ReactDOMComponent} 13298 * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. 13299 */ 13300 simulateNativeEventOnDOMComponent: function( 13301 topLevelType, 13302 comp, 13303 fakeNativeEvent) { 13304 ReactTestUtils.simulateNativeEventOnNode( 13305 topLevelType, 13306 comp.getDOMNode(), 13307 fakeNativeEvent 13308 ); 13309 }, 13310 13311 nativeTouchData: function(x, y) { 13312 return { 13313 touches: [ 13314 {pageX: x, pageY: y} 13315 ] 13316 }; 13317 }, 13318 13319 Simulate: null, 13320 SimulateNative: {} 13321 }; 13322 13323 /** 13324 * Exports: 13325 * 13326 * - `ReactTestUtils.Simulate.click(Element/ReactDOMComponent)` 13327 * - `ReactTestUtils.Simulate.mouseMove(Element/ReactDOMComponent)` 13328 * - `ReactTestUtils.Simulate.change(Element/ReactDOMComponent)` 13329 * - ... (All keys from event plugin `eventTypes` objects) 13330 */ 13331 function makeSimulator(eventType) { 13332 return function(domComponentOrNode, eventData) { 13333 var node; 13334 if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { 13335 node = domComponentOrNode.getDOMNode(); 13336 } else if (domComponentOrNode.tagName) { 13337 node = domComponentOrNode; 13338 } 13339 13340 var fakeNativeEvent = new Event(); 13341 fakeNativeEvent.target = node; 13342 // We don't use SyntheticEvent.getPooled in order to not have to worry about 13343 // properly destroying any properties assigned from `eventData` upon release 13344 var event = new SyntheticEvent( 13345 ReactEventEmitter.eventNameDispatchConfigs[eventType], 13346 ReactMount.getID(node), 13347 fakeNativeEvent 13348 ); 13349 mergeInto(event, eventData); 13350 EventPropagators.accumulateTwoPhaseDispatches(event); 13351 13352 ReactUpdates.batchedUpdates(function() { 13353 EventPluginHub.enqueueEvents(event); 13354 EventPluginHub.processEventQueue(); 13355 }); 13356 }; 13357 } 13358 13359 function buildSimulators() { 13360 ReactTestUtils.Simulate = {}; 13361 13362 var eventType; 13363 for (eventType in ReactEventEmitter.eventNameDispatchConfigs) { 13364 /** 13365 * @param {!Element || ReactDOMComponent} domComponentOrNode 13366 * @param {?object} eventData Fake event data to use in SyntheticEvent. 13367 */ 13368 ReactTestUtils.Simulate[eventType] = makeSimulator(eventType); 13369 } 13370 } 13371 13372 // Rebuild ReactTestUtils.Simulate whenever event plugins are injected 13373 var oldInjectEventPluginOrder = EventPluginHub.injection.injectEventPluginOrder; 13374 EventPluginHub.injection.injectEventPluginOrder = function() { 13375 oldInjectEventPluginOrder.apply(this, arguments); 13376 buildSimulators(); 13377 }; 13378 var oldInjectEventPlugins = EventPluginHub.injection.injectEventPluginsByName; 13379 EventPluginHub.injection.injectEventPluginsByName = function() { 13380 oldInjectEventPlugins.apply(this, arguments); 13381 buildSimulators(); 13382 }; 13383 13384 buildSimulators(); 13385 13386 /** 13387 * Exports: 13388 * 13389 * - `ReactTestUtils.SimulateNative.click(Element/ReactDOMComponent)` 13390 * - `ReactTestUtils.SimulateNative.mouseMove(Element/ReactDOMComponent)` 13391 * - `ReactTestUtils.SimulateNative.mouseIn/ReactDOMComponent)` 13392 * - `ReactTestUtils.SimulateNative.mouseOut(Element/ReactDOMComponent)` 13393 * - ... (All keys from `EventConstants.topLevelTypes`) 13394 * 13395 * Note: Top level event types are a subset of the entire set of handler types 13396 * (which include a broader set of "synthetic" events). For example, onDragDone 13397 * is a synthetic event. Except when testing an event plugin or React's event 13398 * handling code specifically, you probably want to use ReactTestUtils.Simulate 13399 * to dispatch synthetic events. 13400 */ 13401 13402 function makeNativeSimulator(eventType) { 13403 return function(domComponentOrNode, nativeEventData) { 13404 var fakeNativeEvent = new Event(eventType); 13405 mergeInto(fakeNativeEvent, nativeEventData); 13406 if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { 13407 ReactTestUtils.simulateNativeEventOnDOMComponent( 13408 eventType, 13409 domComponentOrNode, 13410 fakeNativeEvent 13411 ); 13412 } else if (!!domComponentOrNode.tagName) { 13413 // Will allow on actual dom nodes. 13414 ReactTestUtils.simulateNativeEventOnNode( 13415 eventType, 13416 domComponentOrNode, 13417 fakeNativeEvent 13418 ); 13419 } 13420 }; 13421 } 13422 13423 var eventType; 13424 for (eventType in topLevelTypes) { 13425 // Event type is stored as 'topClick' - we transform that to 'click' 13426 var convenienceName = eventType.indexOf('top') === 0 ? 13427 eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType; 13428 /** 13429 * @param {!Element || ReactDOMComponent} domComponentOrNode 13430 * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent. 13431 */ 13432 ReactTestUtils.SimulateNative[convenienceName] = 13433 makeNativeSimulator(eventType); 13434 } 13435 13436 module.exports = ReactTestUtils; 13437 13438 },{"./EventConstants":15,"./EventPluginHub":17,"./EventPropagators":20,"./React":26,"./ReactComponent":31,"./ReactDOM":36,"./ReactEventEmitter":52,"./ReactMount":60,"./ReactTextComponent":77,"./ReactUpdates":81,"./SyntheticEvent":89,"./copyProperties":102,"./mergeInto":136}],77:[function(_dereq_,module,exports){ 13439 /** 13440 * Copyright 2013-2014 Facebook, Inc. 13441 * 13442 * Licensed under the Apache License, Version 2.0 (the "License"); 13443 * you may not use this file except in compliance with the License. 13444 * You may obtain a copy of the License at 13445 * 13446 * http://www.apache.org/licenses/LICENSE-2.0 13447 * 13448 * Unless required by applicable law or agreed to in writing, software 13449 * distributed under the License is distributed on an "AS IS" BASIS, 13450 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13451 * See the License for the specific language governing permissions and 13452 * limitations under the License. 13453 * 13454 * @providesModule ReactTextComponent 13455 * @typechecks static-only 13456 */ 13457 13458 "use strict"; 13459 13460 var DOMPropertyOperations = _dereq_("./DOMPropertyOperations"); 13461 var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin"); 13462 var ReactComponent = _dereq_("./ReactComponent"); 13463 13464 var escapeTextForBrowser = _dereq_("./escapeTextForBrowser"); 13465 var mixInto = _dereq_("./mixInto"); 13466 13467 /** 13468 * Text nodes violate a couple assumptions that React makes about components: 13469 * 13470 * - When mounting text into the DOM, adjacent text nodes are merged. 13471 * - Text nodes cannot be assigned a React root ID. 13472 * 13473 * This component is used to wrap strings in elements so that they can undergo 13474 * the same reconciliation that is applied to elements. 13475 * 13476 * TODO: Investigate representing React components in the DOM with text nodes. 13477 * 13478 * @class ReactTextComponent 13479 * @extends ReactComponent 13480 * @internal 13481 */ 13482 var ReactTextComponent = function(initialText) { 13483 this.construct({text: initialText}); 13484 }; 13485 13486 /** 13487 * Used to clone the text descriptor object before it's mounted. 13488 * 13489 * @param {object} props 13490 * @return {object} A new ReactTextComponent instance 13491 */ 13492 ReactTextComponent.ConvenienceConstructor = function(props) { 13493 return new ReactTextComponent(props.text); 13494 }; 13495 13496 mixInto(ReactTextComponent, ReactComponent.Mixin); 13497 mixInto(ReactTextComponent, ReactBrowserComponentMixin); 13498 mixInto(ReactTextComponent, { 13499 13500 /** 13501 * Creates the markup for this text node. This node is not intended to have 13502 * any features besides containing text content. 13503 * 13504 * @param {string} rootID DOM ID of the root node. 13505 * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction 13506 * @param {number} mountDepth number of components in the owner hierarchy 13507 * @return {string} Markup for this text node. 13508 * @internal 13509 */ 13510 mountComponent: function(rootID, transaction, mountDepth) { 13511 ReactComponent.Mixin.mountComponent.call( 13512 this, 13513 rootID, 13514 transaction, 13515 mountDepth 13516 ); 13517 13518 var escapedText = escapeTextForBrowser(this.props.text); 13519 13520 if (transaction.renderToStaticMarkup) { 13521 // Normally we'd wrap this in a `span` for the reasons stated above, but 13522 // since this is a situation where React won't take over (static pages), 13523 // we can simply return the text as it is. 13524 return escapedText; 13525 } 13526 13527 return ( 13528 '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' + 13529 escapedText + 13530 '</span>' 13531 ); 13532 }, 13533 13534 /** 13535 * Updates this component by updating the text content. 13536 * 13537 * @param {object} nextComponent Contains the next text content. 13538 * @param {ReactReconcileTransaction} transaction 13539 * @internal 13540 */ 13541 receiveComponent: function(nextComponent, transaction) { 13542 var nextProps = nextComponent.props; 13543 if (nextProps.text !== this.props.text) { 13544 this.props.text = nextProps.text; 13545 ReactComponent.BackendIDOperations.updateTextContentByID( 13546 this._rootNodeID, 13547 nextProps.text 13548 ); 13549 } 13550 } 13551 13552 }); 13553 13554 // Expose the constructor on itself and the prototype for consistency with other 13555 // descriptors. 13556 ReactTextComponent.type = ReactTextComponent; 13557 ReactTextComponent.prototype.type = ReactTextComponent; 13558 13559 module.exports = ReactTextComponent; 13560 13561 },{"./DOMPropertyOperations":10,"./ReactBrowserComponentMixin":27,"./ReactComponent":31,"./escapeTextForBrowser":111,"./mixInto":137}],78:[function(_dereq_,module,exports){ 13562 /** 13563 * Copyright 2013-2014 Facebook, Inc. 13564 * 13565 * Licensed under the Apache License, Version 2.0 (the "License"); 13566 * you may not use this file except in compliance with the License. 13567 * You may obtain a copy of the License at 13568 * 13569 * http://www.apache.org/licenses/LICENSE-2.0 13570 * 13571 * Unless required by applicable law or agreed to in writing, software 13572 * distributed under the License is distributed on an "AS IS" BASIS, 13573 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13574 * See the License for the specific language governing permissions and 13575 * limitations under the License. 13576 * 13577 * @typechecks static-only 13578 * @providesModule ReactTransitionChildMapping 13579 */ 13580 13581 "use strict"; 13582 13583 var ReactChildren = _dereq_("./ReactChildren"); 13584 13585 var ReactTransitionChildMapping = { 13586 /** 13587 * Given `this.props.children`, return an object mapping key to child. Just 13588 * simple syntactic sugar around ReactChildren.map(). 13589 * 13590 * @param {*} children `this.props.children` 13591 * @return {object} Mapping of key to child 13592 */ 13593 getChildMapping: function(children) { 13594 return ReactChildren.map(children, function(child) { 13595 return child; 13596 }); 13597 }, 13598 13599 /** 13600 * When you're adding or removing children some may be added or removed in the 13601 * same render pass. We want ot show *both* since we want to simultaneously 13602 * animate elements in and out. This function takes a previous set of keys 13603 * and a new set of keys and merges them with its best guess of the correct 13604 * ordering. In the future we may expose some of the utilities in 13605 * ReactMultiChild to make this easy, but for now React itself does not 13606 * directly have this concept of the union of prevChildren and nextChildren 13607 * so we implement it here. 13608 * 13609 * @param {object} prev prev children as returned from 13610 * `ReactTransitionChildMapping.getChildMapping()`. 13611 * @param {object} next next children as returned from 13612 * `ReactTransitionChildMapping.getChildMapping()`. 13613 * @return {object} a key set that contains all keys in `prev` and all keys 13614 * in `next` in a reasonable order. 13615 */ 13616 mergeChildMappings: function(prev, next) { 13617 prev = prev || {}; 13618 next = next || {}; 13619 13620 function getValueForKey(key) { 13621 if (next.hasOwnProperty(key)) { 13622 return next[key]; 13623 } else { 13624 return prev[key]; 13625 } 13626 } 13627 13628 // For each key of `next`, the list of keys to insert before that key in 13629 // the combined list 13630 var nextKeysPending = {}; 13631 13632 var pendingKeys = []; 13633 for (var prevKey in prev) { 13634 if (next[prevKey]) { 13635 if (pendingKeys.length) { 13636 nextKeysPending[prevKey] = pendingKeys; 13637 pendingKeys = []; 13638 } 13639 } else { 13640 pendingKeys.push(prevKey); 13641 } 13642 } 13643 13644 var i; 13645 var childMapping = {}; 13646 for (var nextKey in next) { 13647 if (nextKeysPending[nextKey]) { 13648 for (i = 0; i < nextKeysPending[nextKey].length; i++) { 13649 var pendingNextKey = nextKeysPending[nextKey][i]; 13650 childMapping[nextKeysPending[nextKey][i]] = getValueForKey( 13651 pendingNextKey 13652 ); 13653 } 13654 } 13655 childMapping[nextKey] = getValueForKey(nextKey); 13656 } 13657 13658 // Finally, add the keys which didn't appear before any key in `next` 13659 for (i = 0; i < pendingKeys.length; i++) { 13660 childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]); 13661 } 13662 13663 return childMapping; 13664 } 13665 }; 13666 13667 module.exports = ReactTransitionChildMapping; 13668 13669 },{"./ReactChildren":30}],79:[function(_dereq_,module,exports){ 13670 /** 13671 * Copyright 2013-2014 Facebook, Inc. 13672 * 13673 * Licensed under the Apache License, Version 2.0 (the "License"); 13674 * you may not use this file except in compliance with the License. 13675 * You may obtain a copy of the License at 13676 * 13677 * http://www.apache.org/licenses/LICENSE-2.0 13678 * 13679 * Unless required by applicable law or agreed to in writing, software 13680 * distributed under the License is distributed on an "AS IS" BASIS, 13681 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13682 * See the License for the specific language governing permissions and 13683 * limitations under the License. 13684 * 13685 * @providesModule ReactTransitionEvents 13686 */ 13687 13688 "use strict"; 13689 13690 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 13691 13692 var EVENT_NAME_MAP = { 13693 transitionend: { 13694 'transition': 'transitionend', 13695 'WebkitTransition': 'webkitTransitionEnd', 13696 'MozTransition': 'mozTransitionEnd', 13697 'OTransition': 'oTransitionEnd', 13698 'msTransition': 'MSTransitionEnd' 13699 }, 13700 13701 animationend: { 13702 'animation': 'animationend', 13703 'WebkitAnimation': 'webkitAnimationEnd', 13704 'MozAnimation': 'mozAnimationEnd', 13705 'OAnimation': 'oAnimationEnd', 13706 'msAnimation': 'MSAnimationEnd' 13707 } 13708 }; 13709 13710 var endEvents = []; 13711 13712 function detectEvents() { 13713 var testEl = document.createElement('div'); 13714 var style = testEl.style; 13715 for (var baseEventName in EVENT_NAME_MAP) { 13716 var baseEvents = EVENT_NAME_MAP[baseEventName]; 13717 for (var styleName in baseEvents) { 13718 if (styleName in style) { 13719 endEvents.push(baseEvents[styleName]); 13720 break; 13721 } 13722 } 13723 } 13724 } 13725 13726 if (ExecutionEnvironment.canUseDOM) { 13727 detectEvents(); 13728 } 13729 13730 // We use the raw {add|remove}EventListener() call because EventListener 13731 // does not know how to remove event listeners and we really should 13732 // clean up. Also, these events are not triggered in older browsers 13733 // so we should be A-OK here. 13734 13735 function addEventListener(node, eventName, eventListener) { 13736 node.addEventListener(eventName, eventListener, false); 13737 } 13738 13739 function removeEventListener(node, eventName, eventListener) { 13740 node.removeEventListener(eventName, eventListener, false); 13741 } 13742 13743 var ReactTransitionEvents = { 13744 addEndEventListener: function(node, eventListener) { 13745 if (endEvents.length === 0) { 13746 // If CSS transitions are not supported, trigger an "end animation" 13747 // event immediately. 13748 window.setTimeout(eventListener, 0); 13749 return; 13750 } 13751 endEvents.forEach(function(endEvent) { 13752 addEventListener(node, endEvent, eventListener); 13753 }); 13754 }, 13755 13756 removeEndEventListener: function(node, eventListener) { 13757 if (endEvents.length === 0) { 13758 return; 13759 } 13760 endEvents.forEach(function(endEvent) { 13761 removeEventListener(node, endEvent, eventListener); 13762 }); 13763 } 13764 }; 13765 13766 module.exports = ReactTransitionEvents; 13767 13768 },{"./ExecutionEnvironment":21}],80:[function(_dereq_,module,exports){ 13769 /** 13770 * Copyright 2013-2014 Facebook, Inc. 13771 * 13772 * Licensed under the Apache License, Version 2.0 (the "License"); 13773 * you may not use this file except in compliance with the License. 13774 * You may obtain a copy of the License at 13775 * 13776 * http://www.apache.org/licenses/LICENSE-2.0 13777 * 13778 * Unless required by applicable law or agreed to in writing, software 13779 * distributed under the License is distributed on an "AS IS" BASIS, 13780 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13781 * See the License for the specific language governing permissions and 13782 * limitations under the License. 13783 * 13784 * @providesModule ReactTransitionGroup 13785 */ 13786 13787 "use strict"; 13788 13789 var React = _dereq_("./React"); 13790 var ReactTransitionChildMapping = _dereq_("./ReactTransitionChildMapping"); 13791 13792 var cloneWithProps = _dereq_("./cloneWithProps"); 13793 var emptyFunction = _dereq_("./emptyFunction"); 13794 var merge = _dereq_("./merge"); 13795 13796 var ReactTransitionGroup = React.createClass({ 13797 13798 propTypes: { 13799 component: React.PropTypes.func, 13800 childFactory: React.PropTypes.func 13801 }, 13802 13803 getDefaultProps: function() { 13804 return { 13805 component: React.DOM.span, 13806 childFactory: emptyFunction.thatReturnsArgument 13807 }; 13808 }, 13809 13810 getInitialState: function() { 13811 return { 13812 children: ReactTransitionChildMapping.getChildMapping(this.props.children) 13813 }; 13814 }, 13815 13816 componentWillReceiveProps: function(nextProps) { 13817 var nextChildMapping = ReactTransitionChildMapping.getChildMapping( 13818 nextProps.children 13819 ); 13820 var prevChildMapping = this.state.children; 13821 13822 this.setState({ 13823 children: ReactTransitionChildMapping.mergeChildMappings( 13824 prevChildMapping, 13825 nextChildMapping 13826 ) 13827 }); 13828 13829 var key; 13830 13831 for (key in nextChildMapping) { 13832 if (!prevChildMapping.hasOwnProperty(key) && 13833 !this.currentlyTransitioningKeys[key]) { 13834 this.keysToEnter.push(key); 13835 } 13836 } 13837 13838 for (key in prevChildMapping) { 13839 if (!nextChildMapping.hasOwnProperty(key) && 13840 !this.currentlyTransitioningKeys[key]) { 13841 this.keysToLeave.push(key); 13842 } 13843 } 13844 13845 // If we want to someday check for reordering, we could do it here. 13846 }, 13847 13848 componentWillMount: function() { 13849 this.currentlyTransitioningKeys = {}; 13850 this.keysToEnter = []; 13851 this.keysToLeave = []; 13852 }, 13853 13854 componentDidUpdate: function() { 13855 var keysToEnter = this.keysToEnter; 13856 this.keysToEnter = []; 13857 keysToEnter.forEach(this.performEnter); 13858 13859 var keysToLeave = this.keysToLeave; 13860 this.keysToLeave = []; 13861 keysToLeave.forEach(this.performLeave); 13862 }, 13863 13864 performEnter: function(key) { 13865 this.currentlyTransitioningKeys[key] = true; 13866 13867 var component = this.refs[key]; 13868 13869 if (component.componentWillEnter) { 13870 component.componentWillEnter( 13871 this._handleDoneEntering.bind(this, key) 13872 ); 13873 } else { 13874 this._handleDoneEntering(key); 13875 } 13876 }, 13877 13878 _handleDoneEntering: function(key) { 13879 var component = this.refs[key]; 13880 if (component.componentDidEnter) { 13881 component.componentDidEnter(); 13882 } 13883 13884 delete this.currentlyTransitioningKeys[key]; 13885 13886 var currentChildMapping = ReactTransitionChildMapping.getChildMapping( 13887 this.props.children 13888 ); 13889 13890 if (!currentChildMapping.hasOwnProperty(key)) { 13891 // This was removed before it had fully entered. Remove it. 13892 this.performLeave(key); 13893 } 13894 }, 13895 13896 performLeave: function(key) { 13897 this.currentlyTransitioningKeys[key] = true; 13898 13899 var component = this.refs[key]; 13900 if (component.componentWillLeave) { 13901 component.componentWillLeave(this._handleDoneLeaving.bind(this, key)); 13902 } else { 13903 // Note that this is somewhat dangerous b/c it calls setState() 13904 // again, effectively mutating the component before all the work 13905 // is done. 13906 this._handleDoneLeaving(key); 13907 } 13908 }, 13909 13910 _handleDoneLeaving: function(key) { 13911 var component = this.refs[key]; 13912 13913 if (component.componentDidLeave) { 13914 component.componentDidLeave(); 13915 } 13916 13917 delete this.currentlyTransitioningKeys[key]; 13918 13919 var currentChildMapping = ReactTransitionChildMapping.getChildMapping( 13920 this.props.children 13921 ); 13922 13923 if (currentChildMapping.hasOwnProperty(key)) { 13924 // This entered again before it fully left. Add it again. 13925 this.performEnter(key); 13926 } else { 13927 var newChildren = merge(this.state.children); 13928 delete newChildren[key]; 13929 this.setState({children: newChildren}); 13930 } 13931 }, 13932 13933 render: function() { 13934 // TODO: we could get rid of the need for the wrapper node 13935 // by cloning a single child 13936 var childrenToRender = {}; 13937 for (var key in this.state.children) { 13938 var child = this.state.children[key]; 13939 if (child) { 13940 // You may need to apply reactive updates to a child as it is leaving. 13941 // The normal React way to do it won't work since the child will have 13942 // already been removed. In case you need this behavior you can provide 13943 // a childFactory function to wrap every child, even the ones that are 13944 // leaving. 13945 childrenToRender[key] = cloneWithProps( 13946 this.props.childFactory(child), 13947 {ref: key} 13948 ); 13949 } 13950 } 13951 return this.transferPropsTo(this.props.component(null, childrenToRender)); 13952 } 13953 }); 13954 13955 module.exports = ReactTransitionGroup; 13956 13957 },{"./React":26,"./ReactTransitionChildMapping":78,"./cloneWithProps":100,"./emptyFunction":109,"./merge":134}],81:[function(_dereq_,module,exports){ 13958 /** 13959 * Copyright 2013-2014 Facebook, Inc. 13960 * 13961 * Licensed under the Apache License, Version 2.0 (the "License"); 13962 * you may not use this file except in compliance with the License. 13963 * You may obtain a copy of the License at 13964 * 13965 * http://www.apache.org/licenses/LICENSE-2.0 13966 * 13967 * Unless required by applicable law or agreed to in writing, software 13968 * distributed under the License is distributed on an "AS IS" BASIS, 13969 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13970 * See the License for the specific language governing permissions and 13971 * limitations under the License. 13972 * 13973 * @providesModule ReactUpdates 13974 */ 13975 13976 "use strict"; 13977 13978 var ReactPerf = _dereq_("./ReactPerf"); 13979 13980 var invariant = _dereq_("./invariant"); 13981 13982 var dirtyComponents = []; 13983 13984 var batchingStrategy = null; 13985 13986 function ensureBatchingStrategy() { 13987 ("production" !== "development" ? invariant(batchingStrategy, 'ReactUpdates: must inject a batching strategy') : invariant(batchingStrategy)); 13988 } 13989 13990 function batchedUpdates(callback, param) { 13991 ensureBatchingStrategy(); 13992 batchingStrategy.batchedUpdates(callback, param); 13993 } 13994 13995 /** 13996 * Array comparator for ReactComponents by owner depth 13997 * 13998 * @param {ReactComponent} c1 first component you're comparing 13999 * @param {ReactComponent} c2 second component you're comparing 14000 * @return {number} Return value usable by Array.prototype.sort(). 14001 */ 14002 function mountDepthComparator(c1, c2) { 14003 return c1._mountDepth - c2._mountDepth; 14004 } 14005 14006 function runBatchedUpdates() { 14007 // Since reconciling a component higher in the owner hierarchy usually (not 14008 // always -- see shouldComponentUpdate()) will reconcile children, reconcile 14009 // them before their children by sorting the array. 14010 14011 dirtyComponents.sort(mountDepthComparator); 14012 14013 for (var i = 0; i < dirtyComponents.length; i++) { 14014 // If a component is unmounted before pending changes apply, ignore them 14015 // TODO: Queue unmounts in the same list to avoid this happening at all 14016 var component = dirtyComponents[i]; 14017 if (component.isMounted()) { 14018 // If performUpdateIfNecessary happens to enqueue any new updates, we 14019 // shouldn't execute the callbacks until the next render happens, so 14020 // stash the callbacks first 14021 var callbacks = component._pendingCallbacks; 14022 component._pendingCallbacks = null; 14023 component.performUpdateIfNecessary(); 14024 if (callbacks) { 14025 for (var j = 0; j < callbacks.length; j++) { 14026 callbacks[j].call(component); 14027 } 14028 } 14029 } 14030 } 14031 } 14032 14033 function clearDirtyComponents() { 14034 dirtyComponents.length = 0; 14035 } 14036 14037 var flushBatchedUpdates = ReactPerf.measure( 14038 'ReactUpdates', 14039 'flushBatchedUpdates', 14040 function() { 14041 // Run these in separate functions so the JIT can optimize 14042 try { 14043 runBatchedUpdates(); 14044 } finally { 14045 clearDirtyComponents(); 14046 } 14047 } 14048 ); 14049 14050 /** 14051 * Mark a component as needing a rerender, adding an optional callback to a 14052 * list of functions which will be executed once the rerender occurs. 14053 */ 14054 function enqueueUpdate(component, callback) { 14055 ("production" !== "development" ? invariant( 14056 !callback || typeof callback === "function", 14057 'enqueueUpdate(...): You called `setProps`, `replaceProps`, ' + 14058 '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + 14059 'isn\'t callable.' 14060 ) : invariant(!callback || typeof callback === "function")); 14061 ensureBatchingStrategy(); 14062 14063 if (!batchingStrategy.isBatchingUpdates) { 14064 component.performUpdateIfNecessary(); 14065 callback && callback.call(component); 14066 return; 14067 } 14068 14069 dirtyComponents.push(component); 14070 14071 if (callback) { 14072 if (component._pendingCallbacks) { 14073 component._pendingCallbacks.push(callback); 14074 } else { 14075 component._pendingCallbacks = [callback]; 14076 } 14077 } 14078 } 14079 14080 var ReactUpdatesInjection = { 14081 injectBatchingStrategy: function(_batchingStrategy) { 14082 ("production" !== "development" ? invariant( 14083 _batchingStrategy, 14084 'ReactUpdates: must provide a batching strategy' 14085 ) : invariant(_batchingStrategy)); 14086 ("production" !== "development" ? invariant( 14087 typeof _batchingStrategy.batchedUpdates === 'function', 14088 'ReactUpdates: must provide a batchedUpdates() function' 14089 ) : invariant(typeof _batchingStrategy.batchedUpdates === 'function')); 14090 ("production" !== "development" ? invariant( 14091 typeof _batchingStrategy.isBatchingUpdates === 'boolean', 14092 'ReactUpdates: must provide an isBatchingUpdates boolean attribute' 14093 ) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean')); 14094 batchingStrategy = _batchingStrategy; 14095 } 14096 }; 14097 14098 var ReactUpdates = { 14099 batchedUpdates: batchedUpdates, 14100 enqueueUpdate: enqueueUpdate, 14101 flushBatchedUpdates: flushBatchedUpdates, 14102 injection: ReactUpdatesInjection 14103 }; 14104 14105 module.exports = ReactUpdates; 14106 14107 },{"./ReactPerf":65,"./invariant":125}],82:[function(_dereq_,module,exports){ 14108 /** 14109 * Copyright 2013-2014 Facebook, Inc. 14110 * 14111 * Licensed under the Apache License, Version 2.0 (the "License"); 14112 * you may not use this file except in compliance with the License. 14113 * You may obtain a copy of the License at 14114 * 14115 * http://www.apache.org/licenses/LICENSE-2.0 14116 * 14117 * Unless required by applicable law or agreed to in writing, software 14118 * distributed under the License is distributed on an "AS IS" BASIS, 14119 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14120 * See the License for the specific language governing permissions and 14121 * limitations under the License. 14122 * 14123 * @providesModule ReactWithAddons 14124 */ 14125 14126 /** 14127 * This module exists purely in the open source project, and is meant as a way 14128 * to create a separate standalone build of React. This build has "addons", or 14129 * functionality we've built and think might be useful but doesn't have a good 14130 * place to live inside React core. 14131 */ 14132 14133 "use strict"; 14134 14135 var LinkedStateMixin = _dereq_("./LinkedStateMixin"); 14136 var React = _dereq_("./React"); 14137 var ReactCSSTransitionGroup = _dereq_("./ReactCSSTransitionGroup"); 14138 var ReactTransitionGroup = _dereq_("./ReactTransitionGroup"); 14139 var ReactCSSTransitionGroup = _dereq_("./ReactCSSTransitionGroup"); 14140 14141 var cx = _dereq_("./cx"); 14142 var cloneWithProps = _dereq_("./cloneWithProps"); 14143 var update = _dereq_("./update"); 14144 14145 React.addons = { 14146 LinkedStateMixin: LinkedStateMixin, 14147 CSSTransitionGroup: ReactCSSTransitionGroup, 14148 TransitionGroup: ReactTransitionGroup, 14149 14150 classSet: cx, 14151 cloneWithProps: cloneWithProps, 14152 update: update 14153 }; 14154 14155 if ("production" !== "development") { 14156 React.addons.TestUtils = _dereq_("./ReactTestUtils"); 14157 } 14158 14159 module.exports = React; 14160 14161 14162 },{"./LinkedStateMixin":22,"./React":26,"./ReactCSSTransitionGroup":28,"./ReactTestUtils":76,"./ReactTransitionGroup":80,"./cloneWithProps":100,"./cx":107,"./update":147}],83:[function(_dereq_,module,exports){ 14163 /** 14164 * Copyright 2013-2014 Facebook, Inc. 14165 * 14166 * Licensed under the Apache License, Version 2.0 (the "License"); 14167 * you may not use this file except in compliance with the License. 14168 * You may obtain a copy of the License at 14169 * 14170 * http://www.apache.org/licenses/LICENSE-2.0 14171 * 14172 * Unless required by applicable law or agreed to in writing, software 14173 * distributed under the License is distributed on an "AS IS" BASIS, 14174 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14175 * See the License for the specific language governing permissions and 14176 * limitations under the License. 14177 * 14178 * @providesModule SelectEventPlugin 14179 */ 14180 14181 "use strict"; 14182 14183 var EventConstants = _dereq_("./EventConstants"); 14184 var EventPropagators = _dereq_("./EventPropagators"); 14185 var ReactInputSelection = _dereq_("./ReactInputSelection"); 14186 var SyntheticEvent = _dereq_("./SyntheticEvent"); 14187 14188 var getActiveElement = _dereq_("./getActiveElement"); 14189 var isTextInputElement = _dereq_("./isTextInputElement"); 14190 var keyOf = _dereq_("./keyOf"); 14191 var shallowEqual = _dereq_("./shallowEqual"); 14192 14193 var topLevelTypes = EventConstants.topLevelTypes; 14194 14195 var eventTypes = { 14196 select: { 14197 phasedRegistrationNames: { 14198 bubbled: keyOf({onSelect: null}), 14199 captured: keyOf({onSelectCapture: null}) 14200 }, 14201 dependencies: [ 14202 topLevelTypes.topBlur, 14203 topLevelTypes.topContextMenu, 14204 topLevelTypes.topFocus, 14205 topLevelTypes.topKeyDown, 14206 topLevelTypes.topMouseDown, 14207 topLevelTypes.topMouseUp, 14208 topLevelTypes.topSelectionChange 14209 ] 14210 } 14211 }; 14212 14213 var activeElement = null; 14214 var activeElementID = null; 14215 var lastSelection = null; 14216 var mouseDown = false; 14217 14218 /** 14219 * Get an object which is a unique representation of the current selection. 14220 * 14221 * The return value will not be consistent across nodes or browsers, but 14222 * two identical selections on the same node will return identical objects. 14223 * 14224 * @param {DOMElement} node 14225 * @param {object} 14226 */ 14227 function getSelection(node) { 14228 if ('selectionStart' in node && 14229 ReactInputSelection.hasSelectionCapabilities(node)) { 14230 return { 14231 start: node.selectionStart, 14232 end: node.selectionEnd 14233 }; 14234 } else if (document.selection) { 14235 var range = document.selection.createRange(); 14236 return { 14237 parentElement: range.parentElement(), 14238 text: range.text, 14239 top: range.boundingTop, 14240 left: range.boundingLeft 14241 }; 14242 } else { 14243 var selection = window.getSelection(); 14244 return { 14245 anchorNode: selection.anchorNode, 14246 anchorOffset: selection.anchorOffset, 14247 focusNode: selection.focusNode, 14248 focusOffset: selection.focusOffset 14249 }; 14250 } 14251 } 14252 14253 /** 14254 * Poll selection to see whether it's changed. 14255 * 14256 * @param {object} nativeEvent 14257 * @return {?SyntheticEvent} 14258 */ 14259 function constructSelectEvent(nativeEvent) { 14260 // Ensure we have the right element, and that the user is not dragging a 14261 // selection (this matches native `select` event behavior). In HTML5, select 14262 // fires only on input and textarea thus if there's no focused element we 14263 // won't dispatch. 14264 if (mouseDown || 14265 activeElement == null || 14266 activeElement != getActiveElement()) { 14267 return; 14268 } 14269 14270 // Only fire when selection has actually changed. 14271 var currentSelection = getSelection(activeElement); 14272 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { 14273 lastSelection = currentSelection; 14274 14275 var syntheticEvent = SyntheticEvent.getPooled( 14276 eventTypes.select, 14277 activeElementID, 14278 nativeEvent 14279 ); 14280 14281 syntheticEvent.type = 'select'; 14282 syntheticEvent.target = activeElement; 14283 14284 EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent); 14285 14286 return syntheticEvent; 14287 } 14288 } 14289 14290 /** 14291 * This plugin creates an `onSelect` event that normalizes select events 14292 * across form elements. 14293 * 14294 * Supported elements are: 14295 * - input (see `isTextInputElement`) 14296 * - textarea 14297 * - contentEditable 14298 * 14299 * This differs from native browser implementations in the following ways: 14300 * - Fires on contentEditable fields as well as inputs. 14301 * - Fires for collapsed selection. 14302 * - Fires after user input. 14303 */ 14304 var SelectEventPlugin = { 14305 14306 eventTypes: eventTypes, 14307 14308 /** 14309 * @param {string} topLevelType Record from `EventConstants`. 14310 * @param {DOMEventTarget} topLevelTarget The listening component root node. 14311 * @param {string} topLevelTargetID ID of `topLevelTarget`. 14312 * @param {object} nativeEvent Native browser event. 14313 * @return {*} An accumulation of synthetic events. 14314 * @see {EventPluginHub.extractEvents} 14315 */ 14316 extractEvents: function( 14317 topLevelType, 14318 topLevelTarget, 14319 topLevelTargetID, 14320 nativeEvent) { 14321 14322 switch (topLevelType) { 14323 // Track the input node that has focus. 14324 case topLevelTypes.topFocus: 14325 if (isTextInputElement(topLevelTarget) || 14326 topLevelTarget.contentEditable === 'true') { 14327 activeElement = topLevelTarget; 14328 activeElementID = topLevelTargetID; 14329 lastSelection = null; 14330 } 14331 break; 14332 case topLevelTypes.topBlur: 14333 activeElement = null; 14334 activeElementID = null; 14335 lastSelection = null; 14336 break; 14337 14338 // Don't fire the event while the user is dragging. This matches the 14339 // semantics of the native select event. 14340 case topLevelTypes.topMouseDown: 14341 mouseDown = true; 14342 break; 14343 case topLevelTypes.topContextMenu: 14344 case topLevelTypes.topMouseUp: 14345 mouseDown = false; 14346 return constructSelectEvent(nativeEvent); 14347 14348 // Chrome and IE fire non-standard event when selection is changed (and 14349 // sometimes when it hasn't). 14350 // Firefox doesn't support selectionchange, so check selection status 14351 // after each key entry. The selection changes after keydown and before 14352 // keyup, but we check on keydown as well in the case of holding down a 14353 // key, when multiple keydown events are fired but only one keyup is. 14354 case topLevelTypes.topSelectionChange: 14355 case topLevelTypes.topKeyDown: 14356 case topLevelTypes.topKeyUp: 14357 return constructSelectEvent(nativeEvent); 14358 } 14359 } 14360 }; 14361 14362 module.exports = SelectEventPlugin; 14363 14364 },{"./EventConstants":15,"./EventPropagators":20,"./ReactInputSelection":56,"./SyntheticEvent":89,"./getActiveElement":115,"./isTextInputElement":128,"./keyOf":132,"./shallowEqual":143}],84:[function(_dereq_,module,exports){ 14365 /** 14366 * Copyright 2013-2014 Facebook, Inc. 14367 * 14368 * Licensed under the Apache License, Version 2.0 (the "License"); 14369 * you may not use this file except in compliance with the License. 14370 * You may obtain a copy of the License at 14371 * 14372 * http://www.apache.org/licenses/LICENSE-2.0 14373 * 14374 * Unless required by applicable law or agreed to in writing, software 14375 * distributed under the License is distributed on an "AS IS" BASIS, 14376 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14377 * See the License for the specific language governing permissions and 14378 * limitations under the License. 14379 * 14380 * @providesModule ServerReactRootIndex 14381 * @typechecks 14382 */ 14383 14384 "use strict"; 14385 14386 /** 14387 * Size of the reactRoot ID space. We generate random numbers for React root 14388 * IDs and if there's a collision the events and DOM update system will 14389 * get confused. In the future we need a way to generate GUIDs but for 14390 * now this will work on a smaller scale. 14391 */ 14392 var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53); 14393 14394 var ServerReactRootIndex = { 14395 createReactRootIndex: function() { 14396 return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX); 14397 } 14398 }; 14399 14400 module.exports = ServerReactRootIndex; 14401 14402 },{}],85:[function(_dereq_,module,exports){ 14403 /** 14404 * Copyright 2013-2014 Facebook, Inc. 14405 * 14406 * Licensed under the Apache License, Version 2.0 (the "License"); 14407 * you may not use this file except in compliance with the License. 14408 * You may obtain a copy of the License at 14409 * 14410 * http://www.apache.org/licenses/LICENSE-2.0 14411 * 14412 * Unless required by applicable law or agreed to in writing, software 14413 * distributed under the License is distributed on an "AS IS" BASIS, 14414 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14415 * See the License for the specific language governing permissions and 14416 * limitations under the License. 14417 * 14418 * @providesModule SimpleEventPlugin 14419 */ 14420 14421 "use strict"; 14422 14423 var EventConstants = _dereq_("./EventConstants"); 14424 var EventPluginUtils = _dereq_("./EventPluginUtils"); 14425 var EventPropagators = _dereq_("./EventPropagators"); 14426 var SyntheticClipboardEvent = _dereq_("./SyntheticClipboardEvent"); 14427 var SyntheticEvent = _dereq_("./SyntheticEvent"); 14428 var SyntheticFocusEvent = _dereq_("./SyntheticFocusEvent"); 14429 var SyntheticKeyboardEvent = _dereq_("./SyntheticKeyboardEvent"); 14430 var SyntheticMouseEvent = _dereq_("./SyntheticMouseEvent"); 14431 var SyntheticDragEvent = _dereq_("./SyntheticDragEvent"); 14432 var SyntheticTouchEvent = _dereq_("./SyntheticTouchEvent"); 14433 var SyntheticUIEvent = _dereq_("./SyntheticUIEvent"); 14434 var SyntheticWheelEvent = _dereq_("./SyntheticWheelEvent"); 14435 14436 var invariant = _dereq_("./invariant"); 14437 var keyOf = _dereq_("./keyOf"); 14438 14439 var topLevelTypes = EventConstants.topLevelTypes; 14440 14441 var eventTypes = { 14442 blur: { 14443 phasedRegistrationNames: { 14444 bubbled: keyOf({onBlur: true}), 14445 captured: keyOf({onBlurCapture: true}) 14446 } 14447 }, 14448 click: { 14449 phasedRegistrationNames: { 14450 bubbled: keyOf({onClick: true}), 14451 captured: keyOf({onClickCapture: true}) 14452 } 14453 }, 14454 contextMenu: { 14455 phasedRegistrationNames: { 14456 bubbled: keyOf({onContextMenu: true}), 14457 captured: keyOf({onContextMenuCapture: true}) 14458 } 14459 }, 14460 copy: { 14461 phasedRegistrationNames: { 14462 bubbled: keyOf({onCopy: true}), 14463 captured: keyOf({onCopyCapture: true}) 14464 } 14465 }, 14466 cut: { 14467 phasedRegistrationNames: { 14468 bubbled: keyOf({onCut: true}), 14469 captured: keyOf({onCutCapture: true}) 14470 } 14471 }, 14472 doubleClick: { 14473 phasedRegistrationNames: { 14474 bubbled: keyOf({onDoubleClick: true}), 14475 captured: keyOf({onDoubleClickCapture: true}) 14476 } 14477 }, 14478 drag: { 14479 phasedRegistrationNames: { 14480 bubbled: keyOf({onDrag: true}), 14481 captured: keyOf({onDragCapture: true}) 14482 } 14483 }, 14484 dragEnd: { 14485 phasedRegistrationNames: { 14486 bubbled: keyOf({onDragEnd: true}), 14487 captured: keyOf({onDragEndCapture: true}) 14488 } 14489 }, 14490 dragEnter: { 14491 phasedRegistrationNames: { 14492 bubbled: keyOf({onDragEnter: true}), 14493 captured: keyOf({onDragEnterCapture: true}) 14494 } 14495 }, 14496 dragExit: { 14497 phasedRegistrationNames: { 14498 bubbled: keyOf({onDragExit: true}), 14499 captured: keyOf({onDragExitCapture: true}) 14500 } 14501 }, 14502 dragLeave: { 14503 phasedRegistrationNames: { 14504 bubbled: keyOf({onDragLeave: true}), 14505 captured: keyOf({onDragLeaveCapture: true}) 14506 } 14507 }, 14508 dragOver: { 14509 phasedRegistrationNames: { 14510 bubbled: keyOf({onDragOver: true}), 14511 captured: keyOf({onDragOverCapture: true}) 14512 } 14513 }, 14514 dragStart: { 14515 phasedRegistrationNames: { 14516 bubbled: keyOf({onDragStart: true}), 14517 captured: keyOf({onDragStartCapture: true}) 14518 } 14519 }, 14520 drop: { 14521 phasedRegistrationNames: { 14522 bubbled: keyOf({onDrop: true}), 14523 captured: keyOf({onDropCapture: true}) 14524 } 14525 }, 14526 focus: { 14527 phasedRegistrationNames: { 14528 bubbled: keyOf({onFocus: true}), 14529 captured: keyOf({onFocusCapture: true}) 14530 } 14531 }, 14532 input: { 14533 phasedRegistrationNames: { 14534 bubbled: keyOf({onInput: true}), 14535 captured: keyOf({onInputCapture: true}) 14536 } 14537 }, 14538 keyDown: { 14539 phasedRegistrationNames: { 14540 bubbled: keyOf({onKeyDown: true}), 14541 captured: keyOf({onKeyDownCapture: true}) 14542 } 14543 }, 14544 keyPress: { 14545 phasedRegistrationNames: { 14546 bubbled: keyOf({onKeyPress: true}), 14547 captured: keyOf({onKeyPressCapture: true}) 14548 } 14549 }, 14550 keyUp: { 14551 phasedRegistrationNames: { 14552 bubbled: keyOf({onKeyUp: true}), 14553 captured: keyOf({onKeyUpCapture: true}) 14554 } 14555 }, 14556 load: { 14557 phasedRegistrationNames: { 14558 bubbled: keyOf({onLoad: true}), 14559 captured: keyOf({onLoadCapture: true}) 14560 } 14561 }, 14562 error: { 14563 phasedRegistrationNames: { 14564 bubbled: keyOf({onError: true}), 14565 captured: keyOf({onErrorCapture: true}) 14566 } 14567 }, 14568 // Note: We do not allow listening to mouseOver events. Instead, use the 14569 // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`. 14570 mouseDown: { 14571 phasedRegistrationNames: { 14572 bubbled: keyOf({onMouseDown: true}), 14573 captured: keyOf({onMouseDownCapture: true}) 14574 } 14575 }, 14576 mouseMove: { 14577 phasedRegistrationNames: { 14578 bubbled: keyOf({onMouseMove: true}), 14579 captured: keyOf({onMouseMoveCapture: true}) 14580 } 14581 }, 14582 mouseOut: { 14583 phasedRegistrationNames: { 14584 bubbled: keyOf({onMouseOut: true}), 14585 captured: keyOf({onMouseOutCapture: true}) 14586 } 14587 }, 14588 mouseOver: { 14589 phasedRegistrationNames: { 14590 bubbled: keyOf({onMouseOver: true}), 14591 captured: keyOf({onMouseOverCapture: true}) 14592 } 14593 }, 14594 mouseUp: { 14595 phasedRegistrationNames: { 14596 bubbled: keyOf({onMouseUp: true}), 14597 captured: keyOf({onMouseUpCapture: true}) 14598 } 14599 }, 14600 paste: { 14601 phasedRegistrationNames: { 14602 bubbled: keyOf({onPaste: true}), 14603 captured: keyOf({onPasteCapture: true}) 14604 } 14605 }, 14606 reset: { 14607 phasedRegistrationNames: { 14608 bubbled: keyOf({onReset: true}), 14609 captured: keyOf({onResetCapture: true}) 14610 } 14611 }, 14612 scroll: { 14613 phasedRegistrationNames: { 14614 bubbled: keyOf({onScroll: true}), 14615 captured: keyOf({onScrollCapture: true}) 14616 } 14617 }, 14618 submit: { 14619 phasedRegistrationNames: { 14620 bubbled: keyOf({onSubmit: true}), 14621 captured: keyOf({onSubmitCapture: true}) 14622 } 14623 }, 14624 touchCancel: { 14625 phasedRegistrationNames: { 14626 bubbled: keyOf({onTouchCancel: true}), 14627 captured: keyOf({onTouchCancelCapture: true}) 14628 } 14629 }, 14630 touchEnd: { 14631 phasedRegistrationNames: { 14632 bubbled: keyOf({onTouchEnd: true}), 14633 captured: keyOf({onTouchEndCapture: true}) 14634 } 14635 }, 14636 touchMove: { 14637 phasedRegistrationNames: { 14638 bubbled: keyOf({onTouchMove: true}), 14639 captured: keyOf({onTouchMoveCapture: true}) 14640 } 14641 }, 14642 touchStart: { 14643 phasedRegistrationNames: { 14644 bubbled: keyOf({onTouchStart: true}), 14645 captured: keyOf({onTouchStartCapture: true}) 14646 } 14647 }, 14648 wheel: { 14649 phasedRegistrationNames: { 14650 bubbled: keyOf({onWheel: true}), 14651 captured: keyOf({onWheelCapture: true}) 14652 } 14653 } 14654 }; 14655 14656 var topLevelEventsToDispatchConfig = { 14657 topBlur: eventTypes.blur, 14658 topClick: eventTypes.click, 14659 topContextMenu: eventTypes.contextMenu, 14660 topCopy: eventTypes.copy, 14661 topCut: eventTypes.cut, 14662 topDoubleClick: eventTypes.doubleClick, 14663 topDrag: eventTypes.drag, 14664 topDragEnd: eventTypes.dragEnd, 14665 topDragEnter: eventTypes.dragEnter, 14666 topDragExit: eventTypes.dragExit, 14667 topDragLeave: eventTypes.dragLeave, 14668 topDragOver: eventTypes.dragOver, 14669 topDragStart: eventTypes.dragStart, 14670 topDrop: eventTypes.drop, 14671 topError: eventTypes.error, 14672 topFocus: eventTypes.focus, 14673 topInput: eventTypes.input, 14674 topKeyDown: eventTypes.keyDown, 14675 topKeyPress: eventTypes.keyPress, 14676 topKeyUp: eventTypes.keyUp, 14677 topLoad: eventTypes.load, 14678 topMouseDown: eventTypes.mouseDown, 14679 topMouseMove: eventTypes.mouseMove, 14680 topMouseOut: eventTypes.mouseOut, 14681 topMouseOver: eventTypes.mouseOver, 14682 topMouseUp: eventTypes.mouseUp, 14683 topPaste: eventTypes.paste, 14684 topReset: eventTypes.reset, 14685 topScroll: eventTypes.scroll, 14686 topSubmit: eventTypes.submit, 14687 topTouchCancel: eventTypes.touchCancel, 14688 topTouchEnd: eventTypes.touchEnd, 14689 topTouchMove: eventTypes.touchMove, 14690 topTouchStart: eventTypes.touchStart, 14691 topWheel: eventTypes.wheel 14692 }; 14693 14694 for (var topLevelType in topLevelEventsToDispatchConfig) { 14695 topLevelEventsToDispatchConfig[topLevelType].dependencies = [topLevelType]; 14696 } 14697 14698 var SimpleEventPlugin = { 14699 14700 eventTypes: eventTypes, 14701 14702 /** 14703 * Same as the default implementation, except cancels the event when return 14704 * value is false. 14705 * 14706 * @param {object} Event to be dispatched. 14707 * @param {function} Application-level callback. 14708 * @param {string} domID DOM ID to pass to the callback. 14709 */ 14710 executeDispatch: function(event, listener, domID) { 14711 var returnValue = EventPluginUtils.executeDispatch(event, listener, domID); 14712 if (returnValue === false) { 14713 event.stopPropagation(); 14714 event.preventDefault(); 14715 } 14716 }, 14717 14718 /** 14719 * @param {string} topLevelType Record from `EventConstants`. 14720 * @param {DOMEventTarget} topLevelTarget The listening component root node. 14721 * @param {string} topLevelTargetID ID of `topLevelTarget`. 14722 * @param {object} nativeEvent Native browser event. 14723 * @return {*} An accumulation of synthetic events. 14724 * @see {EventPluginHub.extractEvents} 14725 */ 14726 extractEvents: function( 14727 topLevelType, 14728 topLevelTarget, 14729 topLevelTargetID, 14730 nativeEvent) { 14731 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; 14732 if (!dispatchConfig) { 14733 return null; 14734 } 14735 var EventConstructor; 14736 switch (topLevelType) { 14737 case topLevelTypes.topInput: 14738 case topLevelTypes.topLoad: 14739 case topLevelTypes.topError: 14740 case topLevelTypes.topReset: 14741 case topLevelTypes.topSubmit: 14742 // HTML Events 14743 // @see http://www.w3.org/TR/html5/index.html#events-0 14744 EventConstructor = SyntheticEvent; 14745 break; 14746 case topLevelTypes.topKeyDown: 14747 case topLevelTypes.topKeyPress: 14748 case topLevelTypes.topKeyUp: 14749 EventConstructor = SyntheticKeyboardEvent; 14750 break; 14751 case topLevelTypes.topBlur: 14752 case topLevelTypes.topFocus: 14753 EventConstructor = SyntheticFocusEvent; 14754 break; 14755 case topLevelTypes.topClick: 14756 // Firefox creates a click event on right mouse clicks. This removes the 14757 // unwanted click events. 14758 if (nativeEvent.button === 2) { 14759 return null; 14760 } 14761 /* falls through */ 14762 case topLevelTypes.topContextMenu: 14763 case topLevelTypes.topDoubleClick: 14764 case topLevelTypes.topMouseDown: 14765 case topLevelTypes.topMouseMove: 14766 case topLevelTypes.topMouseOut: 14767 case topLevelTypes.topMouseOver: 14768 case topLevelTypes.topMouseUp: 14769 EventConstructor = SyntheticMouseEvent; 14770 break; 14771 case topLevelTypes.topDrag: 14772 case topLevelTypes.topDragEnd: 14773 case topLevelTypes.topDragEnter: 14774 case topLevelTypes.topDragExit: 14775 case topLevelTypes.topDragLeave: 14776 case topLevelTypes.topDragOver: 14777 case topLevelTypes.topDragStart: 14778 case topLevelTypes.topDrop: 14779 EventConstructor = SyntheticDragEvent; 14780 break; 14781 case topLevelTypes.topTouchCancel: 14782 case topLevelTypes.topTouchEnd: 14783 case topLevelTypes.topTouchMove: 14784 case topLevelTypes.topTouchStart: 14785 EventConstructor = SyntheticTouchEvent; 14786 break; 14787 case topLevelTypes.topScroll: 14788 EventConstructor = SyntheticUIEvent; 14789 break; 14790 case topLevelTypes.topWheel: 14791 EventConstructor = SyntheticWheelEvent; 14792 break; 14793 case topLevelTypes.topCopy: 14794 case topLevelTypes.topCut: 14795 case topLevelTypes.topPaste: 14796 EventConstructor = SyntheticClipboardEvent; 14797 break; 14798 } 14799 ("production" !== "development" ? invariant( 14800 EventConstructor, 14801 'SimpleEventPlugin: Unhandled event type, `%s`.', 14802 topLevelType 14803 ) : invariant(EventConstructor)); 14804 var event = EventConstructor.getPooled( 14805 dispatchConfig, 14806 topLevelTargetID, 14807 nativeEvent 14808 ); 14809 EventPropagators.accumulateTwoPhaseDispatches(event); 14810 return event; 14811 } 14812 14813 }; 14814 14815 module.exports = SimpleEventPlugin; 14816 14817 },{"./EventConstants":15,"./EventPluginUtils":19,"./EventPropagators":20,"./SyntheticClipboardEvent":86,"./SyntheticDragEvent":88,"./SyntheticEvent":89,"./SyntheticFocusEvent":90,"./SyntheticKeyboardEvent":91,"./SyntheticMouseEvent":92,"./SyntheticTouchEvent":93,"./SyntheticUIEvent":94,"./SyntheticWheelEvent":95,"./invariant":125,"./keyOf":132}],86:[function(_dereq_,module,exports){ 14818 /** 14819 * Copyright 2013-2014 Facebook, Inc. 14820 * 14821 * Licensed under the Apache License, Version 2.0 (the "License"); 14822 * you may not use this file except in compliance with the License. 14823 * You may obtain a copy of the License at 14824 * 14825 * http://www.apache.org/licenses/LICENSE-2.0 14826 * 14827 * Unless required by applicable law or agreed to in writing, software 14828 * distributed under the License is distributed on an "AS IS" BASIS, 14829 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14830 * See the License for the specific language governing permissions and 14831 * limitations under the License. 14832 * 14833 * @providesModule SyntheticClipboardEvent 14834 * @typechecks static-only 14835 */ 14836 14837 "use strict"; 14838 14839 var SyntheticEvent = _dereq_("./SyntheticEvent"); 14840 14841 /** 14842 * @interface Event 14843 * @see http://www.w3.org/TR/clipboard-apis/ 14844 */ 14845 var ClipboardEventInterface = { 14846 clipboardData: function(event) { 14847 return ( 14848 'clipboardData' in event ? 14849 event.clipboardData : 14850 window.clipboardData 14851 ); 14852 } 14853 }; 14854 14855 /** 14856 * @param {object} dispatchConfig Configuration used to dispatch this event. 14857 * @param {string} dispatchMarker Marker identifying the event target. 14858 * @param {object} nativeEvent Native browser event. 14859 * @extends {SyntheticUIEvent} 14860 */ 14861 function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent) { 14862 SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); 14863 } 14864 14865 SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface); 14866 14867 module.exports = SyntheticClipboardEvent; 14868 14869 14870 },{"./SyntheticEvent":89}],87:[function(_dereq_,module,exports){ 14871 /** 14872 * Copyright 2013-2014 Facebook, Inc. 14873 * 14874 * Licensed under the Apache License, Version 2.0 (the "License"); 14875 * you may not use this file except in compliance with the License. 14876 * You may obtain a copy of the License at 14877 * 14878 * http://www.apache.org/licenses/LICENSE-2.0 14879 * 14880 * Unless required by applicable law or agreed to in writing, software 14881 * distributed under the License is distributed on an "AS IS" BASIS, 14882 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14883 * See the License for the specific language governing permissions and 14884 * limitations under the License. 14885 * 14886 * @providesModule SyntheticCompositionEvent 14887 * @typechecks static-only 14888 */ 14889 14890 "use strict"; 14891 14892 var SyntheticEvent = _dereq_("./SyntheticEvent"); 14893 14894 /** 14895 * @interface Event 14896 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents 14897 */ 14898 var CompositionEventInterface = { 14899 data: null 14900 }; 14901 14902 /** 14903 * @param {object} dispatchConfig Configuration used to dispatch this event. 14904 * @param {string} dispatchMarker Marker identifying the event target. 14905 * @param {object} nativeEvent Native browser event. 14906 * @extends {SyntheticUIEvent} 14907 */ 14908 function SyntheticCompositionEvent( 14909 dispatchConfig, 14910 dispatchMarker, 14911 nativeEvent) { 14912 SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); 14913 } 14914 14915 SyntheticEvent.augmentClass( 14916 SyntheticCompositionEvent, 14917 CompositionEventInterface 14918 ); 14919 14920 module.exports = SyntheticCompositionEvent; 14921 14922 14923 },{"./SyntheticEvent":89}],88:[function(_dereq_,module,exports){ 14924 /** 14925 * Copyright 2013-2014 Facebook, Inc. 14926 * 14927 * Licensed under the Apache License, Version 2.0 (the "License"); 14928 * you may not use this file except in compliance with the License. 14929 * You may obtain a copy of the License at 14930 * 14931 * http://www.apache.org/licenses/LICENSE-2.0 14932 * 14933 * Unless required by applicable law or agreed to in writing, software 14934 * distributed under the License is distributed on an "AS IS" BASIS, 14935 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14936 * See the License for the specific language governing permissions and 14937 * limitations under the License. 14938 * 14939 * @providesModule SyntheticDragEvent 14940 * @typechecks static-only 14941 */ 14942 14943 "use strict"; 14944 14945 var SyntheticMouseEvent = _dereq_("./SyntheticMouseEvent"); 14946 14947 /** 14948 * @interface DragEvent 14949 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 14950 */ 14951 var DragEventInterface = { 14952 dataTransfer: null 14953 }; 14954 14955 /** 14956 * @param {object} dispatchConfig Configuration used to dispatch this event. 14957 * @param {string} dispatchMarker Marker identifying the event target. 14958 * @param {object} nativeEvent Native browser event. 14959 * @extends {SyntheticUIEvent} 14960 */ 14961 function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent) { 14962 SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); 14963 } 14964 14965 SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface); 14966 14967 module.exports = SyntheticDragEvent; 14968 14969 },{"./SyntheticMouseEvent":92}],89:[function(_dereq_,module,exports){ 14970 /** 14971 * Copyright 2013-2014 Facebook, Inc. 14972 * 14973 * Licensed under the Apache License, Version 2.0 (the "License"); 14974 * you may not use this file except in compliance with the License. 14975 * You may obtain a copy of the License at 14976 * 14977 * http://www.apache.org/licenses/LICENSE-2.0 14978 * 14979 * Unless required by applicable law or agreed to in writing, software 14980 * distributed under the License is distributed on an "AS IS" BASIS, 14981 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14982 * See the License for the specific language governing permissions and 14983 * limitations under the License. 14984 * 14985 * @providesModule SyntheticEvent 14986 * @typechecks static-only 14987 */ 14988 14989 "use strict"; 14990 14991 var PooledClass = _dereq_("./PooledClass"); 14992 14993 var emptyFunction = _dereq_("./emptyFunction"); 14994 var getEventTarget = _dereq_("./getEventTarget"); 14995 var merge = _dereq_("./merge"); 14996 var mergeInto = _dereq_("./mergeInto"); 14997 14998 /** 14999 * @interface Event 15000 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 15001 */ 15002 var EventInterface = { 15003 type: null, 15004 target: getEventTarget, 15005 // currentTarget is set when dispatching; no use in copying it here 15006 currentTarget: emptyFunction.thatReturnsNull, 15007 eventPhase: null, 15008 bubbles: null, 15009 cancelable: null, 15010 timeStamp: function(event) { 15011 return event.timeStamp || Date.now(); 15012 }, 15013 defaultPrevented: null, 15014 isTrusted: null 15015 }; 15016 15017 /** 15018 * Synthetic events are dispatched by event plugins, typically in response to a 15019 * top-level event delegation handler. 15020 * 15021 * These systems should generally use pooling to reduce the frequency of garbage 15022 * collection. The system should check `isPersistent` to determine whether the 15023 * event should be released into the pool after being dispatched. Users that 15024 * need a persisted event should invoke `persist`. 15025 * 15026 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by 15027 * normalizing browser quirks. Subclasses do not necessarily have to implement a 15028 * DOM interface; custom application-specific events can also subclass this. 15029 * 15030 * @param {object} dispatchConfig Configuration used to dispatch this event. 15031 * @param {string} dispatchMarker Marker identifying the event target. 15032 * @param {object} nativeEvent Native browser event. 15033 */ 15034 function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) { 15035 this.dispatchConfig = dispatchConfig; 15036 this.dispatchMarker = dispatchMarker; 15037 this.nativeEvent = nativeEvent; 15038 15039 var Interface = this.constructor.Interface; 15040 for (var propName in Interface) { 15041 if (!Interface.hasOwnProperty(propName)) { 15042 continue; 15043 } 15044 var normalize = Interface[propName]; 15045 if (normalize) { 15046 this[propName] = normalize(nativeEvent); 15047 } else { 15048 this[propName] = nativeEvent[propName]; 15049 } 15050 } 15051 15052 var defaultPrevented = nativeEvent.defaultPrevented != null ? 15053 nativeEvent.defaultPrevented : 15054 nativeEvent.returnValue === false; 15055 if (defaultPrevented) { 15056 this.isDefaultPrevented = emptyFunction.thatReturnsTrue; 15057 } else { 15058 this.isDefaultPrevented = emptyFunction.thatReturnsFalse; 15059 } 15060 this.isPropagationStopped = emptyFunction.thatReturnsFalse; 15061 } 15062 15063 mergeInto(SyntheticEvent.prototype, { 15064 15065 preventDefault: function() { 15066 this.defaultPrevented = true; 15067 var event = this.nativeEvent; 15068 event.preventDefault ? event.preventDefault() : event.returnValue = false; 15069 this.isDefaultPrevented = emptyFunction.thatReturnsTrue; 15070 }, 15071 15072 stopPropagation: function() { 15073 var event = this.nativeEvent; 15074 event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; 15075 this.isPropagationStopped = emptyFunction.thatReturnsTrue; 15076 }, 15077 15078 /** 15079 * We release all dispatched `SyntheticEvent`s after each event loop, adding 15080 * them back into the pool. This allows a way to hold onto a reference that 15081 * won't be added back into the pool. 15082 */ 15083 persist: function() { 15084 this.isPersistent = emptyFunction.thatReturnsTrue; 15085 }, 15086 15087 /** 15088 * Checks if this event should be released back into the pool. 15089 * 15090 * @return {boolean} True if this should not be released, false otherwise. 15091 */ 15092 isPersistent: emptyFunction.thatReturnsFalse, 15093 15094 /** 15095 * `PooledClass` looks for `destructor` on each instance it releases. 15096 */ 15097 destructor: function() { 15098 var Interface = this.constructor.Interface; 15099 for (var propName in Interface) { 15100 this[propName] = null; 15101 } 15102 this.dispatchConfig = null; 15103 this.dispatchMarker = null; 15104 this.nativeEvent = null; 15105 } 15106 15107 }); 15108 15109 SyntheticEvent.Interface = EventInterface; 15110 15111 /** 15112 * Helper to reduce boilerplate when creating subclasses. 15113 * 15114 * @param {function} Class 15115 * @param {?object} Interface 15116 */ 15117 SyntheticEvent.augmentClass = function(Class, Interface) { 15118 var Super = this; 15119 15120 var prototype = Object.create(Super.prototype); 15121 mergeInto(prototype, Class.prototype); 15122 Class.prototype = prototype; 15123 Class.prototype.constructor = Class; 15124 15125 Class.Interface = merge(Super.Interface, Interface); 15126 Class.augmentClass = Super.augmentClass; 15127 15128 PooledClass.addPoolingTo(Class, PooledClass.threeArgumentPooler); 15129 }; 15130 15131 PooledClass.addPoolingTo(SyntheticEvent, PooledClass.threeArgumentPooler); 15132 15133 module.exports = SyntheticEvent; 15134 15135 },{"./PooledClass":25,"./emptyFunction":109,"./getEventTarget":117,"./merge":134,"./mergeInto":136}],90:[function(_dereq_,module,exports){ 15136 /** 15137 * Copyright 2013-2014 Facebook, Inc. 15138 * 15139 * Licensed under the Apache License, Version 2.0 (the "License"); 15140 * you may not use this file except in compliance with the License. 15141 * You may obtain a copy of the License at 15142 * 15143 * http://www.apache.org/licenses/LICENSE-2.0 15144 * 15145 * Unless required by applicable law or agreed to in writing, software 15146 * distributed under the License is distributed on an "AS IS" BASIS, 15147 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15148 * See the License for the specific language governing permissions and 15149 * limitations under the License. 15150 * 15151 * @providesModule SyntheticFocusEvent 15152 * @typechecks static-only 15153 */ 15154 15155 "use strict"; 15156 15157 var SyntheticUIEvent = _dereq_("./SyntheticUIEvent"); 15158 15159 /** 15160 * @interface FocusEvent 15161 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 15162 */ 15163 var FocusEventInterface = { 15164 relatedTarget: null 15165 }; 15166 15167 /** 15168 * @param {object} dispatchConfig Configuration used to dispatch this event. 15169 * @param {string} dispatchMarker Marker identifying the event target. 15170 * @param {object} nativeEvent Native browser event. 15171 * @extends {SyntheticUIEvent} 15172 */ 15173 function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent) { 15174 SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); 15175 } 15176 15177 SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface); 15178 15179 module.exports = SyntheticFocusEvent; 15180 15181 },{"./SyntheticUIEvent":94}],91:[function(_dereq_,module,exports){ 15182 /** 15183 * Copyright 2013-2014 Facebook, Inc. 15184 * 15185 * Licensed under the Apache License, Version 2.0 (the "License"); 15186 * you may not use this file except in compliance with the License. 15187 * You may obtain a copy of the License at 15188 * 15189 * http://www.apache.org/licenses/LICENSE-2.0 15190 * 15191 * Unless required by applicable law or agreed to in writing, software 15192 * distributed under the License is distributed on an "AS IS" BASIS, 15193 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15194 * See the License for the specific language governing permissions and 15195 * limitations under the License. 15196 * 15197 * @providesModule SyntheticKeyboardEvent 15198 * @typechecks static-only 15199 */ 15200 15201 "use strict"; 15202 15203 var SyntheticUIEvent = _dereq_("./SyntheticUIEvent"); 15204 15205 var getEventKey = _dereq_("./getEventKey"); 15206 15207 /** 15208 * @interface KeyboardEvent 15209 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 15210 */ 15211 var KeyboardEventInterface = { 15212 key: getEventKey, 15213 location: null, 15214 ctrlKey: null, 15215 shiftKey: null, 15216 altKey: null, 15217 metaKey: null, 15218 repeat: null, 15219 locale: null, 15220 // Legacy Interface 15221 'char': null, 15222 charCode: null, 15223 keyCode: null, 15224 which: null 15225 }; 15226 15227 /** 15228 * @param {object} dispatchConfig Configuration used to dispatch this event. 15229 * @param {string} dispatchMarker Marker identifying the event target. 15230 * @param {object} nativeEvent Native browser event. 15231 * @extends {SyntheticUIEvent} 15232 */ 15233 function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent) { 15234 SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); 15235 } 15236 15237 SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface); 15238 15239 module.exports = SyntheticKeyboardEvent; 15240 15241 },{"./SyntheticUIEvent":94,"./getEventKey":116}],92:[function(_dereq_,module,exports){ 15242 /** 15243 * Copyright 2013-2014 Facebook, Inc. 15244 * 15245 * Licensed under the Apache License, Version 2.0 (the "License"); 15246 * you may not use this file except in compliance with the License. 15247 * You may obtain a copy of the License at 15248 * 15249 * http://www.apache.org/licenses/LICENSE-2.0 15250 * 15251 * Unless required by applicable law or agreed to in writing, software 15252 * distributed under the License is distributed on an "AS IS" BASIS, 15253 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15254 * See the License for the specific language governing permissions and 15255 * limitations under the License. 15256 * 15257 * @providesModule SyntheticMouseEvent 15258 * @typechecks static-only 15259 */ 15260 15261 "use strict"; 15262 15263 var SyntheticUIEvent = _dereq_("./SyntheticUIEvent"); 15264 var ViewportMetrics = _dereq_("./ViewportMetrics"); 15265 15266 /** 15267 * @interface MouseEvent 15268 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 15269 */ 15270 var MouseEventInterface = { 15271 screenX: null, 15272 screenY: null, 15273 clientX: null, 15274 clientY: null, 15275 ctrlKey: null, 15276 shiftKey: null, 15277 altKey: null, 15278 metaKey: null, 15279 button: function(event) { 15280 // Webkit, Firefox, IE9+ 15281 // which: 1 2 3 15282 // button: 0 1 2 (standard) 15283 var button = event.button; 15284 if ('which' in event) { 15285 return button; 15286 } 15287 // IE<9 15288 // which: undefined 15289 // button: 0 0 0 15290 // button: 1 4 2 (onmouseup) 15291 return button === 2 ? 2 : button === 4 ? 1 : 0; 15292 }, 15293 buttons: null, 15294 relatedTarget: function(event) { 15295 return event.relatedTarget || ( 15296 event.fromElement === event.srcElement ? 15297 event.toElement : 15298 event.fromElement 15299 ); 15300 }, 15301 // "Proprietary" Interface. 15302 pageX: function(event) { 15303 return 'pageX' in event ? 15304 event.pageX : 15305 event.clientX + ViewportMetrics.currentScrollLeft; 15306 }, 15307 pageY: function(event) { 15308 return 'pageY' in event ? 15309 event.pageY : 15310 event.clientY + ViewportMetrics.currentScrollTop; 15311 } 15312 }; 15313 15314 /** 15315 * @param {object} dispatchConfig Configuration used to dispatch this event. 15316 * @param {string} dispatchMarker Marker identifying the event target. 15317 * @param {object} nativeEvent Native browser event. 15318 * @extends {SyntheticUIEvent} 15319 */ 15320 function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent) { 15321 SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); 15322 } 15323 15324 SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface); 15325 15326 module.exports = SyntheticMouseEvent; 15327 15328 },{"./SyntheticUIEvent":94,"./ViewportMetrics":97}],93:[function(_dereq_,module,exports){ 15329 /** 15330 * Copyright 2013-2014 Facebook, Inc. 15331 * 15332 * Licensed under the Apache License, Version 2.0 (the "License"); 15333 * you may not use this file except in compliance with the License. 15334 * You may obtain a copy of the License at 15335 * 15336 * http://www.apache.org/licenses/LICENSE-2.0 15337 * 15338 * Unless required by applicable law or agreed to in writing, software 15339 * distributed under the License is distributed on an "AS IS" BASIS, 15340 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15341 * See the License for the specific language governing permissions and 15342 * limitations under the License. 15343 * 15344 * @providesModule SyntheticTouchEvent 15345 * @typechecks static-only 15346 */ 15347 15348 "use strict"; 15349 15350 var SyntheticUIEvent = _dereq_("./SyntheticUIEvent"); 15351 15352 /** 15353 * @interface TouchEvent 15354 * @see http://www.w3.org/TR/touch-events/ 15355 */ 15356 var TouchEventInterface = { 15357 touches: null, 15358 targetTouches: null, 15359 changedTouches: null, 15360 altKey: null, 15361 metaKey: null, 15362 ctrlKey: null, 15363 shiftKey: null 15364 }; 15365 15366 /** 15367 * @param {object} dispatchConfig Configuration used to dispatch this event. 15368 * @param {string} dispatchMarker Marker identifying the event target. 15369 * @param {object} nativeEvent Native browser event. 15370 * @extends {SyntheticUIEvent} 15371 */ 15372 function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent) { 15373 SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); 15374 } 15375 15376 SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface); 15377 15378 module.exports = SyntheticTouchEvent; 15379 15380 },{"./SyntheticUIEvent":94}],94:[function(_dereq_,module,exports){ 15381 /** 15382 * Copyright 2013-2014 Facebook, Inc. 15383 * 15384 * Licensed under the Apache License, Version 2.0 (the "License"); 15385 * you may not use this file except in compliance with the License. 15386 * You may obtain a copy of the License at 15387 * 15388 * http://www.apache.org/licenses/LICENSE-2.0 15389 * 15390 * Unless required by applicable law or agreed to in writing, software 15391 * distributed under the License is distributed on an "AS IS" BASIS, 15392 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15393 * See the License for the specific language governing permissions and 15394 * limitations under the License. 15395 * 15396 * @providesModule SyntheticUIEvent 15397 * @typechecks static-only 15398 */ 15399 15400 "use strict"; 15401 15402 var SyntheticEvent = _dereq_("./SyntheticEvent"); 15403 15404 /** 15405 * @interface UIEvent 15406 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 15407 */ 15408 var UIEventInterface = { 15409 view: null, 15410 detail: null 15411 }; 15412 15413 /** 15414 * @param {object} dispatchConfig Configuration used to dispatch this event. 15415 * @param {string} dispatchMarker Marker identifying the event target. 15416 * @param {object} nativeEvent Native browser event. 15417 * @extends {SyntheticEvent} 15418 */ 15419 function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent) { 15420 SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); 15421 } 15422 15423 SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface); 15424 15425 module.exports = SyntheticUIEvent; 15426 15427 },{"./SyntheticEvent":89}],95:[function(_dereq_,module,exports){ 15428 /** 15429 * Copyright 2013-2014 Facebook, Inc. 15430 * 15431 * Licensed under the Apache License, Version 2.0 (the "License"); 15432 * you may not use this file except in compliance with the License. 15433 * You may obtain a copy of the License at 15434 * 15435 * http://www.apache.org/licenses/LICENSE-2.0 15436 * 15437 * Unless required by applicable law or agreed to in writing, software 15438 * distributed under the License is distributed on an "AS IS" BASIS, 15439 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15440 * See the License for the specific language governing permissions and 15441 * limitations under the License. 15442 * 15443 * @providesModule SyntheticWheelEvent 15444 * @typechecks static-only 15445 */ 15446 15447 "use strict"; 15448 15449 var SyntheticMouseEvent = _dereq_("./SyntheticMouseEvent"); 15450 15451 /** 15452 * @interface WheelEvent 15453 * @see http://www.w3.org/TR/DOM-Level-3-Events/ 15454 */ 15455 var WheelEventInterface = { 15456 deltaX: function(event) { 15457 return ( 15458 'deltaX' in event ? event.deltaX : 15459 // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). 15460 'wheelDeltaX' in event ? -event.wheelDeltaX : 0 15461 ); 15462 }, 15463 deltaY: function(event) { 15464 return ( 15465 'deltaY' in event ? event.deltaY : 15466 // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). 15467 'wheelDeltaY' in event ? -event.wheelDeltaY : 15468 // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). 15469 'wheelDelta' in event ? -event.wheelDelta : 0 15470 ); 15471 }, 15472 deltaZ: null, 15473 15474 // Browsers without "deltaMode" is reporting in raw wheel delta where one 15475 // notch on the scroll is always +/- 120, roughly equivalent to pixels. 15476 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or 15477 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. 15478 deltaMode: null 15479 }; 15480 15481 /** 15482 * @param {object} dispatchConfig Configuration used to dispatch this event. 15483 * @param {string} dispatchMarker Marker identifying the event target. 15484 * @param {object} nativeEvent Native browser event. 15485 * @extends {SyntheticMouseEvent} 15486 */ 15487 function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent) { 15488 SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent); 15489 } 15490 15491 SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface); 15492 15493 module.exports = SyntheticWheelEvent; 15494 15495 },{"./SyntheticMouseEvent":92}],96:[function(_dereq_,module,exports){ 15496 /** 15497 * Copyright 2013-2014 Facebook, Inc. 15498 * 15499 * Licensed under the Apache License, Version 2.0 (the "License"); 15500 * you may not use this file except in compliance with the License. 15501 * You may obtain a copy of the License at 15502 * 15503 * http://www.apache.org/licenses/LICENSE-2.0 15504 * 15505 * Unless required by applicable law or agreed to in writing, software 15506 * distributed under the License is distributed on an "AS IS" BASIS, 15507 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15508 * See the License for the specific language governing permissions and 15509 * limitations under the License. 15510 * 15511 * @providesModule Transaction 15512 */ 15513 15514 "use strict"; 15515 15516 var invariant = _dereq_("./invariant"); 15517 15518 /** 15519 * `Transaction` creates a black box that is able to wrap any method such that 15520 * certain invariants are maintained before and after the method is invoked 15521 * (Even if an exception is thrown while invoking the wrapped method). Whoever 15522 * instantiates a transaction can provide enforcers of the invariants at 15523 * creation time. The `Transaction` class itself will supply one additional 15524 * automatic invariant for you - the invariant that any transaction instance 15525 * should not be run while it is already being run. You would typically create a 15526 * single instance of a `Transaction` for reuse multiple times, that potentially 15527 * is used to wrap several different methods. Wrappers are extremely simple - 15528 * they only require implementing two methods. 15529 * 15530 * <pre> 15531 * wrappers (injected at creation time) 15532 * + + 15533 * | | 15534 * +-----------------|--------|--------------+ 15535 * | v | | 15536 * | +---------------+ | | 15537 * | +--| wrapper1 |---|----+ | 15538 * | | +---------------+ v | | 15539 * | | +-------------+ | | 15540 * | | +----| wrapper2 |--------+ | 15541 * | | | +-------------+ | | | 15542 * | | | | | | 15543 * | v v v v | wrapper 15544 * | +---+ +---+ +---------+ +---+ +---+ | invariants 15545 * perform(anyMethod) | | | | | | | | | | | | maintained 15546 * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|--------> 15547 * | | | | | | | | | | | | 15548 * | | | | | | | | | | | | 15549 * | | | | | | | | | | | | 15550 * | +---+ +---+ +---------+ +---+ +---+ | 15551 * | initialize close | 15552 * +-----------------------------------------+ 15553 * </pre> 15554 * 15555 * Bonus: 15556 * - Reports timing metrics by method name and wrapper index. 15557 * 15558 * Use cases: 15559 * - Preserving the input selection ranges before/after reconciliation. 15560 * Restoring selection even in the event of an unexpected error. 15561 * - Deactivating events while rearranging the DOM, preventing blurs/focuses, 15562 * while guaranteeing that afterwards, the event system is reactivated. 15563 * - Flushing a queue of collected DOM mutations to the main UI thread after a 15564 * reconciliation takes place in a worker thread. 15565 * - Invoking any collected `componentDidUpdate` callbacks after rendering new 15566 * content. 15567 * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue 15568 * to preserve the `scrollTop` (an automatic scroll aware DOM). 15569 * - (Future use case): Layout calculations before and after DOM upates. 15570 * 15571 * Transactional plugin API: 15572 * - A module that has an `initialize` method that returns any precomputation. 15573 * - and a `close` method that accepts the precomputation. `close` is invoked 15574 * when the wrapped process is completed, or has failed. 15575 * 15576 * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules 15577 * that implement `initialize` and `close`. 15578 * @return {Transaction} Single transaction for reuse in thread. 15579 * 15580 * @class Transaction 15581 */ 15582 var Mixin = { 15583 /** 15584 * Sets up this instance so that it is prepared for collecting metrics. Does 15585 * so such that this setup method may be used on an instance that is already 15586 * initialized, in a way that does not consume additional memory upon reuse. 15587 * That can be useful if you decide to make your subclass of this mixin a 15588 * "PooledClass". 15589 */ 15590 reinitializeTransaction: function() { 15591 this.transactionWrappers = this.getTransactionWrappers(); 15592 if (!this.wrapperInitData) { 15593 this.wrapperInitData = []; 15594 } else { 15595 this.wrapperInitData.length = 0; 15596 } 15597 if (!this.timingMetrics) { 15598 this.timingMetrics = {}; 15599 } 15600 this.timingMetrics.methodInvocationTime = 0; 15601 if (!this.timingMetrics.wrapperInitTimes) { 15602 this.timingMetrics.wrapperInitTimes = []; 15603 } else { 15604 this.timingMetrics.wrapperInitTimes.length = 0; 15605 } 15606 if (!this.timingMetrics.wrapperCloseTimes) { 15607 this.timingMetrics.wrapperCloseTimes = []; 15608 } else { 15609 this.timingMetrics.wrapperCloseTimes.length = 0; 15610 } 15611 this._isInTransaction = false; 15612 }, 15613 15614 _isInTransaction: false, 15615 15616 /** 15617 * @abstract 15618 * @return {Array<TransactionWrapper>} Array of transaction wrappers. 15619 */ 15620 getTransactionWrappers: null, 15621 15622 isInTransaction: function() { 15623 return !!this._isInTransaction; 15624 }, 15625 15626 /** 15627 * Executes the function within a safety window. Use this for the top level 15628 * methods that result in large amounts of computation/mutations that would 15629 * need to be safety checked. 15630 * 15631 * @param {function} method Member of scope to call. 15632 * @param {Object} scope Scope to invoke from. 15633 * @param {Object?=} args... Arguments to pass to the method (optional). 15634 * Helps prevent need to bind in many cases. 15635 * @return Return value from `method`. 15636 */ 15637 perform: function(method, scope, a, b, c, d, e, f) { 15638 ("production" !== "development" ? invariant( 15639 !this.isInTransaction(), 15640 'Transaction.perform(...): Cannot initialize a transaction when there ' + 15641 'is already an outstanding transaction.' 15642 ) : invariant(!this.isInTransaction())); 15643 var memberStart = Date.now(); 15644 var errorThrown; 15645 var ret; 15646 try { 15647 this._isInTransaction = true; 15648 // Catching errors makes debugging more difficult, so we start with 15649 // errorThrown set to true before setting it to false after calling 15650 // close -- if it's still set to true in the finally block, it means 15651 // one of these calls threw. 15652 errorThrown = true; 15653 this.initializeAll(0); 15654 ret = method.call(scope, a, b, c, d, e, f); 15655 errorThrown = false; 15656 } finally { 15657 var memberEnd = Date.now(); 15658 this.methodInvocationTime += (memberEnd - memberStart); 15659 try { 15660 if (errorThrown) { 15661 // If `method` throws, prefer to show that stack trace over any thrown 15662 // by invoking `closeAll`. 15663 try { 15664 this.closeAll(0); 15665 } catch (err) { 15666 } 15667 } else { 15668 // Since `method` didn't throw, we don't want to silence the exception 15669 // here. 15670 this.closeAll(0); 15671 } 15672 } finally { 15673 this._isInTransaction = false; 15674 } 15675 } 15676 return ret; 15677 }, 15678 15679 initializeAll: function(startIndex) { 15680 var transactionWrappers = this.transactionWrappers; 15681 var wrapperInitTimes = this.timingMetrics.wrapperInitTimes; 15682 for (var i = startIndex; i < transactionWrappers.length; i++) { 15683 var initStart = Date.now(); 15684 var wrapper = transactionWrappers[i]; 15685 try { 15686 // Catching errors makes debugging more difficult, so we start with the 15687 // OBSERVED_ERROR state before overwriting it with the real return value 15688 // of initialize -- if it's still set to OBSERVED_ERROR in the finally 15689 // block, it means wrapper.initialize threw. 15690 this.wrapperInitData[i] = Transaction.OBSERVED_ERROR; 15691 this.wrapperInitData[i] = wrapper.initialize ? 15692 wrapper.initialize.call(this) : 15693 null; 15694 } finally { 15695 var curInitTime = wrapperInitTimes[i]; 15696 var initEnd = Date.now(); 15697 wrapperInitTimes[i] = (curInitTime || 0) + (initEnd - initStart); 15698 15699 if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) { 15700 // The initializer for wrapper i threw an error; initialize the 15701 // remaining wrappers but silence any exceptions from them to ensure 15702 // that the first error is the one to bubble up. 15703 try { 15704 this.initializeAll(i + 1); 15705 } catch (err) { 15706 } 15707 } 15708 } 15709 } 15710 }, 15711 15712 /** 15713 * Invokes each of `this.transactionWrappers.close[i]` functions, passing into 15714 * them the respective return values of `this.transactionWrappers.init[i]` 15715 * (`close`rs that correspond to initializers that failed will not be 15716 * invoked). 15717 */ 15718 closeAll: function(startIndex) { 15719 ("production" !== "development" ? invariant( 15720 this.isInTransaction(), 15721 'Transaction.closeAll(): Cannot close transaction when none are open.' 15722 ) : invariant(this.isInTransaction())); 15723 var transactionWrappers = this.transactionWrappers; 15724 var wrapperCloseTimes = this.timingMetrics.wrapperCloseTimes; 15725 for (var i = startIndex; i < transactionWrappers.length; i++) { 15726 var wrapper = transactionWrappers[i]; 15727 var closeStart = Date.now(); 15728 var initData = this.wrapperInitData[i]; 15729 var errorThrown; 15730 try { 15731 // Catching errors makes debugging more difficult, so we start with 15732 // errorThrown set to true before setting it to false after calling 15733 // close -- if it's still set to true in the finally block, it means 15734 // wrapper.close threw. 15735 errorThrown = true; 15736 if (initData !== Transaction.OBSERVED_ERROR) { 15737 wrapper.close && wrapper.close.call(this, initData); 15738 } 15739 errorThrown = false; 15740 } finally { 15741 var closeEnd = Date.now(); 15742 var curCloseTime = wrapperCloseTimes[i]; 15743 wrapperCloseTimes[i] = (curCloseTime || 0) + (closeEnd - closeStart); 15744 15745 if (errorThrown) { 15746 // The closer for wrapper i threw an error; close the remaining 15747 // wrappers but silence any exceptions from them to ensure that the 15748 // first error is the one to bubble up. 15749 try { 15750 this.closeAll(i + 1); 15751 } catch (e) { 15752 } 15753 } 15754 } 15755 } 15756 this.wrapperInitData.length = 0; 15757 } 15758 }; 15759 15760 var Transaction = { 15761 15762 Mixin: Mixin, 15763 15764 /** 15765 * Token to look for to determine if an error occured. 15766 */ 15767 OBSERVED_ERROR: {} 15768 15769 }; 15770 15771 module.exports = Transaction; 15772 15773 },{"./invariant":125}],97:[function(_dereq_,module,exports){ 15774 /** 15775 * Copyright 2013-2014 Facebook, Inc. 15776 * 15777 * Licensed under the Apache License, Version 2.0 (the "License"); 15778 * you may not use this file except in compliance with the License. 15779 * You may obtain a copy of the License at 15780 * 15781 * http://www.apache.org/licenses/LICENSE-2.0 15782 * 15783 * Unless required by applicable law or agreed to in writing, software 15784 * distributed under the License is distributed on an "AS IS" BASIS, 15785 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15786 * See the License for the specific language governing permissions and 15787 * limitations under the License. 15788 * 15789 * @providesModule ViewportMetrics 15790 */ 15791 15792 "use strict"; 15793 15794 var getUnboundedScrollPosition = _dereq_("./getUnboundedScrollPosition"); 15795 15796 var ViewportMetrics = { 15797 15798 currentScrollLeft: 0, 15799 15800 currentScrollTop: 0, 15801 15802 refreshScrollValues: function() { 15803 var scrollPosition = getUnboundedScrollPosition(window); 15804 ViewportMetrics.currentScrollLeft = scrollPosition.x; 15805 ViewportMetrics.currentScrollTop = scrollPosition.y; 15806 } 15807 15808 }; 15809 15810 module.exports = ViewportMetrics; 15811 15812 },{"./getUnboundedScrollPosition":122}],98:[function(_dereq_,module,exports){ 15813 /** 15814 * Copyright 2013-2014 Facebook, Inc. 15815 * 15816 * Licensed under the Apache License, Version 2.0 (the "License"); 15817 * you may not use this file except in compliance with the License. 15818 * You may obtain a copy of the License at 15819 * 15820 * http://www.apache.org/licenses/LICENSE-2.0 15821 * 15822 * Unless required by applicable law or agreed to in writing, software 15823 * distributed under the License is distributed on an "AS IS" BASIS, 15824 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15825 * See the License for the specific language governing permissions and 15826 * limitations under the License. 15827 * 15828 * @providesModule accumulate 15829 */ 15830 15831 "use strict"; 15832 15833 var invariant = _dereq_("./invariant"); 15834 15835 /** 15836 * Accumulates items that must not be null or undefined. 15837 * 15838 * This is used to conserve memory by avoiding array allocations. 15839 * 15840 * @return {*|array<*>} An accumulation of items. 15841 */ 15842 function accumulate(current, next) { 15843 ("production" !== "development" ? invariant( 15844 next != null, 15845 'accumulate(...): Accumulated items must be not be null or undefined.' 15846 ) : invariant(next != null)); 15847 if (current == null) { 15848 return next; 15849 } else { 15850 // Both are not empty. Warning: Never call x.concat(y) when you are not 15851 // certain that x is an Array (x could be a string with concat method). 15852 var currentIsArray = Array.isArray(current); 15853 var nextIsArray = Array.isArray(next); 15854 if (currentIsArray) { 15855 return current.concat(next); 15856 } else { 15857 if (nextIsArray) { 15858 return [current].concat(next); 15859 } else { 15860 return [current, next]; 15861 } 15862 } 15863 } 15864 } 15865 15866 module.exports = accumulate; 15867 15868 },{"./invariant":125}],99:[function(_dereq_,module,exports){ 15869 /** 15870 * Copyright 2013-2014 Facebook, Inc. 15871 * 15872 * Licensed under the Apache License, Version 2.0 (the "License"); 15873 * you may not use this file except in compliance with the License. 15874 * You may obtain a copy of the License at 15875 * 15876 * http://www.apache.org/licenses/LICENSE-2.0 15877 * 15878 * Unless required by applicable law or agreed to in writing, software 15879 * distributed under the License is distributed on an "AS IS" BASIS, 15880 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15881 * See the License for the specific language governing permissions and 15882 * limitations under the License. 15883 * 15884 * @providesModule adler32 15885 */ 15886 15887 /* jslint bitwise:true */ 15888 15889 "use strict"; 15890 15891 var MOD = 65521; 15892 15893 // This is a clean-room implementation of adler32 designed for detecting 15894 // if markup is not what we expect it to be. It does not need to be 15895 // cryptographically strong, only reasonable good at detecting if markup 15896 // generated on the server is different than that on the client. 15897 function adler32(data) { 15898 var a = 1; 15899 var b = 0; 15900 for (var i = 0; i < data.length; i++) { 15901 a = (a + data.charCodeAt(i)) % MOD; 15902 b = (b + a) % MOD; 15903 } 15904 return a | (b << 16); 15905 } 15906 15907 module.exports = adler32; 15908 15909 },{}],100:[function(_dereq_,module,exports){ 15910 /** 15911 * Copyright 2013-2014 Facebook, Inc. 15912 * 15913 * Licensed under the Apache License, Version 2.0 (the "License"); 15914 * you may not use this file except in compliance with the License. 15915 * You may obtain a copy of the License at 15916 * 15917 * http://www.apache.org/licenses/LICENSE-2.0 15918 * 15919 * Unless required by applicable law or agreed to in writing, software 15920 * distributed under the License is distributed on an "AS IS" BASIS, 15921 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15922 * See the License for the specific language governing permissions and 15923 * limitations under the License. 15924 * 15925 * @typechecks 15926 * @providesModule cloneWithProps 15927 */ 15928 15929 "use strict"; 15930 15931 var ReactPropTransferer = _dereq_("./ReactPropTransferer"); 15932 15933 var keyOf = _dereq_("./keyOf"); 15934 var warning = _dereq_("./warning"); 15935 15936 var CHILDREN_PROP = keyOf({children: null}); 15937 15938 /** 15939 * Sometimes you want to change the props of a child passed to you. Usually 15940 * this is to add a CSS class. 15941 * 15942 * @param {object} child child component you'd like to clone 15943 * @param {object} props props you'd like to modify. They will be merged 15944 * as if you used `transferPropsTo()`. 15945 * @return {object} a clone of child with props merged in. 15946 */ 15947 function cloneWithProps(child, props) { 15948 if ("production" !== "development") { 15949 ("production" !== "development" ? warning( 15950 !child.props.ref, 15951 'You are calling cloneWithProps() on a child with a ref. This is ' + 15952 'dangerous because you\'re creating a new child which will not be ' + 15953 'added as a ref to its parent.' 15954 ) : null); 15955 } 15956 15957 var newProps = ReactPropTransferer.mergeProps(props, child.props); 15958 15959 // Use `child.props.children` if it is provided. 15960 if (!newProps.hasOwnProperty(CHILDREN_PROP) && 15961 child.props.hasOwnProperty(CHILDREN_PROP)) { 15962 newProps.children = child.props.children; 15963 } 15964 15965 return child.constructor.ConvenienceConstructor(newProps); 15966 } 15967 15968 module.exports = cloneWithProps; 15969 15970 },{"./ReactPropTransferer":66,"./keyOf":132,"./warning":148}],101:[function(_dereq_,module,exports){ 15971 /** 15972 * Copyright 2013-2014 Facebook, Inc. 15973 * 15974 * Licensed under the Apache License, Version 2.0 (the "License"); 15975 * you may not use this file except in compliance with the License. 15976 * You may obtain a copy of the License at 15977 * 15978 * http://www.apache.org/licenses/LICENSE-2.0 15979 * 15980 * Unless required by applicable law or agreed to in writing, software 15981 * distributed under the License is distributed on an "AS IS" BASIS, 15982 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15983 * See the License for the specific language governing permissions and 15984 * limitations under the License. 15985 * 15986 * @providesModule containsNode 15987 * @typechecks 15988 */ 15989 15990 var isTextNode = _dereq_("./isTextNode"); 15991 15992 /*jslint bitwise:true */ 15993 15994 /** 15995 * Checks if a given DOM node contains or is another DOM node. 15996 * 15997 * @param {?DOMNode} outerNode Outer DOM node. 15998 * @param {?DOMNode} innerNode Inner DOM node. 15999 * @return {boolean} True if `outerNode` contains or is `innerNode`. 16000 */ 16001 function containsNode(outerNode, innerNode) { 16002 if (!outerNode || !innerNode) { 16003 return false; 16004 } else if (outerNode === innerNode) { 16005 return true; 16006 } else if (isTextNode(outerNode)) { 16007 return false; 16008 } else if (isTextNode(innerNode)) { 16009 return containsNode(outerNode, innerNode.parentNode); 16010 } else if (outerNode.contains) { 16011 return outerNode.contains(innerNode); 16012 } else if (outerNode.compareDocumentPosition) { 16013 return !!(outerNode.compareDocumentPosition(innerNode) & 16); 16014 } else { 16015 return false; 16016 } 16017 } 16018 16019 module.exports = containsNode; 16020 16021 },{"./isTextNode":129}],102:[function(_dereq_,module,exports){ 16022 /** 16023 * Copyright 2013-2014 Facebook, Inc. 16024 * 16025 * Licensed under the Apache License, Version 2.0 (the "License"); 16026 * you may not use this file except in compliance with the License. 16027 * You may obtain a copy of the License at 16028 * 16029 * http://www.apache.org/licenses/LICENSE-2.0 16030 * 16031 * Unless required by applicable law or agreed to in writing, software 16032 * distributed under the License is distributed on an "AS IS" BASIS, 16033 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16034 * See the License for the specific language governing permissions and 16035 * limitations under the License. 16036 * 16037 * @providesModule copyProperties 16038 */ 16039 16040 /** 16041 * Copy properties from one or more objects (up to 5) into the first object. 16042 * This is a shallow copy. It mutates the first object and also returns it. 16043 * 16044 * NOTE: `arguments` has a very significant performance penalty, which is why 16045 * we don't support unlimited arguments. 16046 */ 16047 function copyProperties(obj, a, b, c, d, e, f) { 16048 obj = obj || {}; 16049 16050 if ("production" !== "development") { 16051 if (f) { 16052 throw new Error('Too many arguments passed to copyProperties'); 16053 } 16054 } 16055 16056 var args = [a, b, c, d, e]; 16057 var ii = 0, v; 16058 while (args[ii]) { 16059 v = args[ii++]; 16060 for (var k in v) { 16061 obj[k] = v[k]; 16062 } 16063 16064 // IE ignores toString in object iteration.. See: 16065 // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html 16066 if (v.hasOwnProperty && v.hasOwnProperty('toString') && 16067 (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) { 16068 obj.toString = v.toString; 16069 } 16070 } 16071 16072 return obj; 16073 } 16074 16075 module.exports = copyProperties; 16076 16077 },{}],103:[function(_dereq_,module,exports){ 16078 /** 16079 * Copyright 2013-2014 Facebook, Inc. 16080 * 16081 * Licensed under the Apache License, Version 2.0 (the "License"); 16082 * you may not use this file except in compliance with the License. 16083 * You may obtain a copy of the License at 16084 * 16085 * http://www.apache.org/licenses/LICENSE-2.0 16086 * 16087 * Unless required by applicable law or agreed to in writing, software 16088 * distributed under the License is distributed on an "AS IS" BASIS, 16089 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16090 * See the License for the specific language governing permissions and 16091 * limitations under the License. 16092 * 16093 * @providesModule createArrayFrom 16094 * @typechecks 16095 */ 16096 16097 var toArray = _dereq_("./toArray"); 16098 16099 /** 16100 * Perform a heuristic test to determine if an object is "array-like". 16101 * 16102 * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" 16103 * Joshu replied: "Mu." 16104 * 16105 * This function determines if its argument has "array nature": it returns 16106 * true if the argument is an actual array, an `arguments' object, or an 16107 * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). 16108 * 16109 * It will return false for other array-like objects like Filelist. 16110 * 16111 * @param {*} obj 16112 * @return {boolean} 16113 */ 16114 function hasArrayNature(obj) { 16115 return ( 16116 // not null/false 16117 !!obj && 16118 // arrays are objects, NodeLists are functions in Safari 16119 (typeof obj == 'object' || typeof obj == 'function') && 16120 // quacks like an array 16121 ('length' in obj) && 16122 // not window 16123 !('setInterval' in obj) && 16124 // no DOM node should be considered an array-like 16125 // a 'select' element has 'length' and 'item' properties on IE8 16126 (typeof obj.nodeType != 'number') && 16127 ( 16128 // a real array 16129 (// HTMLCollection/NodeList 16130 (Array.isArray(obj) || 16131 // arguments 16132 ('callee' in obj) || 'item' in obj)) 16133 ) 16134 ); 16135 } 16136 16137 /** 16138 * Ensure that the argument is an array by wrapping it in an array if it is not. 16139 * Creates a copy of the argument if it is already an array. 16140 * 16141 * This is mostly useful idiomatically: 16142 * 16143 * var createArrayFrom = require('createArrayFrom'); 16144 * 16145 * function takesOneOrMoreThings(things) { 16146 * things = createArrayFrom(things); 16147 * ... 16148 * } 16149 * 16150 * This allows you to treat `things' as an array, but accept scalars in the API. 16151 * 16152 * If you need to convert an array-like object, like `arguments`, into an array 16153 * use toArray instead. 16154 * 16155 * @param {*} obj 16156 * @return {array} 16157 */ 16158 function createArrayFrom(obj) { 16159 if (!hasArrayNature(obj)) { 16160 return [obj]; 16161 } else if (Array.isArray(obj)) { 16162 return obj.slice(); 16163 } else { 16164 return toArray(obj); 16165 } 16166 } 16167 16168 module.exports = createArrayFrom; 16169 16170 },{"./toArray":145}],104:[function(_dereq_,module,exports){ 16171 /** 16172 * Copyright 2013-2014 Facebook, Inc. 16173 * 16174 * Licensed under the Apache License, Version 2.0 (the "License"); 16175 * you may not use this file except in compliance with the License. 16176 * You may obtain a copy of the License at 16177 * 16178 * http://www.apache.org/licenses/LICENSE-2.0 16179 * 16180 * Unless required by applicable law or agreed to in writing, software 16181 * distributed under the License is distributed on an "AS IS" BASIS, 16182 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16183 * See the License for the specific language governing permissions and 16184 * limitations under the License. 16185 * 16186 * @providesModule createFullPageComponent 16187 * @typechecks 16188 */ 16189 16190 "use strict"; 16191 16192 // Defeat circular references by requiring this directly. 16193 var ReactCompositeComponent = _dereq_("./ReactCompositeComponent"); 16194 16195 var invariant = _dereq_("./invariant"); 16196 16197 /** 16198 * Create a component that will throw an exception when unmounted. 16199 * 16200 * Components like <html> <head> and <body> can't be removed or added 16201 * easily in a cross-browser way, however it's valuable to be able to 16202 * take advantage of React's reconciliation for styling and <title> 16203 * management. So we just document it and throw in dangerous cases. 16204 * 16205 * @param {function} componentClass convenience constructor to wrap 16206 * @return {function} convenience constructor of new component 16207 */ 16208 function createFullPageComponent(componentClass) { 16209 var FullPageComponent = ReactCompositeComponent.createClass({ 16210 displayName: 'ReactFullPageComponent' + ( 16211 componentClass.componentConstructor.displayName || '' 16212 ), 16213 16214 componentWillUnmount: function() { 16215 ("production" !== "development" ? invariant( 16216 false, 16217 '%s tried to unmount. Because of cross-browser quirks it is ' + 16218 'impossible to unmount some top-level components (eg <html>, <head>, ' + 16219 'and <body>) reliably and efficiently. To fix this, have a single ' + 16220 'top-level component that never unmounts render these elements.', 16221 this.constructor.displayName 16222 ) : invariant(false)); 16223 }, 16224 16225 render: function() { 16226 return this.transferPropsTo(componentClass(null, this.props.children)); 16227 } 16228 }); 16229 16230 return FullPageComponent; 16231 } 16232 16233 module.exports = createFullPageComponent; 16234 16235 },{"./ReactCompositeComponent":33,"./invariant":125}],105:[function(_dereq_,module,exports){ 16236 /** 16237 * Copyright 2013-2014 Facebook, Inc. 16238 * 16239 * Licensed under the Apache License, Version 2.0 (the "License"); 16240 * you may not use this file except in compliance with the License. 16241 * You may obtain a copy of the License at 16242 * 16243 * http://www.apache.org/licenses/LICENSE-2.0 16244 * 16245 * Unless required by applicable law or agreed to in writing, software 16246 * distributed under the License is distributed on an "AS IS" BASIS, 16247 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16248 * See the License for the specific language governing permissions and 16249 * limitations under the License. 16250 * 16251 * @providesModule createNodesFromMarkup 16252 * @typechecks 16253 */ 16254 16255 /*jslint evil: true, sub: true */ 16256 16257 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 16258 16259 var createArrayFrom = _dereq_("./createArrayFrom"); 16260 var getMarkupWrap = _dereq_("./getMarkupWrap"); 16261 var invariant = _dereq_("./invariant"); 16262 16263 /** 16264 * Dummy container used to render all markup. 16265 */ 16266 var dummyNode = 16267 ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; 16268 16269 /** 16270 * Pattern used by `getNodeName`. 16271 */ 16272 var nodeNamePattern = /^\s*<(\w+)/; 16273 16274 /** 16275 * Extracts the `nodeName` of the first element in a string of markup. 16276 * 16277 * @param {string} markup String of markup. 16278 * @return {?string} Node name of the supplied markup. 16279 */ 16280 function getNodeName(markup) { 16281 var nodeNameMatch = markup.match(nodeNamePattern); 16282 return nodeNameMatch && nodeNameMatch[1].toLowerCase(); 16283 } 16284 16285 /** 16286 * Creates an array containing the nodes rendered from the supplied markup. The 16287 * optionally supplied `handleScript` function will be invoked once for each 16288 * <script> element that is rendered. If no `handleScript` function is supplied, 16289 * an exception is thrown if any <script> elements are rendered. 16290 * 16291 * @param {string} markup A string of valid HTML markup. 16292 * @param {?function} handleScript Invoked once for each rendered <script>. 16293 * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. 16294 */ 16295 function createNodesFromMarkup(markup, handleScript) { 16296 var node = dummyNode; 16297 ("production" !== "development" ? invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized') : invariant(!!dummyNode)); 16298 var nodeName = getNodeName(markup); 16299 16300 var wrap = nodeName && getMarkupWrap(nodeName); 16301 if (wrap) { 16302 node.innerHTML = wrap[1] + markup + wrap[2]; 16303 16304 var wrapDepth = wrap[0]; 16305 while (wrapDepth--) { 16306 node = node.lastChild; 16307 } 16308 } else { 16309 node.innerHTML = markup; 16310 } 16311 16312 var scripts = node.getElementsByTagName('script'); 16313 if (scripts.length) { 16314 ("production" !== "development" ? invariant( 16315 handleScript, 16316 'createNodesFromMarkup(...): Unexpected <script> element rendered.' 16317 ) : invariant(handleScript)); 16318 createArrayFrom(scripts).forEach(handleScript); 16319 } 16320 16321 var nodes = createArrayFrom(node.childNodes); 16322 while (node.lastChild) { 16323 node.removeChild(node.lastChild); 16324 } 16325 return nodes; 16326 } 16327 16328 module.exports = createNodesFromMarkup; 16329 16330 },{"./ExecutionEnvironment":21,"./createArrayFrom":103,"./getMarkupWrap":118,"./invariant":125}],106:[function(_dereq_,module,exports){ 16331 /** 16332 * Copyright 2013-2014 Facebook, Inc. 16333 * 16334 * Licensed under the Apache License, Version 2.0 (the "License"); 16335 * you may not use this file except in compliance with the License. 16336 * You may obtain a copy of the License at 16337 * 16338 * http://www.apache.org/licenses/LICENSE-2.0 16339 * 16340 * Unless required by applicable law or agreed to in writing, software 16341 * distributed under the License is distributed on an "AS IS" BASIS, 16342 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16343 * See the License for the specific language governing permissions and 16344 * limitations under the License. 16345 * 16346 * @providesModule createObjectFrom 16347 */ 16348 16349 /** 16350 * Construct an object from an array of keys 16351 * and optionally specified value or list of values. 16352 * 16353 * >>> createObjectFrom(['a','b','c']); 16354 * {a: true, b: true, c: true} 16355 * 16356 * >>> createObjectFrom(['a','b','c'], false); 16357 * {a: false, b: false, c: false} 16358 * 16359 * >>> createObjectFrom(['a','b','c'], 'monkey'); 16360 * {c:'monkey', b:'monkey' c:'monkey'} 16361 * 16362 * >>> createObjectFrom(['a','b','c'], [1,2,3]); 16363 * {a: 1, b: 2, c: 3} 16364 * 16365 * >>> createObjectFrom(['women', 'men'], [true, false]); 16366 * {women: true, men: false} 16367 * 16368 * @param Array list of keys 16369 * @param mixed optional value or value array. defaults true. 16370 * @returns object 16371 */ 16372 function createObjectFrom(keys, values /* = true */) { 16373 if ("production" !== "development") { 16374 if (!Array.isArray(keys)) { 16375 throw new TypeError('Must pass an array of keys.'); 16376 } 16377 } 16378 16379 var object = {}; 16380 var isArray = Array.isArray(values); 16381 if (typeof values == 'undefined') { 16382 values = true; 16383 } 16384 16385 for (var ii = keys.length; ii--;) { 16386 object[keys[ii]] = isArray ? values[ii] : values; 16387 } 16388 return object; 16389 } 16390 16391 module.exports = createObjectFrom; 16392 16393 },{}],107:[function(_dereq_,module,exports){ 16394 /** 16395 * Copyright 2013-2014 Facebook, Inc. 16396 * 16397 * Licensed under the Apache License, Version 2.0 (the "License"); 16398 * you may not use this file except in compliance with the License. 16399 * You may obtain a copy of the License at 16400 * 16401 * http://www.apache.org/licenses/LICENSE-2.0 16402 * 16403 * Unless required by applicable law or agreed to in writing, software 16404 * distributed under the License is distributed on an "AS IS" BASIS, 16405 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16406 * See the License for the specific language governing permissions and 16407 * limitations under the License. 16408 * 16409 * @providesModule cx 16410 */ 16411 16412 /** 16413 * This function is used to mark string literals representing CSS class names 16414 * so that they can be transformed statically. This allows for modularization 16415 * and minification of CSS class names. 16416 * 16417 * In static_upstream, this function is actually implemented, but it should 16418 * eventually be replaced with something more descriptive, and the transform 16419 * that is used in the main stack should be ported for use elsewhere. 16420 * 16421 * @param string|object className to modularize, or an object of key/values. 16422 * In the object case, the values are conditions that 16423 * determine if the className keys should be included. 16424 * @param [string ...] Variable list of classNames in the string case. 16425 * @return string Renderable space-separated CSS className. 16426 */ 16427 function cx(classNames) { 16428 if (typeof classNames == 'object') { 16429 return Object.keys(classNames).filter(function(className) { 16430 return classNames[className]; 16431 }).join(' '); 16432 } else { 16433 return Array.prototype.join.call(arguments, ' '); 16434 } 16435 } 16436 16437 module.exports = cx; 16438 16439 },{}],108:[function(_dereq_,module,exports){ 16440 /** 16441 * Copyright 2013-2014 Facebook, Inc. 16442 * 16443 * Licensed under the Apache License, Version 2.0 (the "License"); 16444 * you may not use this file except in compliance with the License. 16445 * You may obtain a copy of the License at 16446 * 16447 * http://www.apache.org/licenses/LICENSE-2.0 16448 * 16449 * Unless required by applicable law or agreed to in writing, software 16450 * distributed under the License is distributed on an "AS IS" BASIS, 16451 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16452 * See the License for the specific language governing permissions and 16453 * limitations under the License. 16454 * 16455 * @providesModule dangerousStyleValue 16456 * @typechecks static-only 16457 */ 16458 16459 "use strict"; 16460 16461 var CSSProperty = _dereq_("./CSSProperty"); 16462 16463 /** 16464 * Convert a value into the proper css writable value. The `styleName` name 16465 * name should be logical (no hyphens), as specified 16466 * in `CSSProperty.isUnitlessNumber`. 16467 * 16468 * @param {string} styleName CSS property name such as `topMargin`. 16469 * @param {*} value CSS property value such as `10px`. 16470 * @return {string} Normalized style value with dimensions applied. 16471 */ 16472 function dangerousStyleValue(styleName, value) { 16473 // Note that we've removed escapeTextForBrowser() calls here since the 16474 // whole string will be escaped when the attribute is injected into 16475 // the markup. If you provide unsafe user data here they can inject 16476 // arbitrary CSS which may be problematic (I couldn't repro this): 16477 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet 16478 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ 16479 // This is not an XSS hole but instead a potential CSS injection issue 16480 // which has lead to a greater discussion about how we're going to 16481 // trust URLs moving forward. See #2115901 16482 16483 var isEmpty = value == null || typeof value === 'boolean' || value === ''; 16484 if (isEmpty) { 16485 return ''; 16486 } 16487 16488 var isNonNumeric = isNaN(value); 16489 if (isNonNumeric || value === 0 || CSSProperty.isUnitlessNumber[styleName]) { 16490 return '' + value; // cast to string 16491 } 16492 16493 return value + 'px'; 16494 } 16495 16496 module.exports = dangerousStyleValue; 16497 16498 },{"./CSSProperty":3}],109:[function(_dereq_,module,exports){ 16499 /** 16500 * Copyright 2013-2014 Facebook, Inc. 16501 * 16502 * Licensed under the Apache License, Version 2.0 (the "License"); 16503 * you may not use this file except in compliance with the License. 16504 * You may obtain a copy of the License at 16505 * 16506 * http://www.apache.org/licenses/LICENSE-2.0 16507 * 16508 * Unless required by applicable law or agreed to in writing, software 16509 * distributed under the License is distributed on an "AS IS" BASIS, 16510 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16511 * See the License for the specific language governing permissions and 16512 * limitations under the License. 16513 * 16514 * @providesModule emptyFunction 16515 */ 16516 16517 var copyProperties = _dereq_("./copyProperties"); 16518 16519 function makeEmptyFunction(arg) { 16520 return function() { 16521 return arg; 16522 }; 16523 } 16524 16525 /** 16526 * This function accepts and discards inputs; it has no side effects. This is 16527 * primarily useful idiomatically for overridable function endpoints which 16528 * always need to be callable, since JS lacks a null-call idiom ala Cocoa. 16529 */ 16530 function emptyFunction() {} 16531 16532 copyProperties(emptyFunction, { 16533 thatReturns: makeEmptyFunction, 16534 thatReturnsFalse: makeEmptyFunction(false), 16535 thatReturnsTrue: makeEmptyFunction(true), 16536 thatReturnsNull: makeEmptyFunction(null), 16537 thatReturnsThis: function() { return this; }, 16538 thatReturnsArgument: function(arg) { return arg; } 16539 }); 16540 16541 module.exports = emptyFunction; 16542 16543 },{"./copyProperties":102}],110:[function(_dereq_,module,exports){ 16544 /** 16545 * Copyright 2013-2014 Facebook, Inc. 16546 * 16547 * Licensed under the Apache License, Version 2.0 (the "License"); 16548 * you may not use this file except in compliance with the License. 16549 * You may obtain a copy of the License at 16550 * 16551 * http://www.apache.org/licenses/LICENSE-2.0 16552 * 16553 * Unless required by applicable law or agreed to in writing, software 16554 * distributed under the License is distributed on an "AS IS" BASIS, 16555 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16556 * See the License for the specific language governing permissions and 16557 * limitations under the License. 16558 * 16559 * @providesModule emptyObject 16560 */ 16561 16562 "use strict"; 16563 16564 var emptyObject = {}; 16565 16566 if ("production" !== "development") { 16567 Object.freeze(emptyObject); 16568 } 16569 16570 module.exports = emptyObject; 16571 16572 },{}],111:[function(_dereq_,module,exports){ 16573 /** 16574 * Copyright 2013-2014 Facebook, Inc. 16575 * 16576 * Licensed under the Apache License, Version 2.0 (the "License"); 16577 * you may not use this file except in compliance with the License. 16578 * You may obtain a copy of the License at 16579 * 16580 * http://www.apache.org/licenses/LICENSE-2.0 16581 * 16582 * Unless required by applicable law or agreed to in writing, software 16583 * distributed under the License is distributed on an "AS IS" BASIS, 16584 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16585 * See the License for the specific language governing permissions and 16586 * limitations under the License. 16587 * 16588 * @providesModule escapeTextForBrowser 16589 * @typechecks static-only 16590 */ 16591 16592 "use strict"; 16593 16594 var ESCAPE_LOOKUP = { 16595 "&": "&", 16596 ">": ">", 16597 "<": "<", 16598 "\"": """, 16599 "'": "'", 16600 "/": "/" 16601 }; 16602 16603 var ESCAPE_REGEX = /[&><"'\/]/g; 16604 16605 function escaper(match) { 16606 return ESCAPE_LOOKUP[match]; 16607 } 16608 16609 /** 16610 * Escapes text to prevent scripting attacks. 16611 * 16612 * @param {*} text Text value to escape. 16613 * @return {string} An escaped string. 16614 */ 16615 function escapeTextForBrowser(text) { 16616 return ('' + text).replace(ESCAPE_REGEX, escaper); 16617 } 16618 16619 module.exports = escapeTextForBrowser; 16620 16621 },{}],112:[function(_dereq_,module,exports){ 16622 /** 16623 * Copyright 2013-2014 Facebook, Inc. 16624 * 16625 * Licensed under the Apache License, Version 2.0 (the "License"); 16626 * you may not use this file except in compliance with the License. 16627 * You may obtain a copy of the License at 16628 * 16629 * http://www.apache.org/licenses/LICENSE-2.0 16630 * 16631 * Unless required by applicable law or agreed to in writing, software 16632 * distributed under the License is distributed on an "AS IS" BASIS, 16633 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16634 * See the License for the specific language governing permissions and 16635 * limitations under the License. 16636 * 16637 * @providesModule flattenChildren 16638 */ 16639 16640 "use strict"; 16641 16642 var invariant = _dereq_("./invariant"); 16643 var traverseAllChildren = _dereq_("./traverseAllChildren"); 16644 16645 /** 16646 * @param {function} traverseContext Context passed through traversal. 16647 * @param {?ReactComponent} child React child component. 16648 * @param {!string} name String name of key path to child. 16649 */ 16650 function flattenSingleChildIntoContext(traverseContext, child, name) { 16651 // We found a component instance. 16652 var result = traverseContext; 16653 ("production" !== "development" ? invariant( 16654 !result.hasOwnProperty(name), 16655 'flattenChildren(...): Encountered two children with the same key, `%s`. ' + 16656 'Children keys must be unique.', 16657 name 16658 ) : invariant(!result.hasOwnProperty(name))); 16659 if (child != null) { 16660 result[name] = child; 16661 } 16662 } 16663 16664 /** 16665 * Flattens children that are typically specified as `props.children`. Any null 16666 * children will not be included in the resulting object. 16667 * @return {!object} flattened children keyed by name. 16668 */ 16669 function flattenChildren(children) { 16670 if (children == null) { 16671 return children; 16672 } 16673 var result = {}; 16674 traverseAllChildren(children, flattenSingleChildIntoContext, result); 16675 return result; 16676 } 16677 16678 module.exports = flattenChildren; 16679 16680 },{"./invariant":125,"./traverseAllChildren":146}],113:[function(_dereq_,module,exports){ 16681 /** 16682 * Copyright 2014 Facebook, Inc. 16683 * 16684 * Licensed under the Apache License, Version 2.0 (the "License"); 16685 * you may not use this file except in compliance with the License. 16686 * You may obtain a copy of the License at 16687 * 16688 * http://www.apache.org/licenses/LICENSE-2.0 16689 * 16690 * Unless required by applicable law or agreed to in writing, software 16691 * distributed under the License is distributed on an "AS IS" BASIS, 16692 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16693 * See the License for the specific language governing permissions and 16694 * limitations under the License. 16695 * 16696 * @providesModule focusNode 16697 */ 16698 16699 "use strict"; 16700 16701 /** 16702 * IE8 throws if an input/textarea is disabled and we try to focus it. 16703 * Focus only when necessary. 16704 * 16705 * @param {DOMElement} node input/textarea to focus 16706 */ 16707 function focusNode(node) { 16708 if (!node.disabled) { 16709 node.focus(); 16710 } 16711 } 16712 16713 module.exports = focusNode; 16714 16715 },{}],114:[function(_dereq_,module,exports){ 16716 /** 16717 * Copyright 2013-2014 Facebook, Inc. 16718 * 16719 * Licensed under the Apache License, Version 2.0 (the "License"); 16720 * you may not use this file except in compliance with the License. 16721 * You may obtain a copy of the License at 16722 * 16723 * http://www.apache.org/licenses/LICENSE-2.0 16724 * 16725 * Unless required by applicable law or agreed to in writing, software 16726 * distributed under the License is distributed on an "AS IS" BASIS, 16727 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16728 * See the License for the specific language governing permissions and 16729 * limitations under the License. 16730 * 16731 * @providesModule forEachAccumulated 16732 */ 16733 16734 "use strict"; 16735 16736 /** 16737 * @param {array} an "accumulation" of items which is either an Array or 16738 * a single item. Useful when paired with the `accumulate` module. This is a 16739 * simple utility that allows us to reason about a collection of items, but 16740 * handling the case when there is exactly one item (and we do not need to 16741 * allocate an array). 16742 */ 16743 var forEachAccumulated = function(arr, cb, scope) { 16744 if (Array.isArray(arr)) { 16745 arr.forEach(cb, scope); 16746 } else if (arr) { 16747 cb.call(scope, arr); 16748 } 16749 }; 16750 16751 module.exports = forEachAccumulated; 16752 16753 },{}],115:[function(_dereq_,module,exports){ 16754 /** 16755 * Copyright 2013-2014 Facebook, Inc. 16756 * 16757 * Licensed under the Apache License, Version 2.0 (the "License"); 16758 * you may not use this file except in compliance with the License. 16759 * You may obtain a copy of the License at 16760 * 16761 * http://www.apache.org/licenses/LICENSE-2.0 16762 * 16763 * Unless required by applicable law or agreed to in writing, software 16764 * distributed under the License is distributed on an "AS IS" BASIS, 16765 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16766 * See the License for the specific language governing permissions and 16767 * limitations under the License. 16768 * 16769 * @providesModule getActiveElement 16770 * @typechecks 16771 */ 16772 16773 /** 16774 * Same as document.activeElement but wraps in a try-catch block. In IE it is 16775 * not safe to call document.activeElement if there is nothing focused. 16776 * 16777 * The activeElement will be null only if the document body is not yet defined. 16778 */ 16779 function getActiveElement() /*?DOMElement*/ { 16780 try { 16781 return document.activeElement || document.body; 16782 } catch (e) { 16783 return document.body; 16784 } 16785 } 16786 16787 module.exports = getActiveElement; 16788 16789 },{}],116:[function(_dereq_,module,exports){ 16790 /** 16791 * Copyright 2013-2014 Facebook, Inc. 16792 * 16793 * Licensed under the Apache License, Version 2.0 (the "License"); 16794 * you may not use this file except in compliance with the License. 16795 * You may obtain a copy of the License at 16796 * 16797 * http://www.apache.org/licenses/LICENSE-2.0 16798 * 16799 * Unless required by applicable law or agreed to in writing, software 16800 * distributed under the License is distributed on an "AS IS" BASIS, 16801 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16802 * See the License for the specific language governing permissions and 16803 * limitations under the License. 16804 * 16805 * @providesModule getEventKey 16806 * @typechecks static-only 16807 */ 16808 16809 "use strict"; 16810 16811 /** 16812 * Normalization of deprecated HTML5 "key" values 16813 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 16814 */ 16815 var normalizeKey = { 16816 'Esc': 'Escape', 16817 'Spacebar': ' ', 16818 'Left': 'ArrowLeft', 16819 'Up': 'ArrowUp', 16820 'Right': 'ArrowRight', 16821 'Down': 'ArrowDown', 16822 'Del': 'Delete', 16823 'Win': 'OS', 16824 'Menu': 'ContextMenu', 16825 'Apps': 'ContextMenu', 16826 'Scroll': 'ScrollLock', 16827 'MozPrintableKey': 'Unidentified' 16828 }; 16829 16830 /** 16831 * Translation from legacy "which/keyCode" to HTML5 "key" 16832 * Only special keys supported, all others depend on keyboard layout or browser 16833 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names 16834 */ 16835 var translateToKey = { 16836 8: 'Backspace', 16837 9: 'Tab', 16838 12: 'Clear', 16839 13: 'Enter', 16840 16: 'Shift', 16841 17: 'Control', 16842 18: 'Alt', 16843 19: 'Pause', 16844 20: 'CapsLock', 16845 27: 'Escape', 16846 32: ' ', 16847 33: 'PageUp', 16848 34: 'PageDown', 16849 35: 'End', 16850 36: 'Home', 16851 37: 'ArrowLeft', 16852 38: 'ArrowUp', 16853 39: 'ArrowRight', 16854 40: 'ArrowDown', 16855 45: 'Insert', 16856 46: 'Delete', 16857 112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6', 16858 118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12', 16859 144: 'NumLock', 16860 145: 'ScrollLock', 16861 224: 'Meta' 16862 }; 16863 16864 /** 16865 * @param {object} nativeEvent Native browser event. 16866 * @return {string} Normalized `key` property. 16867 */ 16868 function getEventKey(nativeEvent) { 16869 return 'key' in nativeEvent ? 16870 normalizeKey[nativeEvent.key] || nativeEvent.key : 16871 translateToKey[nativeEvent.which || nativeEvent.keyCode] || 'Unidentified'; 16872 } 16873 16874 module.exports = getEventKey; 16875 16876 },{}],117:[function(_dereq_,module,exports){ 16877 /** 16878 * Copyright 2013-2014 Facebook, Inc. 16879 * 16880 * Licensed under the Apache License, Version 2.0 (the "License"); 16881 * you may not use this file except in compliance with the License. 16882 * You may obtain a copy of the License at 16883 * 16884 * http://www.apache.org/licenses/LICENSE-2.0 16885 * 16886 * Unless required by applicable law or agreed to in writing, software 16887 * distributed under the License is distributed on an "AS IS" BASIS, 16888 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16889 * See the License for the specific language governing permissions and 16890 * limitations under the License. 16891 * 16892 * @providesModule getEventTarget 16893 * @typechecks static-only 16894 */ 16895 16896 "use strict"; 16897 16898 /** 16899 * Gets the target node from a native browser event by accounting for 16900 * inconsistencies in browser DOM APIs. 16901 * 16902 * @param {object} nativeEvent Native browser event. 16903 * @return {DOMEventTarget} Target node. 16904 */ 16905 function getEventTarget(nativeEvent) { 16906 var target = nativeEvent.target || nativeEvent.srcElement || window; 16907 // Safari may fire events on text nodes (Node.TEXT_NODE is 3). 16908 // @see http://www.quirksmode.org/js/events_properties.html 16909 return target.nodeType === 3 ? target.parentNode : target; 16910 } 16911 16912 module.exports = getEventTarget; 16913 16914 },{}],118:[function(_dereq_,module,exports){ 16915 /** 16916 * Copyright 2013-2014 Facebook, Inc. 16917 * 16918 * Licensed under the Apache License, Version 2.0 (the "License"); 16919 * you may not use this file except in compliance with the License. 16920 * You may obtain a copy of the License at 16921 * 16922 * http://www.apache.org/licenses/LICENSE-2.0 16923 * 16924 * Unless required by applicable law or agreed to in writing, software 16925 * distributed under the License is distributed on an "AS IS" BASIS, 16926 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16927 * See the License for the specific language governing permissions and 16928 * limitations under the License. 16929 * 16930 * @providesModule getMarkupWrap 16931 */ 16932 16933 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 16934 16935 var invariant = _dereq_("./invariant"); 16936 16937 /** 16938 * Dummy container used to detect which wraps are necessary. 16939 */ 16940 var dummyNode = 16941 ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; 16942 16943 /** 16944 * Some browsers cannot use `innerHTML` to render certain elements standalone, 16945 * so we wrap them, render the wrapped nodes, then extract the desired node. 16946 * 16947 * In IE8, certain elements cannot render alone, so wrap all elements ('*'). 16948 */ 16949 var shouldWrap = { 16950 // Force wrapping for SVG elements because if they get created inside a <div>, 16951 // they will be initialized in the wrong namespace (and will not display). 16952 'circle': true, 16953 'defs': true, 16954 'g': true, 16955 'line': true, 16956 'linearGradient': true, 16957 'path': true, 16958 'polygon': true, 16959 'polyline': true, 16960 'radialGradient': true, 16961 'rect': true, 16962 'stop': true, 16963 'text': true 16964 }; 16965 16966 var selectWrap = [1, '<select multiple="true">', '</select>']; 16967 var tableWrap = [1, '<table>', '</table>']; 16968 var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; 16969 16970 var svgWrap = [1, '<svg>', '</svg>']; 16971 16972 var markupWrap = { 16973 '*': [1, '?<div>', '</div>'], 16974 16975 'area': [1, '<map>', '</map>'], 16976 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], 16977 'legend': [1, '<fieldset>', '</fieldset>'], 16978 'param': [1, '<object>', '</object>'], 16979 'tr': [2, '<table><tbody>', '</tbody></table>'], 16980 16981 'optgroup': selectWrap, 16982 'option': selectWrap, 16983 16984 'caption': tableWrap, 16985 'colgroup': tableWrap, 16986 'tbody': tableWrap, 16987 'tfoot': tableWrap, 16988 'thead': tableWrap, 16989 16990 'td': trWrap, 16991 'th': trWrap, 16992 16993 'circle': svgWrap, 16994 'defs': svgWrap, 16995 'g': svgWrap, 16996 'line': svgWrap, 16997 'linearGradient': svgWrap, 16998 'path': svgWrap, 16999 'polygon': svgWrap, 17000 'polyline': svgWrap, 17001 'radialGradient': svgWrap, 17002 'rect': svgWrap, 17003 'stop': svgWrap, 17004 'text': svgWrap 17005 }; 17006 17007 /** 17008 * Gets the markup wrap configuration for the supplied `nodeName`. 17009 * 17010 * NOTE: This lazily detects which wraps are necessary for the current browser. 17011 * 17012 * @param {string} nodeName Lowercase `nodeName`. 17013 * @return {?array} Markup wrap configuration, if applicable. 17014 */ 17015 function getMarkupWrap(nodeName) { 17016 ("production" !== "development" ? invariant(!!dummyNode, 'Markup wrapping node not initialized') : invariant(!!dummyNode)); 17017 if (!markupWrap.hasOwnProperty(nodeName)) { 17018 nodeName = '*'; 17019 } 17020 if (!shouldWrap.hasOwnProperty(nodeName)) { 17021 if (nodeName === '*') { 17022 dummyNode.innerHTML = '<link />'; 17023 } else { 17024 dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; 17025 } 17026 shouldWrap[nodeName] = !dummyNode.firstChild; 17027 } 17028 return shouldWrap[nodeName] ? markupWrap[nodeName] : null; 17029 } 17030 17031 17032 module.exports = getMarkupWrap; 17033 17034 },{"./ExecutionEnvironment":21,"./invariant":125}],119:[function(_dereq_,module,exports){ 17035 /** 17036 * Copyright 2013-2014 Facebook, Inc. 17037 * 17038 * Licensed under the Apache License, Version 2.0 (the "License"); 17039 * you may not use this file except in compliance with the License. 17040 * You may obtain a copy of the License at 17041 * 17042 * http://www.apache.org/licenses/LICENSE-2.0 17043 * 17044 * Unless required by applicable law or agreed to in writing, software 17045 * distributed under the License is distributed on an "AS IS" BASIS, 17046 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17047 * See the License for the specific language governing permissions and 17048 * limitations under the License. 17049 * 17050 * @providesModule getNodeForCharacterOffset 17051 */ 17052 17053 "use strict"; 17054 17055 /** 17056 * Given any node return the first leaf node without children. 17057 * 17058 * @param {DOMElement|DOMTextNode} node 17059 * @return {DOMElement|DOMTextNode} 17060 */ 17061 function getLeafNode(node) { 17062 while (node && node.firstChild) { 17063 node = node.firstChild; 17064 } 17065 return node; 17066 } 17067 17068 /** 17069 * Get the next sibling within a container. This will walk up the 17070 * DOM if a node's siblings have been exhausted. 17071 * 17072 * @param {DOMElement|DOMTextNode} node 17073 * @return {?DOMElement|DOMTextNode} 17074 */ 17075 function getSiblingNode(node) { 17076 while (node) { 17077 if (node.nextSibling) { 17078 return node.nextSibling; 17079 } 17080 node = node.parentNode; 17081 } 17082 } 17083 17084 /** 17085 * Get object describing the nodes which contain characters at offset. 17086 * 17087 * @param {DOMElement|DOMTextNode} root 17088 * @param {number} offset 17089 * @return {?object} 17090 */ 17091 function getNodeForCharacterOffset(root, offset) { 17092 var node = getLeafNode(root); 17093 var nodeStart = 0; 17094 var nodeEnd = 0; 17095 17096 while (node) { 17097 if (node.nodeType == 3) { 17098 nodeEnd = nodeStart + node.textContent.length; 17099 17100 if (nodeStart <= offset && nodeEnd >= offset) { 17101 return { 17102 node: node, 17103 offset: offset - nodeStart 17104 }; 17105 } 17106 17107 nodeStart = nodeEnd; 17108 } 17109 17110 node = getLeafNode(getSiblingNode(node)); 17111 } 17112 } 17113 17114 module.exports = getNodeForCharacterOffset; 17115 17116 },{}],120:[function(_dereq_,module,exports){ 17117 /** 17118 * Copyright 2013-2014 Facebook, Inc. 17119 * 17120 * Licensed under the Apache License, Version 2.0 (the "License"); 17121 * you may not use this file except in compliance with the License. 17122 * You may obtain a copy of the License at 17123 * 17124 * http://www.apache.org/licenses/LICENSE-2.0 17125 * 17126 * Unless required by applicable law or agreed to in writing, software 17127 * distributed under the License is distributed on an "AS IS" BASIS, 17128 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17129 * See the License for the specific language governing permissions and 17130 * limitations under the License. 17131 * 17132 * @providesModule getReactRootElementInContainer 17133 */ 17134 17135 "use strict"; 17136 17137 var DOC_NODE_TYPE = 9; 17138 17139 /** 17140 * @param {DOMElement|DOMDocument} container DOM element that may contain 17141 * a React component 17142 * @return {?*} DOM element that may have the reactRoot ID, or null. 17143 */ 17144 function getReactRootElementInContainer(container) { 17145 if (!container) { 17146 return null; 17147 } 17148 17149 if (container.nodeType === DOC_NODE_TYPE) { 17150 return container.documentElement; 17151 } else { 17152 return container.firstChild; 17153 } 17154 } 17155 17156 module.exports = getReactRootElementInContainer; 17157 17158 },{}],121:[function(_dereq_,module,exports){ 17159 /** 17160 * Copyright 2013-2014 Facebook, Inc. 17161 * 17162 * Licensed under the Apache License, Version 2.0 (the "License"); 17163 * you may not use this file except in compliance with the License. 17164 * You may obtain a copy of the License at 17165 * 17166 * http://www.apache.org/licenses/LICENSE-2.0 17167 * 17168 * Unless required by applicable law or agreed to in writing, software 17169 * distributed under the License is distributed on an "AS IS" BASIS, 17170 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17171 * See the License for the specific language governing permissions and 17172 * limitations under the License. 17173 * 17174 * @providesModule getTextContentAccessor 17175 */ 17176 17177 "use strict"; 17178 17179 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 17180 17181 var contentKey = null; 17182 17183 /** 17184 * Gets the key used to access text content on a DOM node. 17185 * 17186 * @return {?string} Key used to access text content. 17187 * @internal 17188 */ 17189 function getTextContentAccessor() { 17190 if (!contentKey && ExecutionEnvironment.canUseDOM) { 17191 // Prefer textContent to innerText because many browsers support both but 17192 // SVG <text> elements don't support innerText even when <div> does. 17193 contentKey = 'textContent' in document.createElement('div') ? 17194 'textContent' : 17195 'innerText'; 17196 } 17197 return contentKey; 17198 } 17199 17200 module.exports = getTextContentAccessor; 17201 17202 },{"./ExecutionEnvironment":21}],122:[function(_dereq_,module,exports){ 17203 /** 17204 * Copyright 2013-2014 Facebook, Inc. 17205 * 17206 * Licensed under the Apache License, Version 2.0 (the "License"); 17207 * you may not use this file except in compliance with the License. 17208 * You may obtain a copy of the License at 17209 * 17210 * http://www.apache.org/licenses/LICENSE-2.0 17211 * 17212 * Unless required by applicable law or agreed to in writing, software 17213 * distributed under the License is distributed on an "AS IS" BASIS, 17214 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17215 * See the License for the specific language governing permissions and 17216 * limitations under the License. 17217 * 17218 * @providesModule getUnboundedScrollPosition 17219 * @typechecks 17220 */ 17221 17222 "use strict"; 17223 17224 /** 17225 * Gets the scroll position of the supplied element or window. 17226 * 17227 * The return values are unbounded, unlike `getScrollPosition`. This means they 17228 * may be negative or exceed the element boundaries (which is possible using 17229 * inertial scrolling). 17230 * 17231 * @param {DOMWindow|DOMElement} scrollable 17232 * @return {object} Map with `x` and `y` keys. 17233 */ 17234 function getUnboundedScrollPosition(scrollable) { 17235 if (scrollable === window) { 17236 return { 17237 x: window.pageXOffset || document.documentElement.scrollLeft, 17238 y: window.pageYOffset || document.documentElement.scrollTop 17239 }; 17240 } 17241 return { 17242 x: scrollable.scrollLeft, 17243 y: scrollable.scrollTop 17244 }; 17245 } 17246 17247 module.exports = getUnboundedScrollPosition; 17248 17249 },{}],123:[function(_dereq_,module,exports){ 17250 /** 17251 * Copyright 2013-2014 Facebook, Inc. 17252 * 17253 * Licensed under the Apache License, Version 2.0 (the "License"); 17254 * you may not use this file except in compliance with the License. 17255 * You may obtain a copy of the License at 17256 * 17257 * http://www.apache.org/licenses/LICENSE-2.0 17258 * 17259 * Unless required by applicable law or agreed to in writing, software 17260 * distributed under the License is distributed on an "AS IS" BASIS, 17261 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17262 * See the License for the specific language governing permissions and 17263 * limitations under the License. 17264 * 17265 * @providesModule hyphenate 17266 * @typechecks 17267 */ 17268 17269 var _uppercasePattern = /([A-Z])/g; 17270 17271 /** 17272 * Hyphenates a camelcased string, for example: 17273 * 17274 * > hyphenate('backgroundColor') 17275 * < "background-color" 17276 * 17277 * @param {string} string 17278 * @return {string} 17279 */ 17280 function hyphenate(string) { 17281 return string.replace(_uppercasePattern, '-$1').toLowerCase(); 17282 } 17283 17284 module.exports = hyphenate; 17285 17286 },{}],124:[function(_dereq_,module,exports){ 17287 /** 17288 * Copyright 2013-2014 Facebook, Inc. 17289 * 17290 * Licensed under the Apache License, Version 2.0 (the "License"); 17291 * you may not use this file except in compliance with the License. 17292 * You may obtain a copy of the License at 17293 * 17294 * http://www.apache.org/licenses/LICENSE-2.0 17295 * 17296 * Unless required by applicable law or agreed to in writing, software 17297 * distributed under the License is distributed on an "AS IS" BASIS, 17298 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17299 * See the License for the specific language governing permissions and 17300 * limitations under the License. 17301 * 17302 * @providesModule instantiateReactComponent 17303 * @typechecks static-only 17304 */ 17305 17306 "use strict"; 17307 17308 var warning = _dereq_("./warning"); 17309 17310 /** 17311 * Validate a `componentDescriptor`. This should be exposed publicly in a follow 17312 * up diff. 17313 * 17314 * @param {object} descriptor 17315 * @return {boolean} Returns true if this is a valid descriptor of a Component. 17316 */ 17317 function isValidComponentDescriptor(descriptor) { 17318 return ( 17319 typeof descriptor.constructor === 'function' && 17320 typeof descriptor.constructor.prototype.construct === 'function' && 17321 typeof descriptor.constructor.prototype.mountComponent === 'function' && 17322 typeof descriptor.constructor.prototype.receiveComponent === 'function' 17323 ); 17324 } 17325 17326 /** 17327 * Given a `componentDescriptor` create an instance that will actually be 17328 * mounted. Currently it just extracts an existing clone from composite 17329 * components but this is an implementation detail which will change. 17330 * 17331 * @param {object} descriptor 17332 * @return {object} A new instance of componentDescriptor's constructor. 17333 * @protected 17334 */ 17335 function instantiateReactComponent(descriptor) { 17336 if ("production" !== "development") { 17337 ("production" !== "development" ? warning( 17338 isValidComponentDescriptor(descriptor), 17339 'Only React Components are valid for mounting.' 17340 ) : null); 17341 // We use the clone of a composite component instead of the original 17342 // instance. This allows us to warn you if you're are accessing the wrong 17343 // instance. 17344 var instance = descriptor.__realComponentInstance || descriptor; 17345 instance._descriptor = descriptor; 17346 return instance; 17347 } 17348 // In prod we don't clone, we simply use the same instance for unaffected 17349 // behavior. We have to keep the descriptor around for comparison later on. 17350 // This should ideally be accepted in the constructor of the instance but 17351 // since that is currently overloaded, we just manually attach it here. 17352 descriptor._descriptor = descriptor; 17353 return descriptor; 17354 } 17355 17356 module.exports = instantiateReactComponent; 17357 17358 },{"./warning":148}],125:[function(_dereq_,module,exports){ 17359 /** 17360 * Copyright 2013-2014 Facebook, Inc. 17361 * 17362 * Licensed under the Apache License, Version 2.0 (the "License"); 17363 * you may not use this file except in compliance with the License. 17364 * You may obtain a copy of the License at 17365 * 17366 * http://www.apache.org/licenses/LICENSE-2.0 17367 * 17368 * Unless required by applicable law or agreed to in writing, software 17369 * distributed under the License is distributed on an "AS IS" BASIS, 17370 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17371 * See the License for the specific language governing permissions and 17372 * limitations under the License. 17373 * 17374 * @providesModule invariant 17375 */ 17376 17377 "use strict"; 17378 17379 /** 17380 * Use invariant() to assert state which your program assumes to be true. 17381 * 17382 * Provide sprintf-style format (only %s is supported) and arguments 17383 * to provide information about what broke and what you were 17384 * expecting. 17385 * 17386 * The invariant message will be stripped in production, but the invariant 17387 * will remain to ensure logic does not differ in production. 17388 */ 17389 17390 var invariant = function(condition) { 17391 if (!condition) { 17392 var error = new Error( 17393 'Minified exception occured; use the non-minified dev environment for ' + 17394 'the full error message and additional helpful warnings.' 17395 ); 17396 error.framesToPop = 1; 17397 throw error; 17398 } 17399 }; 17400 17401 if ("production" !== "development") { 17402 invariant = function(condition, format, a, b, c, d, e, f) { 17403 if (format === undefined) { 17404 throw new Error('invariant requires an error message argument'); 17405 } 17406 17407 if (!condition) { 17408 var args = [a, b, c, d, e, f]; 17409 var argIndex = 0; 17410 var error = new Error( 17411 'Invariant Violation: ' + 17412 format.replace(/%s/g, function() { return args[argIndex++]; }) 17413 ); 17414 error.framesToPop = 1; // we don't care about invariant's own frame 17415 throw error; 17416 } 17417 }; 17418 } 17419 17420 module.exports = invariant; 17421 17422 },{}],126:[function(_dereq_,module,exports){ 17423 /** 17424 * Copyright 2013-2014 Facebook, Inc. 17425 * 17426 * Licensed under the Apache License, Version 2.0 (the "License"); 17427 * you may not use this file except in compliance with the License. 17428 * You may obtain a copy of the License at 17429 * 17430 * http://www.apache.org/licenses/LICENSE-2.0 17431 * 17432 * Unless required by applicable law or agreed to in writing, software 17433 * distributed under the License is distributed on an "AS IS" BASIS, 17434 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17435 * See the License for the specific language governing permissions and 17436 * limitations under the License. 17437 * 17438 * @providesModule isEventSupported 17439 */ 17440 17441 "use strict"; 17442 17443 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 17444 17445 var useHasFeature; 17446 if (ExecutionEnvironment.canUseDOM) { 17447 useHasFeature = 17448 document.implementation && 17449 document.implementation.hasFeature && 17450 // always returns true in newer browsers as per the standard. 17451 // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature 17452 document.implementation.hasFeature('', '') !== true; 17453 } 17454 17455 /** 17456 * Checks if an event is supported in the current execution environment. 17457 * 17458 * NOTE: This will not work correctly for non-generic events such as `change`, 17459 * `reset`, `load`, `error`, and `select`. 17460 * 17461 * Borrows from Modernizr. 17462 * 17463 * @param {string} eventNameSuffix Event name, e.g. "click". 17464 * @param {?boolean} capture Check if the capture phase is supported. 17465 * @return {boolean} True if the event is supported. 17466 * @internal 17467 * @license Modernizr 3.0.0pre (Custom Build) | MIT 17468 */ 17469 function isEventSupported(eventNameSuffix, capture) { 17470 if (!ExecutionEnvironment.canUseDOM || 17471 capture && !('addEventListener' in document)) { 17472 return false; 17473 } 17474 17475 var eventName = 'on' + eventNameSuffix; 17476 var isSupported = eventName in document; 17477 17478 if (!isSupported) { 17479 var element = document.createElement('div'); 17480 element.setAttribute(eventName, 'return;'); 17481 isSupported = typeof element[eventName] === 'function'; 17482 } 17483 17484 if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { 17485 // This is the only way to test support for the `wheel` event in IE9+. 17486 isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); 17487 } 17488 17489 return isSupported; 17490 } 17491 17492 module.exports = isEventSupported; 17493 17494 },{"./ExecutionEnvironment":21}],127:[function(_dereq_,module,exports){ 17495 /** 17496 * Copyright 2013-2014 Facebook, Inc. 17497 * 17498 * Licensed under the Apache License, Version 2.0 (the "License"); 17499 * you may not use this file except in compliance with the License. 17500 * You may obtain a copy of the License at 17501 * 17502 * http://www.apache.org/licenses/LICENSE-2.0 17503 * 17504 * Unless required by applicable law or agreed to in writing, software 17505 * distributed under the License is distributed on an "AS IS" BASIS, 17506 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17507 * See the License for the specific language governing permissions and 17508 * limitations under the License. 17509 * 17510 * @providesModule isNode 17511 * @typechecks 17512 */ 17513 17514 /** 17515 * @param {*} object The object to check. 17516 * @return {boolean} Whether or not the object is a DOM node. 17517 */ 17518 function isNode(object) { 17519 return !!(object && ( 17520 typeof Node === 'function' ? object instanceof Node : 17521 typeof object === 'object' && 17522 typeof object.nodeType === 'number' && 17523 typeof object.nodeName === 'string' 17524 )); 17525 } 17526 17527 module.exports = isNode; 17528 17529 },{}],128:[function(_dereq_,module,exports){ 17530 /** 17531 * Copyright 2013-2014 Facebook, Inc. 17532 * 17533 * Licensed under the Apache License, Version 2.0 (the "License"); 17534 * you may not use this file except in compliance with the License. 17535 * You may obtain a copy of the License at 17536 * 17537 * http://www.apache.org/licenses/LICENSE-2.0 17538 * 17539 * Unless required by applicable law or agreed to in writing, software 17540 * distributed under the License is distributed on an "AS IS" BASIS, 17541 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17542 * See the License for the specific language governing permissions and 17543 * limitations under the License. 17544 * 17545 * @providesModule isTextInputElement 17546 */ 17547 17548 "use strict"; 17549 17550 /** 17551 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary 17552 */ 17553 var supportedInputTypes = { 17554 'color': true, 17555 'date': true, 17556 'datetime': true, 17557 'datetime-local': true, 17558 'email': true, 17559 'month': true, 17560 'number': true, 17561 'password': true, 17562 'range': true, 17563 'search': true, 17564 'tel': true, 17565 'text': true, 17566 'time': true, 17567 'url': true, 17568 'week': true 17569 }; 17570 17571 function isTextInputElement(elem) { 17572 return elem && ( 17573 (elem.nodeName === 'INPUT' && supportedInputTypes[elem.type]) || 17574 elem.nodeName === 'TEXTAREA' 17575 ); 17576 } 17577 17578 module.exports = isTextInputElement; 17579 17580 },{}],129:[function(_dereq_,module,exports){ 17581 /** 17582 * Copyright 2013-2014 Facebook, Inc. 17583 * 17584 * Licensed under the Apache License, Version 2.0 (the "License"); 17585 * you may not use this file except in compliance with the License. 17586 * You may obtain a copy of the License at 17587 * 17588 * http://www.apache.org/licenses/LICENSE-2.0 17589 * 17590 * Unless required by applicable law or agreed to in writing, software 17591 * distributed under the License is distributed on an "AS IS" BASIS, 17592 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17593 * See the License for the specific language governing permissions and 17594 * limitations under the License. 17595 * 17596 * @providesModule isTextNode 17597 * @typechecks 17598 */ 17599 17600 var isNode = _dereq_("./isNode"); 17601 17602 /** 17603 * @param {*} object The object to check. 17604 * @return {boolean} Whether or not the object is a DOM text node. 17605 */ 17606 function isTextNode(object) { 17607 return isNode(object) && object.nodeType == 3; 17608 } 17609 17610 module.exports = isTextNode; 17611 17612 },{"./isNode":127}],130:[function(_dereq_,module,exports){ 17613 /** 17614 * Copyright 2013-2014 Facebook, Inc. 17615 * 17616 * Licensed under the Apache License, Version 2.0 (the "License"); 17617 * you may not use this file except in compliance with the License. 17618 * You may obtain a copy of the License at 17619 * 17620 * http://www.apache.org/licenses/LICENSE-2.0 17621 * 17622 * Unless required by applicable law or agreed to in writing, software 17623 * distributed under the License is distributed on an "AS IS" BASIS, 17624 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17625 * See the License for the specific language governing permissions and 17626 * limitations under the License. 17627 * 17628 * @providesModule joinClasses 17629 * @typechecks static-only 17630 */ 17631 17632 "use strict"; 17633 17634 /** 17635 * Combines multiple className strings into one. 17636 * http://jsperf.com/joinclasses-args-vs-array 17637 * 17638 * @param {...?string} classes 17639 * @return {string} 17640 */ 17641 function joinClasses(className/*, ... */) { 17642 if (!className) { 17643 className = ''; 17644 } 17645 var nextClass; 17646 var argLength = arguments.length; 17647 if (argLength > 1) { 17648 for (var ii = 1; ii < argLength; ii++) { 17649 nextClass = arguments[ii]; 17650 nextClass && (className += ' ' + nextClass); 17651 } 17652 } 17653 return className; 17654 } 17655 17656 module.exports = joinClasses; 17657 17658 },{}],131:[function(_dereq_,module,exports){ 17659 /** 17660 * Copyright 2013-2014 Facebook, Inc. 17661 * 17662 * Licensed under the Apache License, Version 2.0 (the "License"); 17663 * you may not use this file except in compliance with the License. 17664 * You may obtain a copy of the License at 17665 * 17666 * http://www.apache.org/licenses/LICENSE-2.0 17667 * 17668 * Unless required by applicable law or agreed to in writing, software 17669 * distributed under the License is distributed on an "AS IS" BASIS, 17670 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17671 * See the License for the specific language governing permissions and 17672 * limitations under the License. 17673 * 17674 * @providesModule keyMirror 17675 * @typechecks static-only 17676 */ 17677 17678 "use strict"; 17679 17680 var invariant = _dereq_("./invariant"); 17681 17682 /** 17683 * Constructs an enumeration with keys equal to their value. 17684 * 17685 * For example: 17686 * 17687 * var COLORS = keyMirror({blue: null, red: null}); 17688 * var myColor = COLORS.blue; 17689 * var isColorValid = !!COLORS[myColor]; 17690 * 17691 * The last line could not be performed if the values of the generated enum were 17692 * not equal to their keys. 17693 * 17694 * Input: {key1: val1, key2: val2} 17695 * Output: {key1: key1, key2: key2} 17696 * 17697 * @param {object} obj 17698 * @return {object} 17699 */ 17700 var keyMirror = function(obj) { 17701 var ret = {}; 17702 var key; 17703 ("production" !== "development" ? invariant( 17704 obj instanceof Object && !Array.isArray(obj), 17705 'keyMirror(...): Argument must be an object.' 17706 ) : invariant(obj instanceof Object && !Array.isArray(obj))); 17707 for (key in obj) { 17708 if (!obj.hasOwnProperty(key)) { 17709 continue; 17710 } 17711 ret[key] = key; 17712 } 17713 return ret; 17714 }; 17715 17716 module.exports = keyMirror; 17717 17718 },{"./invariant":125}],132:[function(_dereq_,module,exports){ 17719 /** 17720 * Copyright 2013-2014 Facebook, Inc. 17721 * 17722 * Licensed under the Apache License, Version 2.0 (the "License"); 17723 * you may not use this file except in compliance with the License. 17724 * You may obtain a copy of the License at 17725 * 17726 * http://www.apache.org/licenses/LICENSE-2.0 17727 * 17728 * Unless required by applicable law or agreed to in writing, software 17729 * distributed under the License is distributed on an "AS IS" BASIS, 17730 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17731 * See the License for the specific language governing permissions and 17732 * limitations under the License. 17733 * 17734 * @providesModule keyOf 17735 */ 17736 17737 /** 17738 * Allows extraction of a minified key. Let's the build system minify keys 17739 * without loosing the ability to dynamically use key strings as values 17740 * themselves. Pass in an object with a single key/val pair and it will return 17741 * you the string key of that single record. Suppose you want to grab the 17742 * value for a key 'className' inside of an object. Key/val minification may 17743 * have aliased that key to be 'xa12'. keyOf({className: null}) will return 17744 * 'xa12' in that case. Resolve keys you want to use once at startup time, then 17745 * reuse those resolutions. 17746 */ 17747 var keyOf = function(oneKeyObj) { 17748 var key; 17749 for (key in oneKeyObj) { 17750 if (!oneKeyObj.hasOwnProperty(key)) { 17751 continue; 17752 } 17753 return key; 17754 } 17755 return null; 17756 }; 17757 17758 17759 module.exports = keyOf; 17760 17761 },{}],133:[function(_dereq_,module,exports){ 17762 /** 17763 * Copyright 2013-2014 Facebook, Inc. 17764 * 17765 * Licensed under the Apache License, Version 2.0 (the "License"); 17766 * you may not use this file except in compliance with the License. 17767 * You may obtain a copy of the License at 17768 * 17769 * http://www.apache.org/licenses/LICENSE-2.0 17770 * 17771 * Unless required by applicable law or agreed to in writing, software 17772 * distributed under the License is distributed on an "AS IS" BASIS, 17773 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17774 * See the License for the specific language governing permissions and 17775 * limitations under the License. 17776 * 17777 * @providesModule memoizeStringOnly 17778 * @typechecks static-only 17779 */ 17780 17781 "use strict"; 17782 17783 /** 17784 * Memoizes the return value of a function that accepts one string argument. 17785 * 17786 * @param {function} callback 17787 * @return {function} 17788 */ 17789 function memoizeStringOnly(callback) { 17790 var cache = {}; 17791 return function(string) { 17792 if (cache.hasOwnProperty(string)) { 17793 return cache[string]; 17794 } else { 17795 return cache[string] = callback.call(this, string); 17796 } 17797 }; 17798 } 17799 17800 module.exports = memoizeStringOnly; 17801 17802 },{}],134:[function(_dereq_,module,exports){ 17803 /** 17804 * Copyright 2013-2014 Facebook, Inc. 17805 * 17806 * Licensed under the Apache License, Version 2.0 (the "License"); 17807 * you may not use this file except in compliance with the License. 17808 * You may obtain a copy of the License at 17809 * 17810 * http://www.apache.org/licenses/LICENSE-2.0 17811 * 17812 * Unless required by applicable law or agreed to in writing, software 17813 * distributed under the License is distributed on an "AS IS" BASIS, 17814 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17815 * See the License for the specific language governing permissions and 17816 * limitations under the License. 17817 * 17818 * @providesModule merge 17819 */ 17820 17821 "use strict"; 17822 17823 var mergeInto = _dereq_("./mergeInto"); 17824 17825 /** 17826 * Shallow merges two structures into a return value, without mutating either. 17827 * 17828 * @param {?object} one Optional object with properties to merge from. 17829 * @param {?object} two Optional object with properties to merge from. 17830 * @return {object} The shallow extension of one by two. 17831 */ 17832 var merge = function(one, two) { 17833 var result = {}; 17834 mergeInto(result, one); 17835 mergeInto(result, two); 17836 return result; 17837 }; 17838 17839 module.exports = merge; 17840 17841 },{"./mergeInto":136}],135:[function(_dereq_,module,exports){ 17842 /** 17843 * Copyright 2013-2014 Facebook, Inc. 17844 * 17845 * Licensed under the Apache License, Version 2.0 (the "License"); 17846 * you may not use this file except in compliance with the License. 17847 * You may obtain a copy of the License at 17848 * 17849 * http://www.apache.org/licenses/LICENSE-2.0 17850 * 17851 * Unless required by applicable law or agreed to in writing, software 17852 * distributed under the License is distributed on an "AS IS" BASIS, 17853 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17854 * See the License for the specific language governing permissions and 17855 * limitations under the License. 17856 * 17857 * @providesModule mergeHelpers 17858 * 17859 * requiresPolyfills: Array.isArray 17860 */ 17861 17862 "use strict"; 17863 17864 var invariant = _dereq_("./invariant"); 17865 var keyMirror = _dereq_("./keyMirror"); 17866 17867 /** 17868 * Maximum number of levels to traverse. Will catch circular structures. 17869 * @const 17870 */ 17871 var MAX_MERGE_DEPTH = 36; 17872 17873 /** 17874 * We won't worry about edge cases like new String('x') or new Boolean(true). 17875 * Functions are considered terminals, and arrays are not. 17876 * @param {*} o The item/object/value to test. 17877 * @return {boolean} true iff the argument is a terminal. 17878 */ 17879 var isTerminal = function(o) { 17880 return typeof o !== 'object' || o === null; 17881 }; 17882 17883 var mergeHelpers = { 17884 17885 MAX_MERGE_DEPTH: MAX_MERGE_DEPTH, 17886 17887 isTerminal: isTerminal, 17888 17889 /** 17890 * Converts null/undefined values into empty object. 17891 * 17892 * @param {?Object=} arg Argument to be normalized (nullable optional) 17893 * @return {!Object} 17894 */ 17895 normalizeMergeArg: function(arg) { 17896 return arg === undefined || arg === null ? {} : arg; 17897 }, 17898 17899 /** 17900 * If merging Arrays, a merge strategy *must* be supplied. If not, it is 17901 * likely the caller's fault. If this function is ever called with anything 17902 * but `one` and `two` being `Array`s, it is the fault of the merge utilities. 17903 * 17904 * @param {*} one Array to merge into. 17905 * @param {*} two Array to merge from. 17906 */ 17907 checkMergeArrayArgs: function(one, two) { 17908 ("production" !== "development" ? invariant( 17909 Array.isArray(one) && Array.isArray(two), 17910 'Tried to merge arrays, instead got %s and %s.', 17911 one, 17912 two 17913 ) : invariant(Array.isArray(one) && Array.isArray(two))); 17914 }, 17915 17916 /** 17917 * @param {*} one Object to merge into. 17918 * @param {*} two Object to merge from. 17919 */ 17920 checkMergeObjectArgs: function(one, two) { 17921 mergeHelpers.checkMergeObjectArg(one); 17922 mergeHelpers.checkMergeObjectArg(two); 17923 }, 17924 17925 /** 17926 * @param {*} arg 17927 */ 17928 checkMergeObjectArg: function(arg) { 17929 ("production" !== "development" ? invariant( 17930 !isTerminal(arg) && !Array.isArray(arg), 17931 'Tried to merge an object, instead got %s.', 17932 arg 17933 ) : invariant(!isTerminal(arg) && !Array.isArray(arg))); 17934 }, 17935 17936 /** 17937 * Checks that a merge was not given a circular object or an object that had 17938 * too great of depth. 17939 * 17940 * @param {number} Level of recursion to validate against maximum. 17941 */ 17942 checkMergeLevel: function(level) { 17943 ("production" !== "development" ? invariant( 17944 level < MAX_MERGE_DEPTH, 17945 'Maximum deep merge depth exceeded. You may be attempting to merge ' + 17946 'circular structures in an unsupported way.' 17947 ) : invariant(level < MAX_MERGE_DEPTH)); 17948 }, 17949 17950 /** 17951 * Checks that the supplied merge strategy is valid. 17952 * 17953 * @param {string} Array merge strategy. 17954 */ 17955 checkArrayStrategy: function(strategy) { 17956 ("production" !== "development" ? invariant( 17957 strategy === undefined || strategy in mergeHelpers.ArrayStrategies, 17958 'You must provide an array strategy to deep merge functions to ' + 17959 'instruct the deep merge how to resolve merging two arrays.' 17960 ) : invariant(strategy === undefined || strategy in mergeHelpers.ArrayStrategies)); 17961 }, 17962 17963 /** 17964 * Set of possible behaviors of merge algorithms when encountering two Arrays 17965 * that must be merged together. 17966 * - `clobber`: The left `Array` is ignored. 17967 * - `indexByIndex`: The result is achieved by recursively deep merging at 17968 * each index. (not yet supported.) 17969 */ 17970 ArrayStrategies: keyMirror({ 17971 Clobber: true, 17972 IndexByIndex: true 17973 }) 17974 17975 }; 17976 17977 module.exports = mergeHelpers; 17978 17979 },{"./invariant":125,"./keyMirror":131}],136:[function(_dereq_,module,exports){ 17980 /** 17981 * Copyright 2013-2014 Facebook, Inc. 17982 * 17983 * Licensed under the Apache License, Version 2.0 (the "License"); 17984 * you may not use this file except in compliance with the License. 17985 * You may obtain a copy of the License at 17986 * 17987 * http://www.apache.org/licenses/LICENSE-2.0 17988 * 17989 * Unless required by applicable law or agreed to in writing, software 17990 * distributed under the License is distributed on an "AS IS" BASIS, 17991 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17992 * See the License for the specific language governing permissions and 17993 * limitations under the License. 17994 * 17995 * @providesModule mergeInto 17996 * @typechecks static-only 17997 */ 17998 17999 "use strict"; 18000 18001 var mergeHelpers = _dereq_("./mergeHelpers"); 18002 18003 var checkMergeObjectArg = mergeHelpers.checkMergeObjectArg; 18004 18005 /** 18006 * Shallow merges two structures by mutating the first parameter. 18007 * 18008 * @param {object} one Object to be merged into. 18009 * @param {?object} two Optional object with properties to merge from. 18010 */ 18011 function mergeInto(one, two) { 18012 checkMergeObjectArg(one); 18013 if (two != null) { 18014 checkMergeObjectArg(two); 18015 for (var key in two) { 18016 if (!two.hasOwnProperty(key)) { 18017 continue; 18018 } 18019 one[key] = two[key]; 18020 } 18021 } 18022 } 18023 18024 module.exports = mergeInto; 18025 18026 },{"./mergeHelpers":135}],137:[function(_dereq_,module,exports){ 18027 /** 18028 * Copyright 2013-2014 Facebook, Inc. 18029 * 18030 * Licensed under the Apache License, Version 2.0 (the "License"); 18031 * you may not use this file except in compliance with the License. 18032 * You may obtain a copy of the License at 18033 * 18034 * http://www.apache.org/licenses/LICENSE-2.0 18035 * 18036 * Unless required by applicable law or agreed to in writing, software 18037 * distributed under the License is distributed on an "AS IS" BASIS, 18038 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18039 * See the License for the specific language governing permissions and 18040 * limitations under the License. 18041 * 18042 * @providesModule mixInto 18043 */ 18044 18045 "use strict"; 18046 18047 /** 18048 * Simply copies properties to the prototype. 18049 */ 18050 var mixInto = function(constructor, methodBag) { 18051 var methodName; 18052 for (methodName in methodBag) { 18053 if (!methodBag.hasOwnProperty(methodName)) { 18054 continue; 18055 } 18056 constructor.prototype[methodName] = methodBag[methodName]; 18057 } 18058 }; 18059 18060 module.exports = mixInto; 18061 18062 },{}],138:[function(_dereq_,module,exports){ 18063 /** 18064 * Copyright 2014 Facebook, Inc. 18065 * 18066 * Licensed under the Apache License, Version 2.0 (the "License"); 18067 * you may not use this file except in compliance with the License. 18068 * You may obtain a copy of the License at 18069 * 18070 * http://www.apache.org/licenses/LICENSE-2.0 18071 * 18072 * Unless required by applicable law or agreed to in writing, software 18073 * distributed under the License is distributed on an "AS IS" BASIS, 18074 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18075 * See the License for the specific language governing permissions and 18076 * limitations under the License. 18077 * 18078 * @providesModule monitorCodeUse 18079 */ 18080 18081 "use strict"; 18082 18083 var invariant = _dereq_("./invariant"); 18084 18085 /** 18086 * Provides open-source compatible instrumentation for monitoring certain API 18087 * uses before we're ready to issue a warning or refactor. It accepts an event 18088 * name which may only contain the characters [a-z0-9_] and an optional data 18089 * object with further information. 18090 */ 18091 18092 function monitorCodeUse(eventName, data) { 18093 ("production" !== "development" ? invariant( 18094 eventName && !/[^a-z0-9_]/.test(eventName), 18095 'You must provide an eventName using only the characters [a-z0-9_]' 18096 ) : invariant(eventName && !/[^a-z0-9_]/.test(eventName))); 18097 } 18098 18099 module.exports = monitorCodeUse; 18100 18101 },{"./invariant":125}],139:[function(_dereq_,module,exports){ 18102 /** 18103 * Copyright 2013-2014 Facebook, Inc. 18104 * 18105 * Licensed under the Apache License, Version 2.0 (the "License"); 18106 * you may not use this file except in compliance with the License. 18107 * You may obtain a copy of the License at 18108 * 18109 * http://www.apache.org/licenses/LICENSE-2.0 18110 * 18111 * Unless required by applicable law or agreed to in writing, software 18112 * distributed under the License is distributed on an "AS IS" BASIS, 18113 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18114 * See the License for the specific language governing permissions and 18115 * limitations under the License. 18116 * 18117 * @providesModule objMap 18118 */ 18119 18120 "use strict"; 18121 18122 /** 18123 * For each key/value pair, invokes callback func and constructs a resulting 18124 * object which contains, for every key in obj, values that are the result of 18125 * of invoking the function: 18126 * 18127 * func(value, key, iteration) 18128 * 18129 * @param {?object} obj Object to map keys over 18130 * @param {function} func Invoked for each key/val pair. 18131 * @param {?*} context 18132 * @return {?object} Result of mapping or null if obj is falsey 18133 */ 18134 function objMap(obj, func, context) { 18135 if (!obj) { 18136 return null; 18137 } 18138 var i = 0; 18139 var ret = {}; 18140 for (var key in obj) { 18141 if (obj.hasOwnProperty(key)) { 18142 ret[key] = func.call(context, obj[key], key, i++); 18143 } 18144 } 18145 return ret; 18146 } 18147 18148 module.exports = objMap; 18149 18150 },{}],140:[function(_dereq_,module,exports){ 18151 /** 18152 * Copyright 2013-2014 Facebook, Inc. 18153 * 18154 * Licensed under the Apache License, Version 2.0 (the "License"); 18155 * you may not use this file except in compliance with the License. 18156 * You may obtain a copy of the License at 18157 * 18158 * http://www.apache.org/licenses/LICENSE-2.0 18159 * 18160 * Unless required by applicable law or agreed to in writing, software 18161 * distributed under the License is distributed on an "AS IS" BASIS, 18162 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18163 * See the License for the specific language governing permissions and 18164 * limitations under the License. 18165 * 18166 * @providesModule objMapKeyVal 18167 */ 18168 18169 "use strict"; 18170 18171 /** 18172 * Behaves the same as `objMap` but invokes func with the key first, and value 18173 * second. Use `objMap` unless you need this special case. 18174 * Invokes func as: 18175 * 18176 * func(key, value, iteration) 18177 * 18178 * @param {?object} obj Object to map keys over 18179 * @param {!function} func Invoked for each key/val pair. 18180 * @param {?*} context 18181 * @return {?object} Result of mapping or null if obj is falsey 18182 */ 18183 function objMapKeyVal(obj, func, context) { 18184 if (!obj) { 18185 return null; 18186 } 18187 var i = 0; 18188 var ret = {}; 18189 for (var key in obj) { 18190 if (obj.hasOwnProperty(key)) { 18191 ret[key] = func.call(context, key, obj[key], i++); 18192 } 18193 } 18194 return ret; 18195 } 18196 18197 module.exports = objMapKeyVal; 18198 18199 },{}],141:[function(_dereq_,module,exports){ 18200 /** 18201 * Copyright 2013-2014 Facebook, Inc. 18202 * 18203 * Licensed under the Apache License, Version 2.0 (the "License"); 18204 * you may not use this file except in compliance with the License. 18205 * You may obtain a copy of the License at 18206 * 18207 * http://www.apache.org/licenses/LICENSE-2.0 18208 * 18209 * Unless required by applicable law or agreed to in writing, software 18210 * distributed under the License is distributed on an "AS IS" BASIS, 18211 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18212 * See the License for the specific language governing permissions and 18213 * limitations under the License. 18214 * 18215 * @providesModule onlyChild 18216 */ 18217 "use strict"; 18218 18219 var ReactComponent = _dereq_("./ReactComponent"); 18220 18221 var invariant = _dereq_("./invariant"); 18222 18223 /** 18224 * Returns the first child in a collection of children and verifies that there 18225 * is only one child in the collection. The current implementation of this 18226 * function assumes that a single child gets passed without a wrapper, but the 18227 * purpose of this helper function is to abstract away the particular structure 18228 * of children. 18229 * 18230 * @param {?object} children Child collection structure. 18231 * @return {ReactComponent} The first and only `ReactComponent` contained in the 18232 * structure. 18233 */ 18234 function onlyChild(children) { 18235 ("production" !== "development" ? invariant( 18236 ReactComponent.isValidComponent(children), 18237 'onlyChild must be passed a children with exactly one child.' 18238 ) : invariant(ReactComponent.isValidComponent(children))); 18239 return children; 18240 } 18241 18242 module.exports = onlyChild; 18243 18244 },{"./ReactComponent":31,"./invariant":125}],142:[function(_dereq_,module,exports){ 18245 /** 18246 * Copyright 2013-2014 Facebook, Inc. 18247 * 18248 * Licensed under the Apache License, Version 2.0 (the "License"); 18249 * you may not use this file except in compliance with the License. 18250 * You may obtain a copy of the License at 18251 * 18252 * http://www.apache.org/licenses/LICENSE-2.0 18253 * 18254 * Unless required by applicable law or agreed to in writing, software 18255 * distributed under the License is distributed on an "AS IS" BASIS, 18256 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18257 * See the License for the specific language governing permissions and 18258 * limitations under the License. 18259 * 18260 * @providesModule performanceNow 18261 * @typechecks static-only 18262 */ 18263 18264 "use strict"; 18265 18266 var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); 18267 18268 /** 18269 * Detect if we can use window.performance.now() and gracefully 18270 * fallback to Date.now() if it doesn't exist. 18271 * We need to support Firefox < 15 for now due to Facebook's webdriver 18272 * infrastructure. 18273 */ 18274 var performance = null; 18275 18276 if (ExecutionEnvironment.canUseDOM) { 18277 performance = window.performance || window.webkitPerformance; 18278 } 18279 18280 if (!performance || !performance.now) { 18281 performance = Date; 18282 } 18283 18284 var performanceNow = performance.now.bind(performance); 18285 18286 module.exports = performanceNow; 18287 18288 },{"./ExecutionEnvironment":21}],143:[function(_dereq_,module,exports){ 18289 /** 18290 * Copyright 2013-2014 Facebook, Inc. 18291 * 18292 * Licensed under the Apache License, Version 2.0 (the "License"); 18293 * you may not use this file except in compliance with the License. 18294 * You may obtain a copy of the License at 18295 * 18296 * http://www.apache.org/licenses/LICENSE-2.0 18297 * 18298 * Unless required by applicable law or agreed to in writing, software 18299 * distributed under the License is distributed on an "AS IS" BASIS, 18300 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18301 * See the License for the specific language governing permissions and 18302 * limitations under the License. 18303 * 18304 * @providesModule shallowEqual 18305 */ 18306 18307 "use strict"; 18308 18309 /** 18310 * Performs equality by iterating through keys on an object and returning 18311 * false when any key has values which are not strictly equal between 18312 * objA and objB. Returns true when the values of all keys are strictly equal. 18313 * 18314 * @return {boolean} 18315 */ 18316 function shallowEqual(objA, objB) { 18317 if (objA === objB) { 18318 return true; 18319 } 18320 var key; 18321 // Test for A's keys different from B. 18322 for (key in objA) { 18323 if (objA.hasOwnProperty(key) && 18324 (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) { 18325 return false; 18326 } 18327 } 18328 // Test for B'a keys missing from A. 18329 for (key in objB) { 18330 if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) { 18331 return false; 18332 } 18333 } 18334 return true; 18335 } 18336 18337 module.exports = shallowEqual; 18338 18339 },{}],144:[function(_dereq_,module,exports){ 18340 /** 18341 * Copyright 2013-2014 Facebook, Inc. 18342 * 18343 * Licensed under the Apache License, Version 2.0 (the "License"); 18344 * you may not use this file except in compliance with the License. 18345 * You may obtain a copy of the License at 18346 * 18347 * http://www.apache.org/licenses/LICENSE-2.0 18348 * 18349 * Unless required by applicable law or agreed to in writing, software 18350 * distributed under the License is distributed on an "AS IS" BASIS, 18351 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18352 * See the License for the specific language governing permissions and 18353 * limitations under the License. 18354 * 18355 * @providesModule shouldUpdateReactComponent 18356 * @typechecks static-only 18357 */ 18358 18359 "use strict"; 18360 18361 /** 18362 * Given a `prevComponentInstance` and `nextComponent`, determines if 18363 * `prevComponentInstance` should be updated as opposed to being destroyed or 18364 * replaced by a new instance. The second argument is a descriptor. Future 18365 * versions of the reconciler should only compare descriptors to other 18366 * descriptors. 18367 * 18368 * @param {?object} prevComponentInstance 18369 * @param {?object} nextDescriptor 18370 * @return {boolean} True if `prevComponentInstance` should be updated. 18371 * @protected 18372 */ 18373 function shouldUpdateReactComponent(prevComponentInstance, nextDescriptor) { 18374 // TODO: Remove warning after a release. 18375 if (prevComponentInstance && nextDescriptor && 18376 prevComponentInstance.constructor === nextDescriptor.constructor && ( 18377 (prevComponentInstance.props && prevComponentInstance.props.key) === 18378 (nextDescriptor.props && nextDescriptor.props.key) 18379 )) { 18380 if (prevComponentInstance._owner === nextDescriptor._owner) { 18381 return true; 18382 } else { 18383 if ("production" !== "development") { 18384 if (prevComponentInstance.state) { 18385 console.warn( 18386 'A recent change to React has been found to impact your code. ' + 18387 'A mounted component will now be unmounted and replaced by a ' + 18388 'component (of the same class) if their owners are different. ' + 18389 'Previously, ownership was not considered when updating.', 18390 prevComponentInstance, 18391 nextDescriptor 18392 ); 18393 } 18394 } 18395 } 18396 } 18397 return false; 18398 } 18399 18400 module.exports = shouldUpdateReactComponent; 18401 18402 },{}],145:[function(_dereq_,module,exports){ 18403 /** 18404 * Copyright 2014 Facebook, Inc. 18405 * 18406 * Licensed under the Apache License, Version 2.0 (the "License"); 18407 * you may not use this file except in compliance with the License. 18408 * You may obtain a copy of the License at 18409 * 18410 * http://www.apache.org/licenses/LICENSE-2.0 18411 * 18412 * Unless required by applicable law or agreed to in writing, software 18413 * distributed under the License is distributed on an "AS IS" BASIS, 18414 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18415 * See the License for the specific language governing permissions and 18416 * limitations under the License. 18417 * 18418 * @providesModule toArray 18419 * @typechecks 18420 */ 18421 18422 var invariant = _dereq_("./invariant"); 18423 18424 /** 18425 * Convert array-like objects to arrays. 18426 * 18427 * This API assumes the caller knows the contents of the data type. For less 18428 * well defined inputs use createArrayFrom. 18429 * 18430 * @param {object|function} obj 18431 * @return {array} 18432 */ 18433 function toArray(obj) { 18434 var length = obj.length; 18435 18436 // Some browse builtin objects can report typeof 'function' (e.g. NodeList in 18437 // old versions of Safari). 18438 ("production" !== "development" ? invariant( 18439 !Array.isArray(obj) && 18440 (typeof obj === 'object' || typeof obj === 'function'), 18441 'toArray: Array-like object expected' 18442 ) : invariant(!Array.isArray(obj) && 18443 (typeof obj === 'object' || typeof obj === 'function'))); 18444 18445 ("production" !== "development" ? invariant( 18446 typeof length === 'number', 18447 'toArray: Object needs a length property' 18448 ) : invariant(typeof length === 'number')); 18449 18450 ("production" !== "development" ? invariant( 18451 length === 0 || 18452 (length - 1) in obj, 18453 'toArray: Object should have keys for indices' 18454 ) : invariant(length === 0 || 18455 (length - 1) in obj)); 18456 18457 // Old IE doesn't give collections access to hasOwnProperty. Assume inputs 18458 // without method will throw during the slice call and skip straight to the 18459 // fallback. 18460 if (obj.hasOwnProperty) { 18461 try { 18462 return Array.prototype.slice.call(obj); 18463 } catch (e) { 18464 // IE < 9 does not support Array#slice on collections objects 18465 } 18466 } 18467 18468 // Fall back to copying key by key. This assumes all keys have a value, 18469 // so will not preserve sparsely populated inputs. 18470 var ret = Array(length); 18471 for (var ii = 0; ii < length; ii++) { 18472 ret[ii] = obj[ii]; 18473 } 18474 return ret; 18475 } 18476 18477 module.exports = toArray; 18478 18479 },{"./invariant":125}],146:[function(_dereq_,module,exports){ 18480 /** 18481 * Copyright 2013-2014 Facebook, Inc. 18482 * 18483 * Licensed under the Apache License, Version 2.0 (the "License"); 18484 * you may not use this file except in compliance with the License. 18485 * You may obtain a copy of the License at 18486 * 18487 * http://www.apache.org/licenses/LICENSE-2.0 18488 * 18489 * Unless required by applicable law or agreed to in writing, software 18490 * distributed under the License is distributed on an "AS IS" BASIS, 18491 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18492 * See the License for the specific language governing permissions and 18493 * limitations under the License. 18494 * 18495 * @providesModule traverseAllChildren 18496 */ 18497 18498 "use strict"; 18499 18500 var ReactInstanceHandles = _dereq_("./ReactInstanceHandles"); 18501 var ReactTextComponent = _dereq_("./ReactTextComponent"); 18502 18503 var invariant = _dereq_("./invariant"); 18504 18505 var SEPARATOR = ReactInstanceHandles.SEPARATOR; 18506 var SUBSEPARATOR = ':'; 18507 18508 /** 18509 * TODO: Test that: 18510 * 1. `mapChildren` transforms strings and numbers into `ReactTextComponent`. 18511 * 2. it('should fail when supplied duplicate key', function() { 18512 * 3. That a single child and an array with one item have the same key pattern. 18513 * }); 18514 */ 18515 18516 var userProvidedKeyEscaperLookup = { 18517 '=': '=0', 18518 '.': '=1', 18519 ':': '=2' 18520 }; 18521 18522 var userProvidedKeyEscapeRegex = /[=.:]/g; 18523 18524 function userProvidedKeyEscaper(match) { 18525 return userProvidedKeyEscaperLookup[match]; 18526 } 18527 18528 /** 18529 * Generate a key string that identifies a component within a set. 18530 * 18531 * @param {*} component A component that could contain a manual key. 18532 * @param {number} index Index that is used if a manual key is not provided. 18533 * @return {string} 18534 */ 18535 function getComponentKey(component, index) { 18536 if (component && component.props && component.props.key != null) { 18537 // Explicit key 18538 return wrapUserProvidedKey(component.props.key); 18539 } 18540 // Implicit key determined by the index in the set 18541 return index.toString(36); 18542 } 18543 18544 /** 18545 * Escape a component key so that it is safe to use in a reactid. 18546 * 18547 * @param {*} key Component key to be escaped. 18548 * @return {string} An escaped string. 18549 */ 18550 function escapeUserProvidedKey(text) { 18551 return ('' + text).replace( 18552 userProvidedKeyEscapeRegex, 18553 userProvidedKeyEscaper 18554 ); 18555 } 18556 18557 /** 18558 * Wrap a `key` value explicitly provided by the user to distinguish it from 18559 * implicitly-generated keys generated by a component's index in its parent. 18560 * 18561 * @param {string} key Value of a user-provided `key` attribute 18562 * @return {string} 18563 */ 18564 function wrapUserProvidedKey(key) { 18565 return '$' + escapeUserProvidedKey(key); 18566 } 18567 18568 /** 18569 * @param {?*} children Children tree container. 18570 * @param {!string} nameSoFar Name of the key path so far. 18571 * @param {!number} indexSoFar Number of children encountered until this point. 18572 * @param {!function} callback Callback to invoke with each child found. 18573 * @param {?*} traverseContext Used to pass information throughout the traversal 18574 * process. 18575 * @return {!number} The number of children in this subtree. 18576 */ 18577 var traverseAllChildrenImpl = 18578 function(children, nameSoFar, indexSoFar, callback, traverseContext) { 18579 var subtreeCount = 0; // Count of children found in the current subtree. 18580 if (Array.isArray(children)) { 18581 for (var i = 0; i < children.length; i++) { 18582 var child = children[i]; 18583 var nextName = ( 18584 nameSoFar + 18585 (nameSoFar ? SUBSEPARATOR : SEPARATOR) + 18586 getComponentKey(child, i) 18587 ); 18588 var nextIndex = indexSoFar + subtreeCount; 18589 subtreeCount += traverseAllChildrenImpl( 18590 child, 18591 nextName, 18592 nextIndex, 18593 callback, 18594 traverseContext 18595 ); 18596 } 18597 } else { 18598 var type = typeof children; 18599 var isOnlyChild = nameSoFar === ''; 18600 // If it's the only child, treat the name as if it was wrapped in an array 18601 // so that it's consistent if the number of children grows 18602 var storageName = 18603 isOnlyChild ? SEPARATOR + getComponentKey(children, 0) : nameSoFar; 18604 if (children == null || type === 'boolean') { 18605 // All of the above are perceived as null. 18606 callback(traverseContext, null, storageName, indexSoFar); 18607 subtreeCount = 1; 18608 } else if (children.type && children.type.prototype && 18609 children.type.prototype.mountComponentIntoNode) { 18610 callback(traverseContext, children, storageName, indexSoFar); 18611 subtreeCount = 1; 18612 } else { 18613 if (type === 'object') { 18614 ("production" !== "development" ? invariant( 18615 !children || children.nodeType !== 1, 18616 'traverseAllChildren(...): Encountered an invalid child; DOM ' + 18617 'elements are not valid children of React components.' 18618 ) : invariant(!children || children.nodeType !== 1)); 18619 for (var key in children) { 18620 if (children.hasOwnProperty(key)) { 18621 subtreeCount += traverseAllChildrenImpl( 18622 children[key], 18623 ( 18624 nameSoFar + (nameSoFar ? SUBSEPARATOR : SEPARATOR) + 18625 wrapUserProvidedKey(key) + SUBSEPARATOR + 18626 getComponentKey(children[key], 0) 18627 ), 18628 indexSoFar + subtreeCount, 18629 callback, 18630 traverseContext 18631 ); 18632 } 18633 } 18634 } else if (type === 'string') { 18635 var normalizedText = new ReactTextComponent(children); 18636 callback(traverseContext, normalizedText, storageName, indexSoFar); 18637 subtreeCount += 1; 18638 } else if (type === 'number') { 18639 var normalizedNumber = new ReactTextComponent('' + children); 18640 callback(traverseContext, normalizedNumber, storageName, indexSoFar); 18641 subtreeCount += 1; 18642 } 18643 } 18644 } 18645 return subtreeCount; 18646 }; 18647 18648 /** 18649 * Traverses children that are typically specified as `props.children`, but 18650 * might also be specified through attributes: 18651 * 18652 * - `traverseAllChildren(this.props.children, ...)` 18653 * - `traverseAllChildren(this.props.leftPanelChildren, ...)` 18654 * 18655 * The `traverseContext` is an optional argument that is passed through the 18656 * entire traversal. It can be used to store accumulations or anything else that 18657 * the callback might find relevant. 18658 * 18659 * @param {?*} children Children tree object. 18660 * @param {!function} callback To invoke upon traversing each child. 18661 * @param {?*} traverseContext Context for traversal. 18662 */ 18663 function traverseAllChildren(children, callback, traverseContext) { 18664 if (children !== null && children !== undefined) { 18665 traverseAllChildrenImpl(children, '', 0, callback, traverseContext); 18666 } 18667 } 18668 18669 module.exports = traverseAllChildren; 18670 18671 },{"./ReactInstanceHandles":57,"./ReactTextComponent":77,"./invariant":125}],147:[function(_dereq_,module,exports){ 18672 /** 18673 * Copyright 2013-2014 Facebook, Inc. 18674 * 18675 * Licensed under the Apache License, Version 2.0 (the "License"); 18676 * you may not use this file except in compliance with the License. 18677 * You may obtain a copy of the License at 18678 * 18679 * http://www.apache.org/licenses/LICENSE-2.0 18680 * 18681 * Unless required by applicable law or agreed to in writing, software 18682 * distributed under the License is distributed on an "AS IS" BASIS, 18683 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18684 * See the License for the specific language governing permissions and 18685 * limitations under the License. 18686 * 18687 * @providesModule update 18688 */ 18689 18690 "use strict"; 18691 18692 var copyProperties = _dereq_("./copyProperties"); 18693 var keyOf = _dereq_("./keyOf"); 18694 var invariant = _dereq_("./invariant"); 18695 18696 function shallowCopy(x) { 18697 if (Array.isArray(x)) { 18698 return x.concat(); 18699 } else if (x && typeof x === 'object') { 18700 return copyProperties(new x.constructor(), x); 18701 } else { 18702 return x; 18703 } 18704 } 18705 18706 var DIRECTIVE_PUSH = keyOf({$push: null}); 18707 var DIRECTIVE_UNSHIFT = keyOf({$unshift: null}); 18708 var DIRECTIVE_SPLICE = keyOf({$splice: null}); 18709 var DIRECTIVE_SET = keyOf({$set: null}); 18710 var DIRECTIVE_MERGE = keyOf({$merge: null}); 18711 18712 var ALL_DIRECTIVES_LIST = [ 18713 DIRECTIVE_PUSH, 18714 DIRECTIVE_UNSHIFT, 18715 DIRECTIVE_SPLICE, 18716 DIRECTIVE_SET, 18717 DIRECTIVE_MERGE 18718 ]; 18719 18720 var ALL_DIRECTIVES_SET = {}; 18721 18722 ALL_DIRECTIVES_LIST.forEach(function(directive) { 18723 ALL_DIRECTIVES_SET[directive] = true; 18724 }); 18725 18726 function invariantArrayCase(value, spec, directive) { 18727 ("production" !== "development" ? invariant( 18728 Array.isArray(value), 18729 'update(): expected target of %s to be an array; got %s.', 18730 directive, 18731 value 18732 ) : invariant(Array.isArray(value))); 18733 var specValue = spec[directive]; 18734 ("production" !== "development" ? invariant( 18735 Array.isArray(specValue), 18736 'update(): expected spec of %s to be an array; got %s. ' + 18737 'Did you forget to wrap your parameter in an array?', 18738 directive, 18739 specValue 18740 ) : invariant(Array.isArray(specValue))); 18741 } 18742 18743 function update(value, spec) { 18744 ("production" !== "development" ? invariant( 18745 typeof spec === 'object', 18746 'update(): You provided a key path to update() that did not contain one ' + 18747 'of %s. Did you forget to include {%s: ...}?', 18748 ALL_DIRECTIVES_LIST.join(', '), 18749 DIRECTIVE_SET 18750 ) : invariant(typeof spec === 'object')); 18751 18752 if (spec.hasOwnProperty(DIRECTIVE_SET)) { 18753 ("production" !== "development" ? invariant( 18754 Object.keys(spec).length === 1, 18755 'Cannot have more than one key in an object with %s', 18756 DIRECTIVE_SET 18757 ) : invariant(Object.keys(spec).length === 1)); 18758 18759 return spec[DIRECTIVE_SET]; 18760 } 18761 18762 var nextValue = shallowCopy(value); 18763 18764 if (spec.hasOwnProperty(DIRECTIVE_MERGE)) { 18765 var mergeObj = spec[DIRECTIVE_MERGE]; 18766 ("production" !== "development" ? invariant( 18767 mergeObj && typeof mergeObj === 'object', 18768 'update(): %s expects a spec of type \'object\'; got %s', 18769 DIRECTIVE_MERGE, 18770 mergeObj 18771 ) : invariant(mergeObj && typeof mergeObj === 'object')); 18772 ("production" !== "development" ? invariant( 18773 nextValue && typeof nextValue === 'object', 18774 'update(): %s expects a target of type \'object\'; got %s', 18775 DIRECTIVE_MERGE, 18776 nextValue 18777 ) : invariant(nextValue && typeof nextValue === 'object')); 18778 copyProperties(nextValue, spec[DIRECTIVE_MERGE]); 18779 } 18780 18781 if (spec.hasOwnProperty(DIRECTIVE_PUSH)) { 18782 invariantArrayCase(value, spec, DIRECTIVE_PUSH); 18783 spec[DIRECTIVE_PUSH].forEach(function(item) { 18784 nextValue.push(item); 18785 }); 18786 } 18787 18788 if (spec.hasOwnProperty(DIRECTIVE_UNSHIFT)) { 18789 invariantArrayCase(value, spec, DIRECTIVE_UNSHIFT); 18790 spec[DIRECTIVE_UNSHIFT].forEach(function(item) { 18791 nextValue.unshift(item); 18792 }); 18793 } 18794 18795 if (spec.hasOwnProperty(DIRECTIVE_SPLICE)) { 18796 ("production" !== "development" ? invariant( 18797 Array.isArray(value), 18798 'Expected %s target to be an array; got %s', 18799 DIRECTIVE_SPLICE, 18800 value 18801 ) : invariant(Array.isArray(value))); 18802 ("production" !== "development" ? invariant( 18803 Array.isArray(spec[DIRECTIVE_SPLICE]), 18804 'update(): expected spec of %s to be an array of arrays; got %s. ' + 18805 'Did you forget to wrap your parameters in an array?', 18806 DIRECTIVE_SPLICE, 18807 spec[DIRECTIVE_SPLICE] 18808 ) : invariant(Array.isArray(spec[DIRECTIVE_SPLICE]))); 18809 spec[DIRECTIVE_SPLICE].forEach(function(args) { 18810 ("production" !== "development" ? invariant( 18811 Array.isArray(args), 18812 'update(): expected spec of %s to be an array of arrays; got %s. ' + 18813 'Did you forget to wrap your parameters in an array?', 18814 DIRECTIVE_SPLICE, 18815 spec[DIRECTIVE_SPLICE] 18816 ) : invariant(Array.isArray(args))); 18817 nextValue.splice.apply(nextValue, args); 18818 }); 18819 } 18820 18821 for (var k in spec) { 18822 if (!ALL_DIRECTIVES_SET[k]) { 18823 nextValue[k] = update(value[k], spec[k]); 18824 } 18825 } 18826 18827 return nextValue; 18828 } 18829 18830 module.exports = update; 18831 18832 },{"./copyProperties":102,"./invariant":125,"./keyOf":132}],148:[function(_dereq_,module,exports){ 18833 /** 18834 * Copyright 2014 Facebook, Inc. 18835 * 18836 * Licensed under the Apache License, Version 2.0 (the "License"); 18837 * you may not use this file except in compliance with the License. 18838 * You may obtain a copy of the License at 18839 * 18840 * http://www.apache.org/licenses/LICENSE-2.0 18841 * 18842 * Unless required by applicable law or agreed to in writing, software 18843 * distributed under the License is distributed on an "AS IS" BASIS, 18844 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18845 * See the License for the specific language governing permissions and 18846 * limitations under the License. 18847 * 18848 * @providesModule warning 18849 */ 18850 18851 "use strict"; 18852 18853 var emptyFunction = _dereq_("./emptyFunction"); 18854 18855 /** 18856 * Similar to invariant but only logs a warning if the condition is not met. 18857 * This can be used to log issues in development environments in critical 18858 * paths. Removing the logging code for production environments will keep the 18859 * same logic and follow the same code paths. 18860 */ 18861 18862 var warning = emptyFunction; 18863 18864 if ("production" !== "development") { 18865 warning = function(condition, format ) {var args=Array.prototype.slice.call(arguments,2); 18866 if (format === undefined) { 18867 throw new Error( 18868 '`warning(condition, format, ...args)` requires a warning ' + 18869 'message argument' 18870 ); 18871 } 18872 18873 if (!condition) { 18874 var argIndex = 0; 18875 console.warn('Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];})); 18876 } 18877 }; 18878 } 18879 18880 module.exports = warning; 18881 18882 },{"./emptyFunction":109}]},{},[82]) 18883 (82) 18884 });