diff --git a/firebase-init.js b/firebase-init.js index 2d2340dd..bd48fe27 100644 --- a/firebase-init.js +++ b/firebase-init.js @@ -1,7 +1,4 @@ // Get these values for your project from the https://console.firebase.google.com/ -// You can get most of this file at -// Project Settings -> General -> Your Apps -> [Add app] -> [Add Firebase to your Web app] -// The `messagingVapidKey` needs to be added separately. const FIREBASE_INIT = { // Project Settings -> Cloud Messaging, "Sender ID". messagingSenderId: "114126160546", diff --git a/package.json b/package.json index 3715b0dd..1b855fde 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "tinode-webapp", "description": "Tinode messenger for the web", - "version": "0.15.6", + "version": "0.15.7-rc1", "devDependencies": { "babel-cli": "^6.26.0", "babel-preset-env": "^1.7.0", @@ -66,8 +66,8 @@ "license": "Apache-2.0", "dependencies": { "firebase": "^5.5.0", - "react": "^16.5.1", - "react-dom": "^16.4.2", + "react": "^16.5.2", + "react-dom": "^16.5.2", "tinode-sdk": "^0.15.6" } } diff --git a/src/webapp.jsx b/src/webapp.jsx index 77310968..1a272022 100644 --- a/src/webapp.jsx +++ b/src/webapp.jsx @@ -4980,7 +4980,6 @@ class TinodeWeb extends React.Component { if (enabled) { if (!this.state.firebaseToken) { this.fbPush.requestPermission().then(() => { - console.log("got permission, requesting token"); this.requestPushToken(true); }).catch((err) => { this.handleError(err.message, "err"); @@ -5007,9 +5006,7 @@ class TinodeWeb extends React.Component { } requestPushToken(sendToServer) { - console.log("requestPushToken", sendToServer); this.fbPush.getToken().then((refreshedToken) => { - console.log("got token", refreshedToken, this.state.firebaseToken); if (refreshedToken != this.state.firebaseToken) { this.tinode.setDeviceToken(refreshedToken, sendToServer); localStorage.setObject("firebase-token", refreshedToken); diff --git a/umd/index.dev.js b/umd/index.dev.js index 79548c0b..626910bf 100644 --- a/umd/index.dev.js +++ b/umd/index.dev.js @@ -2525,7 +2525,7 @@ function isSWControllerSupported() { exports.registerMessaging = registerMessaging; exports.isSupported = isSupported; -},{"@firebase/app":1,"@firebase/util":4,"tslib":31}],3:[function(require,module,exports){ +},{"@firebase/app":1,"@firebase/util":4,"tslib":23}],3:[function(require,module,exports){ (function (global,setImmediate){ 'use strict'; @@ -4060,7 +4060,7 @@ var iterator = _wksExt.f('iterator'); */ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("timers").setImmediate) -},{"timers":37,"whatwg-fetch":32}],4:[function(require,module,exports){ +},{"timers":29,"whatwg-fetch":24}],4:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); @@ -5838,542 +5838,7 @@ exports.validateNamespace = validateNamespace; exports.stringLength = stringLength; exports.stringToByteArray = stringToByteArray$1; -},{"tslib":31}],5:[function(require,module,exports){ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -'use strict'; - -var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); - -/** - * Simple, lightweight module assisting with the detection and context of - * Worker. Helps avoid circular dependencies and allows code to reason about - * whether or not they are in a Worker, even if they never include the main - * `ReactWorker` dependency. - */ -var ExecutionEnvironment = { - - canUseDOM: canUseDOM, - - canUseWorkers: typeof Worker !== 'undefined', - - canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent), - - canUseViewport: canUseDOM && !!window.screen, - - isInWorker: !canUseDOM // For now, this is true - might change in the future. - -}; - -module.exports = ExecutionEnvironment; -},{}],6:[function(require,module,exports){ -"use strict"; - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @typechecks - */ - -var _hyphenPattern = /-(.)/g; - -/** - * Camelcases a hyphenated string, for example: - * - * > camelize('background-color') - * < "backgroundColor" - * - * @param {string} string - * @return {string} - */ -function camelize(string) { - return string.replace(_hyphenPattern, function (_, character) { - return character.toUpperCase(); - }); -} - -module.exports = camelize; -},{}],7:[function(require,module,exports){ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @typechecks - */ - -'use strict'; - -var camelize = require('./camelize'); - -var msPattern = /^-ms-/; - -/** - * Camelcases a hyphenated CSS property name, for example: - * - * > camelizeStyleName('background-color') - * < "backgroundColor" - * > camelizeStyleName('-moz-transition') - * < "MozTransition" - * > camelizeStyleName('-ms-transition') - * < "msTransition" - * - * As Andi Smith suggests - * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix - * is converted to lowercase `ms`. - * - * @param {string} string - * @return {string} - */ -function camelizeStyleName(string) { - return camelize(string.replace(msPattern, 'ms-')); -} - -module.exports = camelizeStyleName; -},{"./camelize":6}],8:[function(require,module,exports){ -'use strict'; - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * - */ - -var isTextNode = require('./isTextNode'); - -/*eslint-disable no-bitwise */ - -/** - * Checks if a given DOM node contains or is another DOM node. - */ -function containsNode(outerNode, innerNode) { - if (!outerNode || !innerNode) { - return false; - } else if (outerNode === innerNode) { - return true; - } else if (isTextNode(outerNode)) { - return false; - } else if (isTextNode(innerNode)) { - return containsNode(outerNode, innerNode.parentNode); - } else if ('contains' in outerNode) { - return outerNode.contains(innerNode); - } else if (outerNode.compareDocumentPosition) { - return !!(outerNode.compareDocumentPosition(innerNode) & 16); - } else { - return false; - } -} - -module.exports = containsNode; -},{"./isTextNode":16}],9:[function(require,module,exports){ -"use strict"; - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * - */ - -function makeEmptyFunction(arg) { - return function () { - return arg; - }; -} - -/** - * This function accepts and discards inputs; it has no side effects. This is - * primarily useful idiomatically for overridable function endpoints which - * always need to be callable, since JS lacks a null-call idiom ala Cocoa. - */ -var emptyFunction = function emptyFunction() {}; - -emptyFunction.thatReturns = makeEmptyFunction; -emptyFunction.thatReturnsFalse = makeEmptyFunction(false); -emptyFunction.thatReturnsTrue = makeEmptyFunction(true); -emptyFunction.thatReturnsNull = makeEmptyFunction(null); -emptyFunction.thatReturnsThis = function () { - return this; -}; -emptyFunction.thatReturnsArgument = function (arg) { - return arg; -}; - -module.exports = emptyFunction; -},{}],10:[function(require,module,exports){ -(function (process){ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -'use strict'; - -var emptyObject = {}; - -if (process.env.NODE_ENV !== 'production') { - Object.freeze(emptyObject); -} - -module.exports = emptyObject; -}).call(this,require('_process')) -},{"_process":36}],11:[function(require,module,exports){ -'use strict'; - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @typechecks - */ - -/* eslint-disable fb-www/typeof-undefined */ - -/** - * Same as document.activeElement but wraps in a try-catch block. In IE it is - * not safe to call document.activeElement if there is nothing focused. - * - * The activeElement will be null only if the document or document body is not - * yet defined. - * - * @param {?DOMDocument} doc Defaults to current document. - * @return {?DOMElement} - */ -function getActiveElement(doc) /*?DOMElement*/{ - doc = doc || (typeof document !== 'undefined' ? document : undefined); - if (typeof doc === 'undefined') { - return null; - } - try { - return doc.activeElement || doc.body; - } catch (e) { - return doc.body; - } -} - -module.exports = getActiveElement; -},{}],12:[function(require,module,exports){ -'use strict'; - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @typechecks - */ - -var _uppercasePattern = /([A-Z])/g; - -/** - * Hyphenates a camelcased string, for example: - * - * > hyphenate('backgroundColor') - * < "background-color" - * - * For CSS style names, use `hyphenateStyleName` instead which works properly - * with all vendor prefixes, including `ms`. - * - * @param {string} string - * @return {string} - */ -function hyphenate(string) { - return string.replace(_uppercasePattern, '-$1').toLowerCase(); -} - -module.exports = hyphenate; -},{}],13:[function(require,module,exports){ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @typechecks - */ - -'use strict'; - -var hyphenate = require('./hyphenate'); - -var msPattern = /^ms-/; - -/** - * Hyphenates a camelcased CSS property name, for example: - * - * > hyphenateStyleName('backgroundColor') - * < "background-color" - * > hyphenateStyleName('MozTransition') - * < "-moz-transition" - * > hyphenateStyleName('msTransition') - * < "-ms-transition" - * - * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix - * is converted to `-ms-`. - * - * @param {string} string - * @return {string} - */ -function hyphenateStyleName(string) { - return hyphenate(string).replace(msPattern, '-ms-'); -} - -module.exports = hyphenateStyleName; -},{"./hyphenate":12}],14:[function(require,module,exports){ -(function (process){ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -'use strict'; - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var validateFormat = function validateFormat(format) {}; - -if (process.env.NODE_ENV !== 'production') { - validateFormat = function validateFormat(format) { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - }; -} - -function invariant(condition, format, a, b, c, d, e, f) { - validateFormat(format); - - if (!condition) { - var error; - if (format === undefined) { - error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error(format.replace(/%s/g, function () { - return args[argIndex++]; - })); - error.name = 'Invariant Violation'; - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -} - -module.exports = invariant; -}).call(this,require('_process')) -},{"_process":36}],15:[function(require,module,exports){ -'use strict'; - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @typechecks - */ - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM node. - */ -function isNode(object) { - var doc = object ? object.ownerDocument || object : document; - var defaultView = doc.defaultView || window; - return !!(object && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string')); -} - -module.exports = isNode; -},{}],16:[function(require,module,exports){ -'use strict'; - -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @typechecks - */ - -var isNode = require('./isNode'); - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM text node. - */ -function isTextNode(object) { - return isNode(object) && object.nodeType == 3; -} - -module.exports = isTextNode; -},{"./isNode":15}],17:[function(require,module,exports){ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @typechecks - * - */ - -/*eslint-disable no-self-compare */ - -'use strict'; - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * inlined Object.is polyfill to avoid requiring consumers ship their own - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is - */ -function is(x, y) { - // SameValue algorithm - if (x === y) { - // Steps 1-5, 7-10 - // Steps 6.b-6.e: +0 != -0 - // Added the nonzero y check to make Flow happy, but it is redundant - return x !== 0 || y !== 0 || 1 / x === 1 / y; - } else { - // Step 6.a: NaN == NaN - return x !== x && y !== y; - } -} - -/** - * Performs equality by iterating through keys on an object and returning false - * when any key has values which are not strictly equal between the arguments. - * Returns true when the values of all keys are strictly equal. - */ -function shallowEqual(objA, objB) { - if (is(objA, objB)) { - return true; - } - - if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { - return false; - } - - var keysA = Object.keys(objA); - var keysB = Object.keys(objB); - - if (keysA.length !== keysB.length) { - return false; - } - - // Test for A's keys different from B. - for (var i = 0; i < keysA.length; i++) { - if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { - return false; - } - } - - return true; -} - -module.exports = shallowEqual; -},{}],18:[function(require,module,exports){ -(function (process){ -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -'use strict'; - -var emptyFunction = require('./emptyFunction'); - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = emptyFunction; - -if (process.env.NODE_ENV !== 'production') { - var printWarning = function printWarning(format) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - var argIndex = 0; - var message = 'Warning: ' + format.replace(/%s/g, function () { - return args[argIndex++]; - }); - if (typeof console !== 'undefined') { - console.error(message); - } - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - warning = function warning(condition, format) { - if (format === undefined) { - throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); - } - - if (format.indexOf('Failed Composite propType: ') === 0) { - return; // Ignore CompositeComponent proptype check. - } - - if (!condition) { - for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { - args[_key2 - 2] = arguments[_key2]; - } - - printWarning.apply(undefined, [format].concat(args)); - } - }; -} - -module.exports = warning; -}).call(this,require('_process')) -},{"./emptyFunction":9,"_process":36}],19:[function(require,module,exports){ +},{"tslib":23}],5:[function(require,module,exports){ 'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } @@ -6399,7 +5864,7 @@ var firebase = _interopDefault(require('@firebase/app')); module.exports = firebase; -},{"@firebase/app":1,"@firebase/polyfill":3}],20:[function(require,module,exports){ +},{"@firebase/app":1,"@firebase/polyfill":3}],6:[function(require,module,exports){ 'use strict'; require('@firebase/messaging'); @@ -6420,7 +5885,7 @@ require('@firebase/messaging'); * limitations under the License. */ -},{"@firebase/messaging":2}],21:[function(require,module,exports){ +},{"@firebase/messaging":2}],7:[function(require,module,exports){ /* object-assign (c) Sindre Sorhus @@ -6512,7 +5977,7 @@ module.exports = shouldUseNative() ? Object.assign : function (target, source) { return to; }; -},{}],22:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ (function (process){ /** * Copyright (c) 2013-present, Facebook, Inc. @@ -6607,7 +6072,7 @@ function checkPropTypes(typeSpecs, values, location, componentName, getStack) { module.exports = checkPropTypes; }).call(this,require('_process')) -},{"./lib/ReactPropTypesSecret":23,"_process":36}],23:[function(require,module,exports){ +},{"./lib/ReactPropTypesSecret":9,"_process":28}],9:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * @@ -6621,12 +6086,12 @@ var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; module.exports = ReactPropTypesSecret; -},{}],24:[function(require,module,exports){ +},{}],10:[function(require,module,exports){ (function (process){ -/** @license React v16.4.2 +/** @license React v16.5.2 * react-dom.development.js * - * Copyright (c) 2013-present, Facebook, Inc. + * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -6640,34 +6105,65 @@ if (process.env.NODE_ENV !== "production") { (function() { 'use strict'; -var invariant = require('fbjs/lib/invariant'); var React = require('react'); -var warning = require('fbjs/lib/warning'); -var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); var _assign = require('object-assign'); -var emptyFunction = require('fbjs/lib/emptyFunction'); var checkPropTypes = require('prop-types/checkPropTypes'); -var getActiveElement = require('fbjs/lib/getActiveElement'); -var shallowEqual = require('fbjs/lib/shallowEqual'); -var containsNode = require('fbjs/lib/containsNode'); -var emptyObject = require('fbjs/lib/emptyObject'); -var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName'); -var camelizeStyleName = require('fbjs/lib/camelizeStyleName'); +var schedule = require('schedule'); +var tracing = require('schedule/tracing'); + +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + +var validateFormat = function () {}; + +{ + validateFormat = function (format) { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + }; +} + +function invariant(condition, format, a, b, c, d, e, f) { + validateFormat(format); + + if (!condition) { + var error = void 0; + if (format === undefined) { + error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error(format.replace(/%s/g, function () { + return args[argIndex++]; + })); + error.name = 'Invariant Violation'; + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } +} // Relying on the `invariant()` implementation lets us -// have preserve the format and params in the www builds. +// preserve the format and params in the www builds. !React ? invariant(false, 'ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.') : void 0; -var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) { - this._hasCaughtError = false; - this._caughtError = null; +var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { func.apply(context, funcArgs); } catch (error) { - this._caughtError = error; - this._hasCaughtError = true; + this.onError(error); } }; @@ -6712,6 +6208,11 @@ var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) { // the error event at all. var didError = true; + // Keeps track of the value of window.event so that we can reset it + // during the callback to let user code access window.event in the + // browsers that support it. + var windowEvent = window.event; + // Create an event handler for our fake event. We will synchronously // dispatch our fake event using `dispatchEvent`. Inside the handler, we // call the user-provided callback. @@ -6722,6 +6223,15 @@ var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) { // nested call would trigger the fake event handlers of any call higher // in the stack. fakeNode.removeEventListener(evtType, callCallback, false); + + // We check for window.hasOwnProperty('event') to prevent the + // window.event assignment in both IE <= 10 as they throw an error + // "Member not found" in strict mode, and in Firefox which does not + // support window.event. + if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) { + window.event = windowEvent; + } + func.apply(context, funcArgs); didError = false; } @@ -6742,19 +6252,31 @@ var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) { var didSetError = false; var isCrossOriginError = false; - function onError(event) { + function handleWindowError(event) { error = event.error; didSetError = true; if (error === null && event.colno === 0 && event.lineno === 0) { isCrossOriginError = true; } + if (event.defaultPrevented) { + // Some other error handler has prevented default. + // Browsers silence the error report if this happens. + // We'll remember this to later decide whether to log it or not. + if (error != null && typeof error === 'object') { + try { + error._suppressLogging = true; + } catch (inner) { + // Ignore. + } + } + } } // Create a fake event type. var evtType = 'react-' + (name ? name : 'invokeguardedcallback'); // Attach our event handlers - window.addEventListener('error', onError); + window.addEventListener('error', handleWindowError); fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function @@ -6769,102 +6291,101 @@ var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) { } else if (isCrossOriginError) { error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.'); } - this._hasCaughtError = true; - this._caughtError = error; - } else { - this._hasCaughtError = false; - this._caughtError = null; + this.onError(error); } // Remove our event listeners - window.removeEventListener('error', onError); + window.removeEventListener('error', handleWindowError); }; - invokeGuardedCallback = invokeGuardedCallbackDev; + invokeGuardedCallbackImpl = invokeGuardedCallbackDev; } } -var invokeGuardedCallback$1 = invokeGuardedCallback; +var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl; -var ReactErrorUtils = { - // Used by Fiber to simulate a try-catch. - _caughtError: null, - _hasCaughtError: false, +// Used by Fiber to simulate a try-catch. +var hasError = false; +var caughtError = null; - // Used by event system to capture/rethrow the first error. - _rethrowError: null, - _hasRethrowError: false, +// Used by event system to capture/rethrow the first error. +var hasRethrowError = false; +var rethrowError = null; - /** - * Call a function while guarding against errors that happens within it. - * Returns an error if it throws, otherwise null. - * - * In production, this is implemented using a try-catch. The reason we don't - * use a try-catch directly is so that we can swap out a different - * implementation in DEV mode. - * - * @param {String} name of the guard to use for logging or debugging - * @param {Function} func The function to invoke - * @param {*} context The context to use when calling the function - * @param {...*} args Arguments for function - */ - invokeGuardedCallback: function (name, func, context, a, b, c, d, e, f) { - invokeGuardedCallback$1.apply(ReactErrorUtils, arguments); - }, - - /** - * Same as invokeGuardedCallback, but instead of returning an error, it stores - * it in a global so it can be rethrown by `rethrowCaughtError` later. - * TODO: See if _caughtError and _rethrowError can be unified. - * - * @param {String} name of the guard to use for logging or debugging - * @param {Function} func The function to invoke - * @param {*} context The context to use when calling the function - * @param {...*} args Arguments for function - */ - invokeGuardedCallbackAndCatchFirstError: function (name, func, context, a, b, c, d, e, f) { - ReactErrorUtils.invokeGuardedCallback.apply(this, arguments); - if (ReactErrorUtils.hasCaughtError()) { - var error = ReactErrorUtils.clearCaughtError(); - if (!ReactErrorUtils._hasRethrowError) { - ReactErrorUtils._hasRethrowError = true; - ReactErrorUtils._rethrowError = error; - } - } - }, - - /** - * During execution of guarded functions we will capture the first error which - * we will rethrow to be handled by the top level error handler. - */ - rethrowCaughtError: function () { - return rethrowCaughtError.apply(ReactErrorUtils, arguments); - }, - - hasCaughtError: function () { - return ReactErrorUtils._hasCaughtError; - }, - - clearCaughtError: function () { - if (ReactErrorUtils._hasCaughtError) { - var error = ReactErrorUtils._caughtError; - ReactErrorUtils._caughtError = null; - ReactErrorUtils._hasCaughtError = false; - return error; - } else { - invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'); - } +var reporter = { + onError: function (error) { + hasError = true; + caughtError = error; } }; -var rethrowCaughtError = function () { - if (ReactErrorUtils._hasRethrowError) { - var error = ReactErrorUtils._rethrowError; - ReactErrorUtils._rethrowError = null; - ReactErrorUtils._hasRethrowError = false; +/** + * Call a function while guarding against errors that happens within it. + * Returns an error if it throws, otherwise null. + * + * In production, this is implemented using a try-catch. The reason we don't + * use a try-catch directly is so that we can swap out a different + * implementation in DEV mode. + * + * @param {String} name of the guard to use for logging or debugging + * @param {Function} func The function to invoke + * @param {*} context The context to use when calling the function + * @param {...*} args Arguments for function + */ +function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { + hasError = false; + caughtError = null; + invokeGuardedCallbackImpl$1.apply(reporter, arguments); +} + +/** + * Same as invokeGuardedCallback, but instead of returning an error, it stores + * it in a global so it can be rethrown by `rethrowCaughtError` later. + * TODO: See if caughtError and rethrowError can be unified. + * + * @param {String} name of the guard to use for logging or debugging + * @param {Function} func The function to invoke + * @param {*} context The context to use when calling the function + * @param {...*} args Arguments for function + */ +function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) { + invokeGuardedCallback.apply(this, arguments); + if (hasError) { + var error = clearCaughtError(); + if (!hasRethrowError) { + hasRethrowError = true; + rethrowError = error; + } + } +} + +/** + * During execution of guarded functions we will capture the first error which + * we will rethrow to be handled by the top level error handler. + */ +function rethrowCaughtError() { + if (hasRethrowError) { + var error = rethrowError; + hasRethrowError = false; + rethrowError = null; throw error; } -}; +} + +function hasCaughtError() { + return hasError; +} + +function clearCaughtError() { + if (hasError) { + var error = caughtError; + hasError = false; + caughtError = null; + return error; + } else { + invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'); + } +} /** * Injectable ordering of event plugins. @@ -7031,31 +6552,107 @@ function injectEventPluginsByName(injectedNamesToPlugins) { } } -var EventPluginRegistry = Object.freeze({ - plugins: plugins, - eventNameDispatchConfigs: eventNameDispatchConfigs, - registrationNameModules: registrationNameModules, - registrationNameDependencies: registrationNameDependencies, - possibleRegistrationNames: possibleRegistrationNames, - injectEventPluginOrder: injectEventPluginOrder, - injectEventPluginsByName: injectEventPluginsByName -}); +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warningWithoutStack = function () {}; + +{ + warningWithoutStack = function (condition, format) { + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } + + if (format === undefined) { + throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument'); + } + if (args.length > 8) { + // Check before the condition to catch violations early. + throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); + } + if (condition) { + return; + } + if (typeof console !== 'undefined') { + var _args$map = args.map(function (item) { + return '' + item; + }), + a = _args$map[0], + b = _args$map[1], + c = _args$map[2], + d = _args$map[3], + e = _args$map[4], + f = _args$map[5], + g = _args$map[6], + h = _args$map[7]; + + var message = 'Warning: ' + format; + + // We intentionally don't use spread (or .apply) because it breaks IE9: + // https://github.com/facebook/react/issues/13610 + switch (args.length) { + case 0: + console.error(message); + break; + case 1: + console.error(message, a); + break; + case 2: + console.error(message, a, b); + break; + case 3: + console.error(message, a, b, c); + break; + case 4: + console.error(message, a, b, c, d); + break; + case 5: + console.error(message, a, b, c, d, e); + break; + case 6: + console.error(message, a, b, c, d, e, f); + break; + case 7: + console.error(message, a, b, c, d, e, f, g); + break; + case 8: + console.error(message, a, b, c, d, e, f, g, h); + break; + default: + throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); + } + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var _message = 'Warning: ' + format.replace(/%s/g, function () { + return args[argIndex++]; + }); + throw new Error(_message); + } catch (x) {} + }; +} + +var warningWithoutStack$1 = warningWithoutStack; var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; -var injection$1 = { - injectComponentTree: function (Injected) { - getFiberCurrentPropsFromNode = Injected.getFiberCurrentPropsFromNode; - getInstanceFromNode = Injected.getInstanceFromNode; - getNodeFromInstance = Injected.getNodeFromInstance; - - { - !(getNodeFromInstance && getInstanceFromNode) ? warning(false, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0; - } +function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) { + getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl; + getInstanceFromNode = getInstanceFromNodeImpl; + getNodeFromInstance = getNodeFromInstanceImpl; + { + !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0; } -}; +} var validateEventDispatches = void 0; { @@ -7069,7 +6666,7 @@ var validateEventDispatches = void 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; - !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warning(false, 'EventPluginUtils: Invalid `event`.') : void 0; + !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0; }; } @@ -7083,7 +6680,7 @@ var validateEventDispatches = void 0; function executeDispatch(event, simulated, listener, inst) { var type = event.type || 'unknown-event'; event.currentTarget = getNodeFromInstance(inst); - ReactErrorUtils.invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event); + invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event); event.currentTarget = null; } @@ -7349,7 +6946,7 @@ function runEventsInBatch(events, simulated) { } !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0; // This would be a good time to rethrow if any of the event handlers threw. - ReactErrorUtils.rethrowCaughtError(); + rethrowCaughtError(); } function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) { @@ -7357,30 +6954,23 @@ function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, native runEventsInBatch(events, false); } -var EventPluginHub = Object.freeze({ - injection: injection, - getListener: getListener, - runEventsInBatch: runEventsInBatch, - runExtractedEventsInBatch: runExtractedEventsInBatch -}); - -var IndeterminateComponent = 0; // Before we know whether it is functional or class -var FunctionalComponent = 1; +var FunctionalComponent = 0; +var FunctionalComponentLazy = 1; var ClassComponent = 2; -var HostRoot = 3; // Root of a host tree. Could be nested inside another node. -var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. -var HostComponent = 5; -var HostText = 6; - - - -var Fragment = 10; -var Mode = 11; -var ContextConsumer = 12; -var ContextProvider = 13; -var ForwardRef = 14; +var ClassComponentLazy = 3; +var IndeterminateComponent = 4; // Before we know whether it is functional or class +var HostRoot = 5; // Root of a host tree. Could be nested inside another node. +var HostPortal = 6; // A subtree. Could be an entry point to a different renderer. +var HostComponent = 7; +var HostText = 8; +var Fragment = 9; +var Mode = 10; +var ContextConsumer = 11; +var ContextProvider = 12; +var ForwardRef = 13; +var ForwardRefLazy = 14; var Profiler = 15; -var TimeoutComponent = 16; +var PlaceholderComponent = 16; var randomKey = Math.random().toString(36).slice(2); var internalInstanceKey = '__reactInternalInstance$' + randomKey; @@ -7458,15 +7048,6 @@ function updateFiberProps(node, props) { node[internalEventHandlersKey] = props; } -var ReactDOMComponentTree = Object.freeze({ - precacheFiberNode: precacheFiberNode, - getClosestInstanceFromNode: getClosestInstanceFromNode, - getInstanceFromNode: getInstanceFromNode$1, - getNodeFromInstance: getNodeFromInstance$1, - getFiberCurrentPropsFromNode: getFiberCurrentPropsFromNode$1, - updateFiberProps: updateFiberProps -}); - function getParent(inst) { do { inst = inst.return; @@ -7528,9 +7109,7 @@ function getLowestCommonAncestor(instA, instB) { /** * Return the parent instance of the passed-in instance. */ -function getParentInstance(inst) { - return getParent(inst); -} + /** * Simulates the traversal of a two-phase, capture/bubble event dispatch. @@ -7624,7 +7203,7 @@ function listenerAtPhase(inst, event, propagationPhase) { */ function accumulateDirectionalDispatches(inst, phase, event) { { - !inst ? warning(false, 'Dispatching inst must not be null') : void 0; + !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0; } var listener = listenerAtPhase(inst, event, phase); if (listener) { @@ -7646,17 +7225,6 @@ function accumulateTwoPhaseDispatchesSingle(event) { } } -/** - * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. - */ -function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - var targetInst = event._targetInst; - var parentInst = targetInst ? getParentInstance(targetInst) : null; - traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); - } -} - /** * Accumulates without regard to direction, does not look for phased * registration names. Same as `accumulateDirectDispatchesSingle` but without @@ -7688,9 +7256,7 @@ function accumulateTwoPhaseDispatches(events) { forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); } -function accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); -} + function accumulateEnterLeaveDispatches(leave, enter, from, to) { traverseEnterLeave(from, to, accumulateDispatches, leave, enter); @@ -7700,12 +7266,7 @@ function accumulateDirectDispatches(events) { forEachAccumulated(events, accumulateDirectDispatchesSingle); } -var EventPropagators = Object.freeze({ - accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, - accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget, - accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches, - accumulateDirectDispatches: accumulateDirectDispatches -}); +var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); // Do not uses the below two methods directly! // Instead use constants exported from DOMTopLevelEventTypes in ReactDOM. @@ -7732,8 +7293,6 @@ function makePrefixMap(styleProp, eventName) { prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); prefixes['Webkit' + styleProp] = 'webkit' + eventName; prefixes['Moz' + styleProp] = 'moz' + eventName; - prefixes['ms' + styleProp] = 'MS' + eventName; - prefixes['O' + styleProp] = 'o' + eventName.toLowerCase(); return prefixes; } @@ -7761,7 +7320,7 @@ var style = {}; /** * Bootstrap if a DOM exists. */ -if (ExecutionEnvironment.canUseDOM) { +if (canUseDOM) { style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x, @@ -7829,6 +7388,7 @@ var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu'); var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy'); var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut'); var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick'); +var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick'); var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag'); var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend'); var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter'); @@ -7902,25 +7462,8 @@ function getRawEventName(topLevelType) { return unsafeCastDOMTopLevelTypeToString(topLevelType); } -var contentKey = null; - /** - * Gets the key used to access text content on a DOM node. - * - * @return {?string} Key used to access text content. - * @internal - */ -function getTextContentAccessor() { - if (!contentKey && ExecutionEnvironment.canUseDOM) { - // Prefer textContent to innerText because many browsers support both but - // SVG elements don't support innerText even when
does. - contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText'; - } - return contentKey; -} - -/** - * This helper object stores information about text content of a target node, + * These variables store information about text content of a target node, * allowing comparison of content before and after a given event. * * Identify the node where selection currently begins, then observe @@ -7930,31 +7473,30 @@ function getTextContentAccessor() { * * */ -var compositionState = { - _root: null, - _startText: null, - _fallbackText: null -}; + +var root = null; +var startText = null; +var fallbackText = null; function initialize(nativeEventTarget) { - compositionState._root = nativeEventTarget; - compositionState._startText = getText(); + root = nativeEventTarget; + startText = getText(); return true; } function reset() { - compositionState._root = null; - compositionState._startText = null; - compositionState._fallbackText = null; + root = null; + startText = null; + fallbackText = null; } function getData() { - if (compositionState._fallbackText) { - return compositionState._fallbackText; + if (fallbackText) { + return fallbackText; } var start = void 0; - var startValue = compositionState._startText; + var startValue = startText; var startLength = startValue.length; var end = void 0; var endValue = getText(); @@ -7974,24 +7516,21 @@ function getData() { } var sliceTail = end > 1 ? 1 - end : undefined; - compositionState._fallbackText = endValue.slice(start, sliceTail); - return compositionState._fallbackText; + fallbackText = endValue.slice(start, sliceTail); + return fallbackText; } function getText() { - if ('value' in compositionState._root) { - return compositionState._root.value; + if ('value' in root) { + return root.value; } - return compositionState._root[getTextContentAccessor()]; + return root.textContent; } /* eslint valid-typeof: 0 */ -var didWarnForAddedNewProperty = false; var EVENT_POOL_SIZE = 10; -var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances']; - /** * @interface Event * @see http://www.w3.org/TR/DOM-Level-3-Events/ @@ -8000,7 +7539,9 @@ var EventInterface = { type: null, target: null, // currentTarget is set when dispatching; no use in copying it here - currentTarget: emptyFunction.thatReturnsNull, + currentTarget: function () { + return null; + }, eventPhase: null, bubbles: null, cancelable: null, @@ -8011,6 +7552,14 @@ var EventInterface = { isTrusted: null }; +function functionThatReturnsTrue() { + return true; +} + +function functionThatReturnsFalse() { + return false; +} + /** * Synthetic events are dispatched by event plugins, typically in response to a * top-level event delegation handler. @@ -8035,6 +7584,8 @@ function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarg delete this.nativeEvent; delete this.preventDefault; delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; } this.dispatchConfig = dispatchConfig; @@ -8063,11 +7614,11 @@ function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarg var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; if (defaultPrevented) { - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; + this.isDefaultPrevented = functionThatReturnsTrue; } else { - this.isDefaultPrevented = emptyFunction.thatReturnsFalse; + this.isDefaultPrevented = functionThatReturnsFalse; } - this.isPropagationStopped = emptyFunction.thatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; return this; } @@ -8084,7 +7635,7 @@ _assign(SyntheticEvent.prototype, { } else if (typeof event.returnValue !== 'unknown') { event.returnValue = false; } - this.isDefaultPrevented = emptyFunction.thatReturnsTrue; + this.isDefaultPrevented = functionThatReturnsTrue; }, stopPropagation: function () { @@ -8104,7 +7655,7 @@ _assign(SyntheticEvent.prototype, { event.cancelBubble = true; } - this.isPropagationStopped = emptyFunction.thatReturnsTrue; + this.isPropagationStopped = functionThatReturnsTrue; }, /** @@ -8113,7 +7664,7 @@ _assign(SyntheticEvent.prototype, { * won't be added back into the pool. */ persist: function () { - this.isPersistent = emptyFunction.thatReturnsTrue; + this.isPersistent = functionThatReturnsTrue; }, /** @@ -8121,7 +7672,7 @@ _assign(SyntheticEvent.prototype, { * * @return {boolean} True if this should not be released, false otherwise. */ - isPersistent: emptyFunction.thatReturnsFalse, + isPersistent: functionThatReturnsFalse, /** * `PooledClass` looks for `destructor` on each instance it releases. @@ -8133,13 +7684,19 @@ _assign(SyntheticEvent.prototype, { Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName])); } } - for (var i = 0; i < shouldBeReleasedProperties.length; i++) { - this[shouldBeReleasedProperties[i]] = null; - } + this.dispatchConfig = null; + this._targetInst = null; + this.nativeEvent = null; + this.isDefaultPrevented = functionThatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; + this._dispatchListeners = null; + this._dispatchInstances = null; { Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null)); - Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction)); - Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction)); + Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse)); + Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse)); + Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {})); + Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {})); } } }); @@ -8170,38 +7727,6 @@ SyntheticEvent.extend = function (Interface) { return Class; }; -/** Proxying after everything set on SyntheticEvent - * to resolve Proxy issue on some WebKit browsers - * in which some Event properties are set to undefined (GH#10010) - */ -{ - var isProxySupported = typeof Proxy === 'function' && - // https://github.com/facebook/react/issues/12011 - !Object.isSealed(new Proxy({}, {})); - - if (isProxySupported) { - /*eslint-disable no-func-assign */ - SyntheticEvent = new Proxy(SyntheticEvent, { - construct: function (target, args) { - return this.apply(target, Object.create(target.prototype), args); - }, - apply: function (constructor, that, args) { - return new Proxy(constructor.apply(that, args), { - set: function (target, prop, value) { - if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) { - !(didWarnForAddedNewProperty || target.isPersistent()) ? warning(false, "This synthetic event is reused for performance reasons. If you're " + "seeing this, you're adding a new property in the synthetic event object. " + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0; - didWarnForAddedNewProperty = true; - } - target[prop] = value; - return true; - } - }); - } - }); - /*eslint-enable no-func-assign */ - } -} - addEventPoolingTo(SyntheticEvent); /** @@ -8234,7 +7759,7 @@ function getPooledWarningPropertyDefinition(propName, getVal) { function warn(action, result) { var warningCondition = false; - !warningCondition ? warning(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0; + !warningCondition ? warningWithoutStack$1(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0; } } @@ -8250,7 +7775,7 @@ function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { function releasePooledEvent(event) { var EventConstructor = this; - !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0; + !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0; event.destructor(); if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { EventConstructor.eventPool.push(event); @@ -8263,13 +7788,11 @@ function addEventPoolingTo(EventConstructor) { EventConstructor.release = releasePooledEvent; } -var SyntheticEvent$1 = SyntheticEvent; - /** * @interface Event * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents */ -var SyntheticCompositionEvent = SyntheticEvent$1.extend({ +var SyntheticCompositionEvent = SyntheticEvent.extend({ data: null }); @@ -8278,29 +7801,29 @@ var SyntheticCompositionEvent = SyntheticEvent$1.extend({ * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 * /#events-inputevents */ -var SyntheticInputEvent = SyntheticEvent$1.extend({ +var SyntheticInputEvent = SyntheticEvent.extend({ data: null }); var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space var START_KEYCODE = 229; -var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window; +var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window; var documentMode = null; -if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { +if (canUseDOM && 'documentMode' in document) { documentMode = document.documentMode; } // Webkit offers a very useful `textInput` event that can be used to // directly represent `beforeInput`. The IE `textinput` event is not as // useful, so we don't use it. -var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode; +var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied // by the native compositionend event may be incorrect. Japanese ideographic // spaces, for instance (\u3000) are not recorded correctly. -var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); +var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); var SPACEBAR_CODE = 32; var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); @@ -8423,6 +7946,20 @@ function getDataFromCustomEvent(nativeEvent) { return null; } +/** + * Check if a composition event was triggered by Korean IME. + * Our fallback mode does not work well with IE's Korean IME, + * so just use native composition events when Korean IME is used. + * Although CompositionEvent.locale property is deprecated, + * it is available in IE, where our fallback mode is enabled. + * + * @param {object} nativeEvent + * @return {boolean} + */ +function isUsingKoreanIME(nativeEvent) { + return nativeEvent.locale === 'ko'; +} + // Track the current IME composition status, if any. var isComposing = false; @@ -8447,7 +7984,7 @@ function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEv return null; } - if (useFallbackCompositionData) { + if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) { // The current composition is stored statically and must not be // overwritten while composition continues. if (!isComposing && eventType === eventTypes.compositionStart) { @@ -8514,7 +8051,7 @@ function getNativeBeforeInputChars(topLevelType, nativeEvent) { // If it's a spacebar character, assume that we have already handled // it at the keypress level and bail immediately. Android Chrome - // doesn't give us keycodes, so we need to blacklist it. + // doesn't give us keycodes, so we need to ignore it. if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { return null; } @@ -8587,7 +8124,7 @@ function getFallbackBeforeInputChars(topLevelType, nativeEvent) { } return null; case TOP_COMPOSITION_END: - return useFallbackCompositionData ? null : nativeEvent.data; + return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data; default: return null; } @@ -8661,16 +8198,7 @@ var BeforeInputEventPlugin = { // Use to restore controlled state after a change event has fired. -var fiberHostComponent = null; - -var ReactControlledComponentInjection = { - injectFiberControlledHostComponent: function (hostComponentImpl) { - // The fiber implementation doesn't use dynamic dispatch so we need to - // inject the implementation. - fiberHostComponent = hostComponentImpl; - } -}; - +var restoreImpl = null; var restoreTarget = null; var restoreQueue = null; @@ -8682,12 +8210,14 @@ function restoreStateOfTarget(target) { // Unmounted return; } - !(fiberHostComponent && typeof fiberHostComponent.restoreControlledState === 'function') ? invariant(false, 'Fiber needs to be injected to handle a fiber target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0; + !(typeof restoreImpl === 'function') ? invariant(false, 'setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0; var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); - fiberHostComponent.restoreControlledState(internalInstance.stateNode, internalInstance.type, props); + restoreImpl(internalInstance.stateNode, internalInstance.type, props); } -var injection$2 = ReactControlledComponentInjection; +function setRestoreImplementation(impl) { + restoreImpl = impl; +} function enqueueStateRestore(target) { if (restoreTarget) { @@ -8722,13 +8252,6 @@ function restoreStateIfNeeded() { } } -var ReactControlledComponent = Object.freeze({ - injection: injection$2, - enqueueStateRestore: enqueueStateRestore, - needsStateRestore: needsStateRestore, - restoreStateIfNeeded: restoreStateIfNeeded -}); - // Used as a way to call batchedUpdates when we don't have a reference to // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when @@ -8736,13 +8259,13 @@ var ReactControlledComponent = Object.freeze({ // scheduled work and instead do synchronous work. // Defaults -var _batchedUpdates = function (fn, bookkeeping) { +var _batchedUpdatesImpl = function (fn, bookkeeping) { return fn(bookkeeping); }; -var _interactiveUpdates = function (fn, a, b) { +var _interactiveUpdatesImpl = function (fn, a, b) { return fn(a, b); }; -var _flushInteractiveUpdates = function () {}; +var _flushInteractiveUpdatesImpl = function () {}; var isBatching = false; function batchedUpdates(fn, bookkeeping) { @@ -8753,7 +8276,7 @@ function batchedUpdates(fn, bookkeeping) { } isBatching = true; try { - return _batchedUpdates(fn, bookkeeping); + return _batchedUpdatesImpl(fn, bookkeeping); } finally { // Here we wait until all updates have propagated, which is important // when using controlled components within layers: @@ -8765,25 +8288,23 @@ function batchedUpdates(fn, bookkeeping) { // If a controlled event was fired, we may need to restore the state of // the DOM node back to the controlled value. This is necessary when React // bails out of the update without touching the DOM. - _flushInteractiveUpdates(); + _flushInteractiveUpdatesImpl(); restoreStateIfNeeded(); } } } function interactiveUpdates(fn, a, b) { - return _interactiveUpdates(fn, a, b); + return _interactiveUpdatesImpl(fn, a, b); } -var injection$3 = { - injectRenderer: function (renderer) { - _batchedUpdates = renderer.batchedUpdates; - _interactiveUpdates = renderer.interactiveUpdates; - _flushInteractiveUpdates = renderer.flushInteractiveUpdates; - } -}; +function setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) { + _batchedUpdatesImpl = batchedUpdatesImpl; + _interactiveUpdatesImpl = interactiveUpdatesImpl; + _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl; +} /** * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary @@ -8861,13 +8382,12 @@ function getEventTarget(nativeEvent) { * Borrows from Modernizr. * * @param {string} eventNameSuffix Event name, e.g. "click". - * @param {?boolean} capture Check if the capture phase is supported. * @return {boolean} True if the event is supported. * @internal * @license Modernizr 3.0.0pre (Custom Build) | MIT */ -function isEventSupported(eventNameSuffix, capture) { - if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) { +function isEventSupported(eventNameSuffix) { + if (!canUseDOM) { return false; } @@ -8991,13 +8511,34 @@ function updateValueIfChanged(node) { return false; } -var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; +var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; -var ReactCurrentOwner = ReactInternals.ReactCurrentOwner; -var ReactDebugCurrentFrame = ReactInternals.ReactDebugCurrentFrame; +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; var describeComponentFrame = function (name, source, ownerName) { - return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : ''); + var sourceInfo = ''; + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ''); + { + // In DEV, include code for a common special case: + // prefer "folder/index.js" instead of just "index.js". + if (/^index\./.test(fileName)) { + var match = path.match(BEFORE_SLASH_RE); + if (match) { + var pathBeforeSlash = match[1]; + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ''); + fileName = folderName + '/' + fileName; + } + } + } + } + sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')'; + } else if (ownerName) { + sourceInfo = ' (created by ' + ownerName + ')'; + } + return '\n in ' + (name || 'Unknown') + sourceInfo; }; // The Symbol used to tag the ReactElement-like types. If there is no native Symbol @@ -9013,13 +8554,13 @@ var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd; var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf; var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; -var REACT_TIMEOUT_TYPE = hasSymbol ? Symbol.for('react.timeout') : 0xead1; +var REACT_PLACEHOLDER_TYPE = hasSymbol ? Symbol.for('react.placeholder') : 0xead1; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = '@@iterator'; function getIteratorFn(maybeIterable) { - if (maybeIterable === null || typeof maybeIterable === 'undefined') { + if (maybeIterable === null || typeof maybeIterable !== 'object') { return null; } var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; @@ -9029,11 +8570,30 @@ function getIteratorFn(maybeIterable) { return null; } -function getComponentName(fiber) { - var type = fiber.type; +var Pending = 0; +var Resolved = 1; +var Rejected = 2; +function getResultFromResolvedThenable(thenable) { + return thenable._reactResult; +} + +function refineResolvedThenable(thenable) { + return thenable._reactStatus === Resolved ? thenable._reactResult : null; +} + +function getComponentName(type) { + if (type == null) { + // Host root, text node or just invalid type. + return null; + } + { + if (typeof type.tag === 'number') { + warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.'); + } + } if (typeof type === 'function') { - return type.displayName || type.name; + return type.displayName || type.name || null; } if (typeof type === 'string') { return type; @@ -9041,43 +8601,56 @@ function getComponentName(fiber) { switch (type) { case REACT_ASYNC_MODE_TYPE: return 'AsyncMode'; - case REACT_CONTEXT_TYPE: - return 'Context.Consumer'; case REACT_FRAGMENT_TYPE: - return 'ReactFragment'; + return 'Fragment'; case REACT_PORTAL_TYPE: - return 'ReactPortal'; + return 'Portal'; case REACT_PROFILER_TYPE: - return 'Profiler(' + fiber.pendingProps.id + ')'; - case REACT_PROVIDER_TYPE: - return 'Context.Provider'; + return 'Profiler'; case REACT_STRICT_MODE_TYPE: return 'StrictMode'; - case REACT_TIMEOUT_TYPE: - return 'Timeout'; + case REACT_PLACEHOLDER_TYPE: + return 'Placeholder'; } - if (typeof type === 'object' && type !== null) { + if (typeof type === 'object') { switch (type.$$typeof) { + case REACT_CONTEXT_TYPE: + return 'Context.Consumer'; + case REACT_PROVIDER_TYPE: + return 'Context.Provider'; case REACT_FORWARD_REF_TYPE: - var functionName = type.render.displayName || type.render.name || ''; - return functionName !== '' ? 'ForwardRef(' + functionName + ')' : 'ForwardRef'; + var renderFn = type.render; + var functionName = renderFn.displayName || renderFn.name || ''; + return type.displayName || (functionName !== '' ? 'ForwardRef(' + functionName + ')' : 'ForwardRef'); + } + if (typeof type.then === 'function') { + var thenable = type; + var resolvedThenable = refineResolvedThenable(thenable); + if (resolvedThenable) { + return getComponentName(resolvedThenable); + } } } return null; } +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + function describeFiber(fiber) { switch (fiber.tag) { case IndeterminateComponent: case FunctionalComponent: + case FunctionalComponentLazy: case ClassComponent: + case ClassComponentLazy: case HostComponent: + case Mode: var owner = fiber._debugOwner; var source = fiber._debugSource; - var name = getComponentName(fiber); + var name = getComponentName(fiber.type); var ownerName = null; if (owner) { - ownerName = getComponentName(owner); + ownerName = getComponentName(owner.type); } return describeComponentFrame(name, source, ownerName); default: @@ -9085,72 +8658,93 @@ function describeFiber(fiber) { } } -// This function can only be called with a work-in-progress fiber and -// only during begin or complete phase. Do not call it under any other -// circumstances. -function getStackAddendumByWorkInProgressFiber(workInProgress) { +function getStackByFiberInDevAndProd(workInProgress) { var info = ''; var node = workInProgress; do { info += describeFiber(node); - // Otherwise this return pointer might point to the wrong tree: node = node.return; } while (node); return info; } -function getCurrentFiberOwnerName$1() { +var current = null; +var phase = null; + +function getCurrentFiberOwnerNameInDevOrNull() { { - var fiber = ReactDebugCurrentFiber.current; - if (fiber === null) { + if (current === null) { return null; } - var owner = fiber._debugOwner; + var owner = current._debugOwner; if (owner !== null && typeof owner !== 'undefined') { - return getComponentName(owner); + return getComponentName(owner.type); } } return null; } -function getCurrentFiberStackAddendum$1() { +function getCurrentFiberStackInDev() { { - var fiber = ReactDebugCurrentFiber.current; - if (fiber === null) { - return null; + if (current === null) { + return ''; } // Safe because if current fiber exists, we are reconciling, // and it is guaranteed to be the work-in-progress version. - return getStackAddendumByWorkInProgressFiber(fiber); + return getStackByFiberInDevAndProd(current); } - return null; + return ''; } function resetCurrentFiber() { - ReactDebugCurrentFrame.getCurrentStack = null; - ReactDebugCurrentFiber.current = null; - ReactDebugCurrentFiber.phase = null; + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + phase = null; + } } function setCurrentFiber(fiber) { - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum$1; - ReactDebugCurrentFiber.current = fiber; - ReactDebugCurrentFiber.phase = null; + { + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; + current = fiber; + phase = null; + } } -function setCurrentPhase(phase) { - ReactDebugCurrentFiber.phase = phase; +function setCurrentPhase(lifeCyclePhase) { + { + phase = lifeCyclePhase; + } } -var ReactDebugCurrentFiber = { - current: null, - phase: null, - resetCurrentFiber: resetCurrentFiber, - setCurrentFiber: setCurrentFiber, - setCurrentPhase: setCurrentPhase, - getCurrentFiberOwnerName: getCurrentFiberOwnerName$1, - getCurrentFiberStackAddendum: getCurrentFiberStackAddendum$1 -}; +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warning = warningWithoutStack$1; + +{ + warning = function (condition, format) { + if (condition) { + return; + } + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + // eslint-disable-next-line react-internal/warning-and-invariant-args + + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } + + warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack])); + }; +} + +var warning$1 = warning; // A reserved attribute. // It is handled by React separately and shouldn't be written to the DOM. @@ -9211,7 +8805,7 @@ function isAttributeNameSafe(attributeName) { } illegalAttributeNameCache[attributeName] = true; { - warning(false, 'Invalid attribute name: `%s`', attributeName); + warning$1(false, 'Invalid attribute name: `%s`', attributeName); } return false; } @@ -9337,7 +8931,7 @@ var properties = {}; // In React, we let users pass `true` and `false` even though technically // these aren't boolean attributes (they are coerced to strings). // Since these are SVG attributes, their attribute names are case-sensitive. -['autoReverse', 'externalResourcesRequired', 'preserveAlpha'].forEach(function (name) { +['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty name, // attributeName null); @@ -9364,7 +8958,7 @@ var properties = {}; // disabled with `removeAttribute`. We have special logic for handling this. 'multiple', 'muted', 'selected'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty - name.toLowerCase(), // attributeName + name, // attributeName null); } // attributeNamespace ); @@ -9373,7 +8967,7 @@ var properties = {}; // booleans, but can also accept a string value. ['capture', 'download'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty - name.toLowerCase(), // attributeName + name, // attributeName null); } // attributeNamespace ); @@ -9381,7 +8975,7 @@ var properties = {}; // These are HTML attributes that must be positive numbers. ['cols', 'rows', 'size', 'span'].forEach(function (name) { properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty - name.toLowerCase(), // attributeName + name, // attributeName null); } // attributeNamespace ); @@ -9580,11 +9174,36 @@ function setValueForProperty(node, name, value, isCustomComponentTag) { } } +// Flow does not allow string concatenation of most non-string types. To work +// around this limitation, we use an opaque type that can only be obtained by +// passing the value through getToStringValue first. +function toString(value) { + return '' + value; +} + +function getToStringValue(value) { + switch (typeof value) { + case 'boolean': + case 'number': + case 'object': + case 'string': + case 'undefined': + return value; + default: + // function, symbol are assigned as empty strings + return ''; + } +} + +var ReactDebugCurrentFrame$1 = null; + var ReactControlledValuePropTypes = { checkPropTypes: null }; { + ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; + var hasReadOnlyValue = { button: true, checkbox: true, @@ -9597,13 +9216,13 @@ var ReactControlledValuePropTypes = { var propTypes = { value: function (props, propName, componentName) { - if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) { + if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) { return null; } return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); }, checked: function (props, propName, componentName) { - if (!props[propName] || props.onChange || props.readOnly || props.disabled) { + if (props.onChange || props.readOnly || props.disabled || props[propName] == null) { return null; } return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); @@ -9614,15 +9233,55 @@ var ReactControlledValuePropTypes = { * Provide a linked `value` attribute for controlled forms. You should not use * this outside of the ReactDOM controlled form components. */ - ReactControlledValuePropTypes.checkPropTypes = function (tagName, props, getStack) { - checkPropTypes(propTypes, props, 'prop', tagName, getStack); + ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) { + checkPropTypes(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum); }; } -// TODO: direct imports like some-package/src/* are bad. Fix me. -var getCurrentFiberOwnerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName; -var getCurrentFiberStackAddendum = ReactDebugCurrentFiber.getCurrentFiberStackAddendum; +// Exports ReactDOM.createRoot +var enableUserTimingAPI = true; +// Experimental error-boundary API that can recover from errors within a single +// render phase +var enableGetDerivedStateFromCatch = false; +// Suspense +var enableSuspense = false; +// Helps identify side effects in begin-phase lifecycle hooks and setState reducers: +var debugRenderPhaseSideEffects = false; + +// In some cases, StrictMode should also double-render lifecycles. +// This can be confusing for tests though, +// And it can be bad for performance in production. +// This feature flag can be used to control the behavior: +var debugRenderPhaseSideEffectsForStrictMode = true; + +// To preserve the "Pause on caught exceptions" behavior of the debugger, we +// replay the begin phase of a failed component inside invokeGuardedCallback. +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; + +// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6: +var warnAboutDeprecatedLifecycles = false; + +// Warn about legacy context API +var warnAboutLegacyContextAPI = false; + +// Gather advanced timing metrics for Profiler subtrees. +var enableProfilerTimer = true; + +// Trace which interactions trigger each commit. +var enableSchedulerTracing = true; + +// Only used in www builds. + + +// Only used in www builds. + + +// React Fire: prevent the value and checked attributes from syncing +// with their related DOM properties +var disableInputAttributeSyncing = false; + +// TODO: direct imports like some-package/src/* are bad. Fix me. var didWarnValueDefaultValue = false; var didWarnCheckedDefaultChecked = false; var didWarnControlledToUncontrolled = false; @@ -9666,14 +9325,14 @@ function getHostProps(element, props) { function initWrapperState(element, props) { { - ReactControlledValuePropTypes.checkPropTypes('input', props, getCurrentFiberStackAddendum); + ReactControlledValuePropTypes.checkPropTypes('input', props); if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { - warning(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerName() || 'A component', props.type); + warning$1(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); didWarnCheckedDefaultChecked = true; } if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { - warning(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerName() || 'A component', props.type); + warning$1(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type); didWarnValueDefaultValue = true; } } @@ -9683,7 +9342,7 @@ function initWrapperState(element, props) { node._wrapperState = { initialChecked: props.checked != null ? props.checked : props.defaultChecked, - initialValue: getSafeValue(props.value != null ? props.value : defaultValue), + initialValue: getToStringValue(props.value != null ? props.value : defaultValue), controlled: isControlled(props) }; } @@ -9702,64 +9361,140 @@ function updateWrapper(element, props) { var _controlled = isControlled(props); if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) { - warning(false, 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s', props.type, getCurrentFiberStackAddendum()); + warning$1(false, 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type); didWarnUncontrolledToControlled = true; } if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) { - warning(false, 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s', props.type, getCurrentFiberStackAddendum()); + warning$1(false, 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type); didWarnControlledToUncontrolled = true; } } updateChecked(element, props); - var value = getSafeValue(props.value); + var value = getToStringValue(props.value); + var type = props.type; if (value != null) { - if (props.type === 'number') { + if (type === 'number') { if (value === 0 && node.value === '' || + // We explicitly want to coerce to number here if possible. // eslint-disable-next-line node.value != value) { - node.value = '' + value; + node.value = toString(value); } - } else if (node.value !== '' + value) { - node.value = '' + value; + } else if (node.value !== toString(value)) { + node.value = toString(value); + } + } else if (type === 'submit' || type === 'reset') { + // Submit/reset inputs need the attribute removed completely to avoid + // blank-text buttons. + node.removeAttribute('value'); + return; + } + + if (disableInputAttributeSyncing) { + // When not syncing the value attribute, React only assigns a new value + // whenever the defaultValue React prop has changed. When not present, + // React does nothing + if (props.hasOwnProperty('defaultValue')) { + setDefaultValue(node, props.type, getToStringValue(props.defaultValue)); + } + } else { + // When syncing the value attribute, the value comes from a cascade of + // properties: + // 1. The value React property + // 2. The defaultValue React property + // 3. Otherwise there should be no change + if (props.hasOwnProperty('value')) { + setDefaultValue(node, props.type, value); + } else if (props.hasOwnProperty('defaultValue')) { + setDefaultValue(node, props.type, getToStringValue(props.defaultValue)); } } - if (props.hasOwnProperty('value')) { - setDefaultValue(node, props.type, value); - } else if (props.hasOwnProperty('defaultValue')) { - setDefaultValue(node, props.type, getSafeValue(props.defaultValue)); - } - - if (props.checked == null && props.defaultChecked != null) { - node.defaultChecked = !!props.defaultChecked; + if (disableInputAttributeSyncing) { + // When not syncing the checked attribute, the attribute is directly + // controllable from the defaultValue React property. It needs to be + // updated as new props come in. + if (props.defaultChecked == null) { + node.removeAttribute('checked'); + } else { + node.defaultChecked = !!props.defaultChecked; + } + } else { + // When syncing the checked attribute, it only changes when it needs + // to be removed, such as transitioning from a checkbox into a text input + if (props.checked == null && props.defaultChecked != null) { + node.defaultChecked = !!props.defaultChecked; + } } } function postMountWrapper(element, props, isHydrating) { var node = element; + // Do not assign value if it is already set. This prevents user text input + // from being lost during SSR hydration. if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) { - var _initialValue = '' + node._wrapperState.initialValue; - var currentValue = node.value; + var type = props.type; + var isButton = type === 'submit' || type === 'reset'; + + // Avoid setting value attribute on submit/reset inputs as it overrides the + // default value provided by the browser. See: #12872 + if (isButton && (props.value === undefined || props.value === null)) { + return; + } + + var _initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input // from being lost during SSR hydration. if (!isHydrating) { - // Do not re-assign the value property if there is no change. This - // potentially avoids a DOM write and prevents Firefox (~60.0.1) from - // prematurely marking required inputs as invalid - if (_initialValue !== currentValue) { - node.value = _initialValue; + if (disableInputAttributeSyncing) { + var value = getToStringValue(props.value); + + // When not syncing the value attribute, the value property points + // directly to the React prop. Only assign it if it exists. + if (value != null) { + // Always assign on buttons so that it is possible to assign an + // empty string to clear button text. + // + // Otherwise, do not re-assign the value property if is empty. This + // potentially avoids a DOM write and prevents Firefox (~60.0.1) from + // prematurely marking required inputs as invalid. Equality is compared + // to the current value in case the browser provided value is not an + // empty string. + if (isButton || value !== node.value) { + node.value = toString(value); + } + } + } else { + // When syncing the value attribute, the value property should use + // the the wrapperState._initialValue property. This uses: + // + // 1. The value React property when present + // 2. The defaultValue React property when present + // 3. An empty string + if (_initialValue !== node.value) { + node.value = _initialValue; + } } } - // value must be assigned before defaultValue. This fixes an issue where the - // visually displayed value of date inputs disappears on mobile Safari and Chrome: - // https://github.com/facebook/react/issues/7233 - node.defaultValue = _initialValue; + if (disableInputAttributeSyncing) { + // When not syncing the value attribute, assign the value attribute + // directly from the defaultValue React property (when present) + var defaultValue = getToStringValue(props.defaultValue); + if (defaultValue != null) { + node.defaultValue = toString(defaultValue); + } + } else { + // Otherwise, the value attribute is synchronized to the property, + // so we assign defaultValue to the same thing as the value property + // assignment step above. + node.defaultValue = _initialValue; + } } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug @@ -9771,8 +9506,34 @@ function postMountWrapper(element, props, isHydrating) { if (name !== '') { node.name = ''; } - node.defaultChecked = !node.defaultChecked; - node.defaultChecked = !node.defaultChecked; + + if (disableInputAttributeSyncing) { + // When not syncing the checked attribute, the checked property + // never gets assigned. It must be manually set. We don't want + // to do this when hydrating so that existing user input isn't + // modified + if (!isHydrating) { + updateChecked(element, props); + } + + // Only assign the checked attribute if it is defined. This saves + // a DOM write when controlling the checked attribute isn't needed + // (text inputs, submit/reset) + if (props.hasOwnProperty('defaultChecked')) { + node.defaultChecked = !node.defaultChecked; + node.defaultChecked = !!props.defaultChecked; + } + } else { + // When syncing the checked attribute, both the the checked property and + // attribute are assigned at the same time using defaultChecked. This uses: + // + // 1. The checked React property when present + // 2. The defaultChecked React property when present + // 3. Otherwise, false + node.defaultChecked = !node.defaultChecked; + node.defaultChecked = !!node._wrapperState.initialChecked; + } + if (name !== '') { node.name = name; } @@ -9839,27 +9600,13 @@ function setDefaultValue(node, type, value) { // Focused number inputs synchronize on blur. See ChangeEventPlugin.js type !== 'number' || node.ownerDocument.activeElement !== node) { if (value == null) { - node.defaultValue = '' + node._wrapperState.initialValue; - } else if (node.defaultValue !== '' + value) { - node.defaultValue = '' + value; + node.defaultValue = toString(node._wrapperState.initialValue); + } else if (node.defaultValue !== toString(value)) { + node.defaultValue = toString(value); } } } -function getSafeValue(value) { - switch (typeof value) { - case 'boolean': - case 'number': - case 'object': - case 'string': - case 'undefined': - return value; - default: - // function, symbol are assigned as empty strings - return ''; - } -} - var eventTypes$1 = { change: { phasedRegistrationNames: { @@ -9871,7 +9618,7 @@ var eventTypes$1 = { }; function createAndAccumulateChangeEvent(inst, nativeEvent, target) { - var event = SyntheticEvent$1.getPooled(eventTypes$1.change, inst, nativeEvent, target); + var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target); event.type = 'change'; // Flag this event loop as needing state restore. enqueueStateRestore(target); @@ -9930,7 +9677,7 @@ function getTargetInstForChangeEvent(topLevelType, targetInst) { * SECTION: handle `input` event */ var isInputEventSupported = false; -if (ExecutionEnvironment.canUseDOM) { +if (canUseDOM) { // IE9 claims to support the input event but fails to trigger it when // deleting text, so we ignore its input events. isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9); @@ -10039,8 +9786,10 @@ function handleControlledInputBlur(node) { return; } - // If controlled, assign the value attribute to the current value on blur - setDefaultValue(node, 'number', node.value); + if (!disableInputAttributeSyncing) { + // If controlled, assign the value attribute to the current value on blur + setDefaultValue(node, 'number', node.value); + } } /** @@ -10104,9 +9853,9 @@ var ChangeEventPlugin = { * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that * preventing default on events is convenient in `SimpleEventPlugin` handlers. */ -var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin']; +var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin']; -var SyntheticUIEvent = SyntheticEvent$1.extend({ +var SyntheticUIEvent = SyntheticEvent.extend({ view: null, detail: null }); @@ -10140,6 +9889,12 @@ function getEventModifierState(nativeEvent) { return modifierStateGetter; } +var previousScreenX = 0; +var previousScreenY = 0; +// Use flags to signal movementX/Y has already been set +var isMovementXSet = false; +var isMovementYSet = false; + /** * @interface MouseEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ @@ -10160,6 +9915,36 @@ var SyntheticMouseEvent = SyntheticUIEvent.extend({ buttons: null, relatedTarget: function (event) { return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement); + }, + movementX: function (event) { + if ('movementX' in event) { + return event.movementX; + } + + var screenX = previousScreenX; + previousScreenX = event.screenX; + + if (!isMovementXSet) { + isMovementXSet = true; + return 0; + } + + return event.type === 'mousemove' ? event.screenX - screenX : 0; + }, + movementY: function (event) { + if ('movementY' in event) { + return event.movementY; + } + + var screenY = previousScreenY; + previousScreenY = event.screenY; + + if (!isMovementYSet) { + isMovementYSet = true; + return 0; + } + + return event.type === 'mousemove' ? event.screenY - screenY : 0; } }); @@ -10172,8 +9957,10 @@ var SyntheticPointerEvent = SyntheticMouseEvent.extend({ width: null, height: null, pressure: null, + tangentialPressure: null, tiltX: null, tiltY: null, + twist: null, pointerType: null, isPrimary: null }); @@ -10287,6 +10074,58 @@ var EnterLeaveEventPlugin = { } }; +/*eslint-disable no-self-compare */ + +var hasOwnProperty$1 = Object.prototype.hasOwnProperty; + +/** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ +function is(x, y) { + // SameValue algorithm + if (x === y) { + // Steps 1-5, 7-10 + // Steps 6.b-6.e: +0 != -0 + // Added the nonzero y check to make Flow happy, but it is redundant + return x !== 0 || y !== 0 || 1 / x === 1 / y; + } else { + // Step 6.a: NaN == NaN + return x !== x && y !== y; + } +} + +/** + * Performs equality by iterating through keys on an object and returning false + * when any key has values which are not strictly equal between the arguments. + * Returns true when the values of all keys are strictly equal. + */ +function shallowEqual(objA, objB) { + if (is(objA, objB)) { + return true; + } + + if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { + return false; + } + + var keysA = Object.keys(objA); + var keysB = Object.keys(objB); + + if (keysA.length !== keysB.length) { + return false; + } + + // Test for A's keys different from B. + for (var i = 0; i < keysA.length; i++) { + if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { + return false; + } + } + + return true; +} + /** * `ReactInstanceMap` maintains a mapping from a public facing stateful * instance (key) and the internal representation (value). This allows public @@ -10331,12 +10170,17 @@ var DidCapture = /* */64; var Ref = /* */128; var Snapshot = /* */256; +// Update & Callback & Ref & Snapshot +var LifecycleEffectMask = /* */420; + // Union of all host effects var HostEffectMask = /* */511; var Incomplete = /* */512; var ShouldCapture = /* */1024; +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; + var MOUNTING = 1; var MOUNTED = 2; var UNMOUNTED = 3; @@ -10376,11 +10220,11 @@ function isFiberMounted(fiber) { function isMounted(component) { { - var owner = ReactCurrentOwner.current; - if (owner !== null && owner.tag === ClassComponent) { + var owner = ReactCurrentOwner$1.current; + if (owner !== null && (owner.tag === ClassComponent || owner.tag === ClassComponentLazy)) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - !instance._warnedAboutRefsInRender ? warning(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber) || 'A component') : void 0; + !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0; instance._warnedAboutRefsInRender = true; } } @@ -10587,7 +10431,7 @@ function addEventCaptureListener(element, eventType, listener) { * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent */ -var SyntheticAnimationEvent = SyntheticEvent$1.extend({ +var SyntheticAnimationEvent = SyntheticEvent.extend({ animationName: null, elapsedTime: null, pseudoElement: null @@ -10597,7 +10441,7 @@ var SyntheticAnimationEvent = SyntheticEvent$1.extend({ * @interface Event * @see http://www.w3.org/TR/clipboard-apis/ */ -var SyntheticClipboardEvent = SyntheticEvent$1.extend({ +var SyntheticClipboardEvent = SyntheticEvent.extend({ clipboardData: function (event) { return 'clipboardData' in event ? event.clipboardData : window.clipboardData; } @@ -10828,7 +10672,7 @@ var SyntheticTouchEvent = SyntheticUIEvent.extend({ * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events- * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent */ -var SyntheticTransitionEvent = SyntheticEvent$1.extend({ +var SyntheticTransitionEvent = SyntheticEvent.extend({ propertyName: null, elapsedTime: null, pseudoElement: null @@ -10877,7 +10721,7 @@ var SyntheticWheelEvent = SyntheticMouseEvent.extend({ * ]); */ -var interactiveEventTypeNames = [[TOP_BLUR, 'blur'], [TOP_CANCEL, 'cancel'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_START, 'dragStart'], [TOP_DROP, 'drop'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_INVALID, 'invalid'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_POINTER_CANCEL, 'pointerCancel'], [TOP_POINTER_DOWN, 'pointerDown'], [TOP_POINTER_UP, 'pointerUp'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_RESET, 'reset'], [TOP_SEEKED, 'seeked'], [TOP_SUBMIT, 'submit'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_START, 'touchStart'], [TOP_VOLUME_CHANGE, 'volumeChange']]; +var interactiveEventTypeNames = [[TOP_BLUR, 'blur'], [TOP_CANCEL, 'cancel'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_AUX_CLICK, 'auxClick'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_START, 'dragStart'], [TOP_DROP, 'drop'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_INVALID, 'invalid'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_POINTER_CANCEL, 'pointerCancel'], [TOP_POINTER_DOWN, 'pointerDown'], [TOP_POINTER_UP, 'pointerUp'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_RESET, 'reset'], [TOP_SEEKED, 'seeked'], [TOP_SUBMIT, 'submit'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_START, 'touchStart'], [TOP_VOLUME_CHANGE, 'volumeChange']]; var nonInteractiveEventTypeNames = [[TOP_ABORT, 'abort'], [TOP_ANIMATION_END, 'animationEnd'], [TOP_ANIMATION_ITERATION, 'animationIteration'], [TOP_ANIMATION_START, 'animationStart'], [TOP_CAN_PLAY, 'canPlay'], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough'], [TOP_DRAG, 'drag'], [TOP_DRAG_ENTER, 'dragEnter'], [TOP_DRAG_EXIT, 'dragExit'], [TOP_DRAG_LEAVE, 'dragLeave'], [TOP_DRAG_OVER, 'dragOver'], [TOP_DURATION_CHANGE, 'durationChange'], [TOP_EMPTIED, 'emptied'], [TOP_ENCRYPTED, 'encrypted'], [TOP_ENDED, 'ended'], [TOP_ERROR, 'error'], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture'], [TOP_LOAD, 'load'], [TOP_LOADED_DATA, 'loadedData'], [TOP_LOADED_METADATA, 'loadedMetadata'], [TOP_LOAD_START, 'loadStart'], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture'], [TOP_MOUSE_MOVE, 'mouseMove'], [TOP_MOUSE_OUT, 'mouseOut'], [TOP_MOUSE_OVER, 'mouseOver'], [TOP_PLAYING, 'playing'], [TOP_POINTER_MOVE, 'pointerMove'], [TOP_POINTER_OUT, 'pointerOut'], [TOP_POINTER_OVER, 'pointerOver'], [TOP_PROGRESS, 'progress'], [TOP_SCROLL, 'scroll'], [TOP_SEEKING, 'seeking'], [TOP_STALLED, 'stalled'], [TOP_SUSPEND, 'suspend'], [TOP_TIME_UPDATE, 'timeUpdate'], [TOP_TOGGLE, 'toggle'], [TOP_TOUCH_MOVE, 'touchMove'], [TOP_TRANSITION_END, 'transitionEnd'], [TOP_WAITING, 'waiting'], [TOP_WHEEL, 'wheel']]; var eventTypes$4 = {}; @@ -10951,6 +10795,7 @@ var SimpleEventPlugin = { return null; } /* falls through */ + case TOP_AUX_CLICK: case TOP_DOUBLE_CLICK: case TOP_MOUSE_DOWN: case TOP_MOUSE_MOVE: @@ -11010,12 +10855,12 @@ var SimpleEventPlugin = { default: { if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) { - warning(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType); + warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType); } } // HTML Events // @see http://www.w3.org/TR/html5/index.html#events-0 - EventConstructor = SyntheticEvent$1; + EventConstructor = SyntheticEvent; break; } var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget); @@ -11184,15 +11029,6 @@ function dispatchEvent(topLevelType, nativeEvent) { } } -var ReactDOMEventListener = Object.freeze({ - get _enabled () { return _enabled; }, - setEnabled: setEnabled, - isEnabled: isEnabled, - trapBubbledEvent: trapBubbledEvent, - trapCapturedEvent: trapCapturedEvent, - dispatchEvent: dispatchEvent -}); - /** * Summary of `ReactBrowserEventEmitter` event handling: * @@ -11310,7 +11146,7 @@ function listenTo(registrationName, mountAt) { break; case TOP_CANCEL: case TOP_CLOSE: - if (isEventSupported(getRawEventName(dependency), true)) { + if (isEventSupported(getRawEventName(dependency))) { trapCapturedEvent(dependency, mountAt); } break; @@ -11346,6 +11182,18 @@ function isListeningToAllDependencies(registrationName, mountAt) { return true; } +function getActiveElement(doc) { + doc = doc || (typeof document !== 'undefined' ? document : undefined); + if (typeof doc === 'undefined') { + return null; + } + try { + return doc.activeElement || doc.body; + } catch (e) { + return doc.body; + } +} + /** * Given any node return the first leaf node without children. * @@ -11410,7 +11258,10 @@ function getNodeForCharacterOffset(root, offset) { * @return {?object} */ function getOffsets(outerNode) { - var selection = window.getSelection && window.getSelection(); + var ownerDocument = outerNode.ownerDocument; + + var win = ownerDocument && ownerDocument.defaultView || window; + var selection = win.getSelection && win.getSelection(); if (!selection || selection.rangeCount === 0) { return null; @@ -11532,12 +11383,10 @@ function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNo * @param {object} offsets */ function setOffsets(node, offsets) { - if (!window.getSelection) { - return; - } - - var selection = window.getSelection(); - var length = node[getTextContentAccessor()].length; + var doc = node.ownerDocument || document; + var win = doc && doc.defaultView || window; + var selection = win.getSelection(); + var length = node.textContent.length; var start = Math.min(offsets.start, length); var end = offsets.end === undefined ? start : Math.min(offsets.end, length); @@ -11556,7 +11405,7 @@ function setOffsets(node, offsets) { if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) { return; } - var range = document.createRange(); + var range = doc.createRange(); range.setStart(startMarker.node, startMarker.offset); selection.removeAllRanges(); @@ -11570,8 +11419,46 @@ function setOffsets(node, offsets) { } } +function isTextNode(node) { + return node && node.nodeType === TEXT_NODE; +} + +function containsNode(outerNode, innerNode) { + if (!outerNode || !innerNode) { + return false; + } else if (outerNode === innerNode) { + return true; + } else if (isTextNode(outerNode)) { + return false; + } else if (isTextNode(innerNode)) { + return containsNode(outerNode, innerNode.parentNode); + } else if ('contains' in outerNode) { + return outerNode.contains(innerNode); + } else if (outerNode.compareDocumentPosition) { + return !!(outerNode.compareDocumentPosition(innerNode) & 16); + } else { + return false; + } +} + function isInDocument(node) { - return containsNode(document.documentElement, node); + return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node); +} + +function getActiveElementDeep() { + var win = window; + var element = getActiveElement(); + while (element instanceof win.HTMLIFrameElement) { + // Accessing the contentDocument of a HTMLIframeElement can cause the browser + // to throw, e.g. if it has a cross-origin src attribute + try { + win = element.contentDocument.defaultView; + } catch (e) { + return element; + } + element = getActiveElement(win.document); + } + return element; } /** @@ -11592,7 +11479,7 @@ function hasSelectionCapabilities(elem) { } function getSelectionInformation() { - var focusedElem = getActiveElement(); + var focusedElem = getActiveElementDeep(); return { focusedElem: focusedElem, selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null @@ -11605,7 +11492,7 @@ function getSelectionInformation() { * nodes and place them back in, resulting in focus being lost. */ function restoreSelection(priorSelectionInformation) { - var curFocusedElem = getActiveElement(); + var curFocusedElem = getActiveElementDeep(); var priorFocusedElem = priorSelectionInformation.focusedElem; var priorSelectionRange = priorSelectionInformation.selectionRange; if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { @@ -11683,7 +11570,7 @@ function setSelection(input, offsets) { } } -var skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11; +var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11; var eventTypes$3 = { select: { @@ -11691,7 +11578,7 @@ var eventTypes$3 = { bubbled: 'onSelect', captured: 'onSelectCapture' }, - dependencies: [TOP_BLUR, TOP_CONTEXT_MENU, TOP_FOCUS, TOP_KEY_DOWN, TOP_KEY_UP, TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_SELECTION_CHANGE] + dependencies: [TOP_BLUR, TOP_CONTEXT_MENU, TOP_DRAG_END, TOP_FOCUS, TOP_KEY_DOWN, TOP_KEY_UP, TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_SELECTION_CHANGE] } }; @@ -11715,8 +11602,9 @@ function getSelection(node) { start: node.selectionStart, end: node.selectionEnd }; - } else if (window.getSelection) { - var selection = window.getSelection(); + } else { + var win = node.ownerDocument && node.ownerDocument.defaultView || window; + var selection = win.getSelection(); return { anchorNode: selection.anchorNode, anchorOffset: selection.anchorOffset, @@ -11726,10 +11614,21 @@ function getSelection(node) { } } +/** + * Get document associated with the event target. + * + * @param {object} nativeEventTarget + * @return {Document} + */ +function getEventTargetDocument(eventTarget) { + return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument; +} + /** * Poll selection to see whether it's changed. * * @param {object} nativeEvent + * @param {object} nativeEventTarget * @return {?SyntheticEvent} */ function constructSelectEvent(nativeEvent, nativeEventTarget) { @@ -11737,7 +11636,9 @@ function constructSelectEvent(nativeEvent, nativeEventTarget) { // selection (this matches native `select` event behavior). In HTML5, select // fires only on input and textarea thus if there's no focused element we // won't dispatch. - if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement()) { + var doc = getEventTargetDocument(nativeEventTarget); + + if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) { return null; } @@ -11746,7 +11647,7 @@ function constructSelectEvent(nativeEvent, nativeEventTarget) { if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { lastSelection = currentSelection; - var syntheticEvent = SyntheticEvent$1.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget); + var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget); syntheticEvent.type = 'select'; syntheticEvent.target = activeElement$1; @@ -11777,7 +11678,7 @@ var SelectEventPlugin = { eventTypes: eventTypes$3, extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { - var doc = nativeEventTarget.window === nativeEventTarget ? nativeEventTarget.document : nativeEventTarget.nodeType === DOCUMENT_NODE ? nativeEventTarget : nativeEventTarget.ownerDocument; + var doc = getEventTargetDocument(nativeEventTarget); // Track whether all listeners exists for this plugin. If none exist, we do // not extract events. See #3639. if (!doc || !isListeningToAllDependencies('onSelect', doc)) { @@ -11807,6 +11708,7 @@ var SelectEventPlugin = { break; case TOP_CONTEXT_MENU: case TOP_MOUSE_UP: + case TOP_DRAG_END: mouseDown = false; return constructSelectEvent(nativeEvent, nativeEventTarget); // Chrome and IE fire non-standard event when selection is changed (and @@ -11836,7 +11738,7 @@ var SelectEventPlugin = { * Inject modules for resolving DOM hierarchy and plugin ordering. */ injection.injectEventPluginOrder(DOMEventPluginOrder); -injection$1.injectComponentTree(ReactDOMComponentTree); +setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1); /** * Some important event plugins included by default (without having to require @@ -11850,388 +11752,25 @@ injection.injectEventPluginsByName({ BeforeInputEventPlugin: BeforeInputEventPlugin }); -// We capture a local reference to any global, in case it gets polyfilled after -// this module is initially evaluated. -// We want to be using a consistent implementation. - -var localRequestAnimationFrame$1 = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : undefined; - -/** - * A scheduling library to allow scheduling work with more granular priority and - * control than requestAnimationFrame and requestIdleCallback. - * Current TODO items: - * X- Pull out the scheduleWork polyfill built into React - * X- Initial test coverage - * X- Support for multiple callbacks - * - Support for two priorities; serial and deferred - * - Better test coverage - * - Better docblock - * - Polish documentation, API - */ - -// This is a built-in polyfill for requestIdleCallback. It works by scheduling -// a requestAnimationFrame, storing the time for the start of the frame, then -// scheduling a postMessage which gets scheduled after paint. Within the -// postMessage handler do as much work as possible until time + frame rate. -// By separating the idle call into a separate event tick we ensure that -// layout, paint and other browser work is counted against the available time. -// The frame rate is dynamically adjusted. - -// We capture a local reference to any global, in case it gets polyfilled after -// this module is initially evaluated. -// We want to be using a consistent implementation. -var localDate = Date; -var localSetTimeout = setTimeout; -var localClearTimeout = clearTimeout; - -var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function'; - -var now$1 = void 0; -if (hasNativePerformanceNow) { - var Performance = performance; - now$1 = function () { - return Performance.now(); - }; -} else { - now$1 = function () { - return localDate.now(); - }; -} - -var scheduleWork = void 0; -var cancelScheduledWork = void 0; - -if (!ExecutionEnvironment.canUseDOM) { - var timeoutIds = new Map(); - - scheduleWork = function (callback, options) { - // keeping return type consistent - var callbackConfig = { - scheduledCallback: callback, - timeoutTime: 0, - next: null, - prev: null - }; - var timeoutId = localSetTimeout(function () { - callback({ - timeRemaining: function () { - return Infinity; - }, - - didTimeout: false - }); - }); - timeoutIds.set(callback, timeoutId); - return callbackConfig; - }; - cancelScheduledWork = function (callbackId) { - var callback = callbackId.scheduledCallback; - var timeoutId = timeoutIds.get(callback); - timeoutIds.delete(callbackId); - localClearTimeout(timeoutId); - }; -} else { - { - if (typeof localRequestAnimationFrame$1 !== 'function') { - warning(false, 'React depends on requestAnimationFrame. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills'); - } - } - - var localRequestAnimationFrame = typeof localRequestAnimationFrame$1 === 'function' ? localRequestAnimationFrame$1 : function (callback) { - invariant(false, 'React depends on requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills'); - }; - - var headOfPendingCallbacksLinkedList = null; - var tailOfPendingCallbacksLinkedList = null; - - // We track what the next soonest timeoutTime is, to be able to quickly tell - // if none of the scheduled callbacks have timed out. - var nextSoonestTimeoutTime = -1; - - var isIdleScheduled = false; - var isAnimationFrameScheduled = false; - - var frameDeadline = 0; - // We start out assuming that we run at 30fps but then the heuristic tracking - // will adjust this value to a faster fps if we get more frequent animation - // frames. - var previousFrameTime = 33; - var activeFrameTime = 33; - - var frameDeadlineObject = { - didTimeout: false, - timeRemaining: function () { - var remaining = frameDeadline - now$1(); - return remaining > 0 ? remaining : 0; - } - }; - - /** - * Handles the case where a callback errors: - * - don't catch the error, because this changes debugging behavior - * - do start a new postMessage callback, to call any remaining callbacks, - * - but only if there is an error, so there is not extra overhead. - */ - var callUnsafely = function (callbackConfig, arg) { - var callback = callbackConfig.scheduledCallback; - var finishedCalling = false; - try { - callback(arg); - finishedCalling = true; - } finally { - // always remove it from linked list - cancelScheduledWork(callbackConfig); - - if (!finishedCalling) { - // an error must have been thrown - isIdleScheduled = true; - window.postMessage(messageKey, '*'); - } - } - }; - - /** - * Checks for timed out callbacks, runs them, and then checks again to see if - * any more have timed out. - * Keeps doing this until there are none which have currently timed out. - */ - var callTimedOutCallbacks = function () { - if (headOfPendingCallbacksLinkedList === null) { - return; - } - - var currentTime = now$1(); - // TODO: this would be more efficient if deferred callbacks are stored in - // min heap. - // Or in a linked list with links for both timeoutTime order and insertion - // order. - // For now an easy compromise is the current approach: - // Keep a pointer to the soonest timeoutTime, and check that first. - // If it has not expired, we can skip traversing the whole list. - // If it has expired, then we step through all the callbacks. - if (nextSoonestTimeoutTime === -1 || nextSoonestTimeoutTime > currentTime) { - // We know that none of them have timed out yet. - return; - } - // NOTE: we intentionally wait to update the nextSoonestTimeoutTime until - // after successfully calling any timed out callbacks. - // If a timed out callback throws an error, we could get stuck in a state - // where the nextSoonestTimeoutTime was set wrong. - var updatedNextSoonestTimeoutTime = -1; // we will update nextSoonestTimeoutTime below - var timedOutCallbacks = []; - - // iterate once to find timed out callbacks and find nextSoonestTimeoutTime - var currentCallbackConfig = headOfPendingCallbacksLinkedList; - while (currentCallbackConfig !== null) { - var _timeoutTime = currentCallbackConfig.timeoutTime; - if (_timeoutTime !== -1 && _timeoutTime <= currentTime) { - // it has timed out! - timedOutCallbacks.push(currentCallbackConfig); - } else { - if (_timeoutTime !== -1 && (updatedNextSoonestTimeoutTime === -1 || _timeoutTime < updatedNextSoonestTimeoutTime)) { - updatedNextSoonestTimeoutTime = _timeoutTime; - } - } - currentCallbackConfig = currentCallbackConfig.next; - } - - if (timedOutCallbacks.length > 0) { - frameDeadlineObject.didTimeout = true; - for (var i = 0, len = timedOutCallbacks.length; i < len; i++) { - callUnsafely(timedOutCallbacks[i], frameDeadlineObject); - } - } - - // NOTE: we intentionally wait to update the nextSoonestTimeoutTime until - // after successfully calling any timed out callbacks. - nextSoonestTimeoutTime = updatedNextSoonestTimeoutTime; - }; - - // We use the postMessage trick to defer idle work until after the repaint. - var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2); - var idleTick = function (event) { - if (event.source !== window || event.data !== messageKey) { - return; - } - isIdleScheduled = false; - - if (headOfPendingCallbacksLinkedList === null) { - return; - } - - // First call anything which has timed out, until we have caught up. - callTimedOutCallbacks(); - - var currentTime = now$1(); - // Next, as long as we have idle time, try calling more callbacks. - while (frameDeadline - currentTime > 0 && headOfPendingCallbacksLinkedList !== null) { - var latestCallbackConfig = headOfPendingCallbacksLinkedList; - frameDeadlineObject.didTimeout = false; - // callUnsafely will remove it from the head of the linked list - callUnsafely(latestCallbackConfig, frameDeadlineObject); - currentTime = now$1(); - } - if (headOfPendingCallbacksLinkedList !== null) { - if (!isAnimationFrameScheduled) { - // Schedule another animation callback so we retry later. - isAnimationFrameScheduled = true; - localRequestAnimationFrame(animationTick); - } - } - }; - // Assumes that we have addEventListener in this environment. Might need - // something better for old IE. - window.addEventListener('message', idleTick, false); - - var animationTick = function (rafTime) { - isAnimationFrameScheduled = false; - var nextFrameTime = rafTime - frameDeadline + activeFrameTime; - if (nextFrameTime < activeFrameTime && previousFrameTime < activeFrameTime) { - if (nextFrameTime < 8) { - // Defensive coding. We don't support higher frame rates than 120hz. - // If we get lower than that, it is probably a bug. - nextFrameTime = 8; - } - // If one frame goes long, then the next one can be short to catch up. - // If two frames are short in a row, then that's an indication that we - // actually have a higher frame rate than what we're currently optimizing. - // We adjust our heuristic dynamically accordingly. For example, if we're - // running on 120hz display or 90hz VR display. - // Take the max of the two in case one of them was an anomaly due to - // missed frame deadlines. - activeFrameTime = nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime; - } else { - previousFrameTime = nextFrameTime; - } - frameDeadline = rafTime + activeFrameTime; - if (!isIdleScheduled) { - isIdleScheduled = true; - window.postMessage(messageKey, '*'); - } - }; - - scheduleWork = function (callback, options) /* CallbackConfigType */{ - var timeoutTime = -1; - if (options != null && typeof options.timeout === 'number') { - timeoutTime = now$1() + options.timeout; - } - if (nextSoonestTimeoutTime === -1 || timeoutTime !== -1 && timeoutTime < nextSoonestTimeoutTime) { - nextSoonestTimeoutTime = timeoutTime; - } - - var scheduledCallbackConfig = { - scheduledCallback: callback, - timeoutTime: timeoutTime, - prev: null, - next: null - }; - if (headOfPendingCallbacksLinkedList === null) { - // Make this callback the head and tail of our list - headOfPendingCallbacksLinkedList = scheduledCallbackConfig; - tailOfPendingCallbacksLinkedList = scheduledCallbackConfig; - } else { - // Add latest callback as the new tail of the list - scheduledCallbackConfig.prev = tailOfPendingCallbacksLinkedList; - // renaming for clarity - var oldTailOfPendingCallbacksLinkedList = tailOfPendingCallbacksLinkedList; - if (oldTailOfPendingCallbacksLinkedList !== null) { - oldTailOfPendingCallbacksLinkedList.next = scheduledCallbackConfig; - } - tailOfPendingCallbacksLinkedList = scheduledCallbackConfig; - } - - if (!isAnimationFrameScheduled) { - // If rAF didn't already schedule one, we need to schedule a frame. - // TODO: If this rAF doesn't materialize because the browser throttles, we - // might want to still have setTimeout trigger scheduleWork as a backup to ensure - // that we keep performing work. - isAnimationFrameScheduled = true; - localRequestAnimationFrame(animationTick); - } - return scheduledCallbackConfig; - }; - - cancelScheduledWork = function (callbackConfig /* CallbackConfigType */ - ) { - if (callbackConfig.prev === null && headOfPendingCallbacksLinkedList !== callbackConfig) { - // this callbackConfig has already been cancelled. - // cancelScheduledWork should be idempotent, a no-op after first call. - return; - } - - /** - * There are four possible cases: - * - Head/nodeToRemove/Tail -> null - * In this case we set Head and Tail to null. - * - Head -> ... middle nodes... -> Tail/nodeToRemove - * In this case we point the middle.next to null and put middle as the new - * Tail. - * - Head/nodeToRemove -> ...middle nodes... -> Tail - * In this case we point the middle.prev at null and move the Head to - * middle. - * - Head -> ... ?some nodes ... -> nodeToRemove -> ... ?some nodes ... -> Tail - * In this case we point the Head.next to the Tail and the Tail.prev to - * the Head. - */ - var next = callbackConfig.next; - var prev = callbackConfig.prev; - callbackConfig.next = null; - callbackConfig.prev = null; - if (next !== null) { - // we have a next - - if (prev !== null) { - // we have a prev - - // callbackConfig is somewhere in the middle of a list of 3 or more nodes. - prev.next = next; - next.prev = prev; - return; - } else { - // there is a next but not a previous one; - // callbackConfig is the head of a list of 2 or more other nodes. - next.prev = null; - headOfPendingCallbacksLinkedList = next; - return; - } - } else { - // there is no next callback config; this must the tail of the list - - if (prev !== null) { - // we have a prev - - // callbackConfig is the tail of a list of 2 or more other nodes. - prev.next = null; - tailOfPendingCallbacksLinkedList = prev; - return; - } else { - // there is no previous callback config; - // callbackConfig is the only thing in the linked list, - // so both head and tail point to it. - headOfPendingCallbacksLinkedList = null; - tailOfPendingCallbacksLinkedList = null; - return; - } - } - }; -} - var didWarnSelectedSetOnOption = false; +var didWarnInvalidChild = false; function flattenChildren(children) { var content = ''; - // Flatten children and warn if they aren't strings or numbers; - // invalid types are ignored. - // We can silently skip them because invalid DOM nesting warning - // catches these cases in Fiber. + // Flatten children. We'll warn if they are invalid + // during validateProps() which runs for hydration too. + // Note that this would throw on non-element objects. + // Elements are stringified (which is normally irrelevant + // but matters for ). React.Children.forEach(children, function (child) { if (child == null) { return; } - if (typeof child === 'string' || typeof child === 'number') { - content += child; - } + content += child; + // Note: we don't warn about invalid children here. + // Instead, this is done separately below so that + // it happens during the hydration codepath too. }); return content; @@ -12242,10 +11781,32 @@ function flattenChildren(children) { */ function validateProps(element, props) { - // TODO (yungsters): Remove support for `selected` in