gecko-dev/devtools/client/shared/vendor/react-dom-server.js

2189 строки
70 KiB
JavaScript

/** @license React v16.8.6
* react-dom-server.browser.production.min.js
*
* 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.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('devtools/client/shared/vendor/react')) :
typeof define === 'function' && define.amd ? define(['devtools/client/shared/vendor/react'], factory) :
(global.ReactDOMServer = factory(global.React));
}(this, (function (React) { '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.
*/
function invariant(condition, format, a, b, c, d, e, f) {
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
// preserve the format and params in the www builds.
/**
* WARNING: DO NOT manually require this module.
* This is a replacement for `invariant(...)` used by the error code system
* and will _only_ be required by the corresponding babel pass.
* It always throws.
*/
function reactProdInvariant(code) {
var argCount = arguments.length - 1;
var url = 'https://reactjs.org/docs/error-decoder.html?invariant=' + code;
for (var argIdx = 0; argIdx < argCount; argIdx++) {
url += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]);
}
// Rename it so that our build transform doesn't attempt
// to replace this invariant() call with reactProdInvariant().
var i = invariant;
i(false,
// The error code is intentionally part of the message (and
// not the format argument) so that we could deduplicate
// different errors in logs based on the code.
'Minified React error #' + code + '; visit %s ' + 'for the full message or use the non-minified dev environment ' + 'for full errors and additional helpful warnings. ', url);
}
// TODO: this is special because it gets imported during build.
var ReactVersion = '16.8.6';
var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
var _assign = ReactInternals.assign;
/**
* 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.
*/
// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
// nor polyfill, then a plain number is used for performance.
var hasSymbol = typeof Symbol === 'function' && Symbol.for;
var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
var Resolved = 1;
function refineResolvedLazyComponent(lazyComponent) {
return lazyComponent._status === Resolved ? lazyComponent._result : null;
}
function getWrappedName(outerType, innerType, wrapperName) {
var functionName = innerType.displayName || innerType.name || '';
return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
}
function getComponentName(type) {
if (type == null) {
// Host root, text node or just invalid type.
return null;
}
if (typeof type === 'function') {
return type.displayName || type.name || null;
}
if (typeof type === 'string') {
return type;
}
switch (type) {
case REACT_CONCURRENT_MODE_TYPE:
return 'ConcurrentMode';
case REACT_FRAGMENT_TYPE:
return 'Fragment';
case REACT_PORTAL_TYPE:
return 'Portal';
case REACT_PROFILER_TYPE:
return 'Profiler';
case REACT_STRICT_MODE_TYPE:
return 'StrictMode';
case REACT_SUSPENSE_TYPE:
return 'Suspense';
}
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:
return getWrappedName(type, type.render, 'ForwardRef');
case REACT_MEMO_TYPE:
return getComponentName(type.type);
case REACT_LAZY_TYPE:
{
var thenable = type;
var resolvedThenable = refineResolvedLazyComponent(thenable);
if (resolvedThenable) {
return getComponentName(resolvedThenable);
}
}
}
}
return null;
}
/**
* Forked from fbjs/warning:
* https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
*
* Only change is we use console.warn instead of console.error,
* and do nothing when 'console' is not supported.
* This really simplifies the code.
* ---
* 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 ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
// Prevent newer renderers from RTE when used with older react package versions.
// Current owner and dispatcher used to share the same ref,
// but PR #14548 split them out to better support the react-debug-tools package.
if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
ReactSharedInternals.ReactCurrentDispatcher = {
current: null
};
}
// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
// 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:
// To preserve the "Pause on caught exceptions" behavior of the debugger, we
// replay the begin phase of a failed component inside invokeGuardedCallback.
// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
// Gather advanced timing metrics for Profiler subtrees.
// Trace which interactions trigger each commit.
// Only used in www builds.
var enableSuspenseServerRenderer = false; // TODO: false? Here it might just be false.
// 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
// These APIs will no longer be "unstable" in the upcoming 16.7 release,
// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
/**
* 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 emptyObject = {};
function maskContext(type, context) {
var contextTypes = type.contextTypes;
if (!contextTypes) {
return emptyObject;
}
var maskedContext = {};
for (var contextName in contextTypes) {
maskedContext[contextName] = context[contextName];
}
return maskedContext;
}
function validateContextBounds(context, threadID) {
// If we don't have enough slots in this context to store this threadID,
// fill it in without leaving any holes to ensure that the VM optimizes
// this as non-holey index properties.
// (Note: If `react` package is < 16.6, _threadCount is undefined.)
for (var i = context._threadCount | 0; i <= threadID; i++) {
// We assume that this is the same as the defaultValue which might not be
// true if we're rendering inside a secondary renderer but they are
// secondary because these use cases are very rare.
context[i] = context._currentValue2;
context._threadCount = i + 1;
}
}
function processContext(type, context, threadID) {
var contextType = type.contextType;
if (typeof contextType === 'object' && contextType !== null) {
validateContextBounds(contextType, threadID);
return contextType[threadID];
} else {
var maskedContext = maskContext(type, context);
return maskedContext;
}
}
// Allocates a new index for each request. Tries to stay as compact as possible so that these
// indices can be used to reference a tightly packaged array. As opposed to being used in a Map.
// The first allocated index is 1.
var nextAvailableThreadIDs = new Uint16Array(16);
for (var i = 0; i < 15; i++) {
nextAvailableThreadIDs[i] = i + 1;
}
nextAvailableThreadIDs[15] = 0;
function growThreadCountAndReturnNextAvailable() {
var oldArray = nextAvailableThreadIDs;
var oldSize = oldArray.length;
var newSize = oldSize * 2;
!(newSize <= 0x10000) ? reactProdInvariant('304') : void 0;
var newArray = new Uint16Array(newSize);
newArray.set(oldArray);
nextAvailableThreadIDs = newArray;
nextAvailableThreadIDs[0] = oldSize + 1;
for (var _i = oldSize; _i < newSize - 1; _i++) {
nextAvailableThreadIDs[_i] = _i + 1;
}
nextAvailableThreadIDs[newSize - 1] = 0;
return oldSize;
}
function allocThreadID() {
var nextID = nextAvailableThreadIDs[0];
if (nextID === 0) {
return growThreadCountAndReturnNextAvailable();
}
nextAvailableThreadIDs[0] = nextAvailableThreadIDs[nextID];
return nextID;
}
function freeThreadID(id) {
nextAvailableThreadIDs[id] = nextAvailableThreadIDs[0];
nextAvailableThreadIDs[0] = id;
}
// A reserved attribute.
// It is handled by React separately and shouldn't be written to the DOM.
var RESERVED = 0;
// A simple string attribute.
// Attributes that aren't in the whitelist are presumed to have this type.
var STRING = 1;
// A string attribute that accepts booleans in React. In HTML, these are called
// "enumerated" attributes with "true" and "false" as possible values.
// When true, it should be set to a "true" string.
// When false, it should be set to a "false" string.
var BOOLEANISH_STRING = 2;
// A real boolean attribute.
// When true, it should be present (set either to an empty string or its name).
// When false, it should be omitted.
var BOOLEAN = 3;
// An attribute that can be used as a flag as well as with a value.
// When true, it should be present (set either to an empty string or its name).
// When false, it should be omitted.
// For any other value, should be present with that value.
var OVERLOADED_BOOLEAN = 4;
// An attribute that must be numeric or parse as a numeric.
// When falsy, it should be removed.
var NUMERIC = 5;
// An attribute that must be positive numeric or parse as a positive numeric.
// When falsy, it should be removed.
var POSITIVE_NUMERIC = 6;
/* eslint-disable max-len */
var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';
/* eslint-enable max-len */
var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
var illegalAttributeNameCache = {};
var validatedAttributeNameCache = {};
function isAttributeNameSafe(attributeName) {
if (hasOwnProperty$1.call(validatedAttributeNameCache, attributeName)) {
return true;
}
if (hasOwnProperty$1.call(illegalAttributeNameCache, attributeName)) {
return false;
}
if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
validatedAttributeNameCache[attributeName] = true;
return true;
}
illegalAttributeNameCache[attributeName] = true;
return false;
}
function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
if (propertyInfo !== null) {
return propertyInfo.type === RESERVED;
}
if (isCustomComponentTag) {
return false;
}
if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
return true;
}
return false;
}
function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
if (propertyInfo !== null && propertyInfo.type === RESERVED) {
return false;
}
switch (typeof value) {
case 'function':
// $FlowIssue symbol is perfectly valid here
case 'symbol':
// eslint-disable-line
return true;
case 'boolean':
{
if (isCustomComponentTag) {
return false;
}
if (propertyInfo !== null) {
return !propertyInfo.acceptsBooleans;
} else {
var prefix = name.toLowerCase().slice(0, 5);
return prefix !== 'data-' && prefix !== 'aria-';
}
}
default:
return false;
}
}
function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
if (value === null || typeof value === 'undefined') {
return true;
}
if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
return true;
}
if (isCustomComponentTag) {
return false;
}
if (propertyInfo !== null) {
switch (propertyInfo.type) {
case BOOLEAN:
return !value;
case OVERLOADED_BOOLEAN:
return value === false;
case NUMERIC:
return isNaN(value);
case POSITIVE_NUMERIC:
return isNaN(value) || value < 1;
}
}
return false;
}
function getPropertyInfo(name) {
return properties.hasOwnProperty(name) ? properties[name] : null;
}
function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
this.attributeName = attributeName;
this.attributeNamespace = attributeNamespace;
this.mustUseProperty = mustUseProperty;
this.propertyName = name;
this.type = type;
}
// When adding attributes to this list, be sure to also add them to
// the `possibleStandardNames` module to ensure casing and incorrect
// name warnings.
var properties = {};
// These props are reserved by React. They shouldn't be written to the DOM.
['children', 'dangerouslySetInnerHTML',
// TODO: This prevents the assignment of defaultValue to regular
// elements (not just inputs). Now that ReactDOMInput assigns to the
// defaultValue property -- do we need this?
'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
name, // attributeName
null);
} // attributeNamespace
);
// A few React string attributes have a different name.
// This is a mapping from React prop names to the attribute names.
[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
var name = _ref[0],
attributeName = _ref[1];
properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
attributeName, // attributeName
null);
} // attributeNamespace
);
// These are "enumerated" HTML attributes that accept "true" and "false".
// In React, we let users pass `true` and `false` even though technically
// these aren't boolean attributes (they are coerced to strings).
['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
name.toLowerCase(), // attributeName
null);
} // attributeNamespace
);
// These are "enumerated" SVG attributes that accept "true" and "false".
// 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', 'focusable', 'preserveAlpha'].forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
name, // attributeName
null);
} // attributeNamespace
);
// These are HTML boolean attributes.
['allowFullScreen', 'async',
// Note: there is a special case that prevents it from being written to the DOM
// on the client side because the browsers are inconsistent. Instead we call focus().
'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
// Microdata
'itemScope'].forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
name.toLowerCase(), // attributeName
null);
} // attributeNamespace
);
// These are the few React props that we set as DOM properties
// rather than attributes. These are all booleans.
['checked',
// Note: `option.selected` is not updated if `select.multiple` is
// 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, // attributeName
null);
} // attributeNamespace
);
// These are HTML attributes that are "overloaded booleans": they behave like
// booleans, but can also accept a string value.
['capture', 'download'].forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
name, // attributeName
null);
} // attributeNamespace
);
// 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, // attributeName
null);
} // attributeNamespace
);
// These are HTML attributes that must be numbers.
['rowSpan', 'start'].forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
name.toLowerCase(), // attributeName
null);
} // attributeNamespace
);
var CAMELIZE = /[\-\:]([a-z])/g;
var capitalize = function (token) {
return token[1].toUpperCase();
};
// This is a list of all SVG attributes that need special casing, namespacing,
// or boolean value assignment. Regular attributes that just accept strings
// and have the same names are omitted, just like in the HTML whitelist.
// Some of these attributes can be hard to find. This list was created by
// scrapping the MDN documentation.
['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height'].forEach(function (attributeName) {
var name = attributeName.replace(CAMELIZE, capitalize);
properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
attributeName, null);
} // attributeNamespace
);
// String SVG attributes with the xlink namespace.
['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
var name = attributeName.replace(CAMELIZE, capitalize);
properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
attributeName, 'http://www.w3.org/1999/xlink');
});
// String SVG attributes with the xml namespace.
['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
var name = attributeName.replace(CAMELIZE, capitalize);
properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
attributeName, 'http://www.w3.org/XML/1998/namespace');
});
// These attribute exists both in HTML and SVG.
// The attribute name is case-sensitive in SVG so we can't just use
// the React name like we do for attributes that exist only in HTML.
['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
attributeName.toLowerCase(), // attributeName
null);
} // attributeNamespace
);
// code copied and modified from escape-html
/**
* Module variables.
* @private
*/
var matchHtmlRegExp = /["'&<>]/;
/**
* Escapes special characters and HTML entities in a given html string.
*
* @param {string} string HTML string to escape for later insertion
* @return {string}
* @public
*/
function escapeHtml(string) {
var str = '' + string;
var match = matchHtmlRegExp.exec(str);
if (!match) {
return str;
}
var escape = void 0;
var html = '';
var index = void 0;
var lastIndex = 0;
for (index = match.index; index < str.length; index++) {
switch (str.charCodeAt(index)) {
case 34:
// "
escape = '&quot;';
break;
case 38:
// &
escape = '&amp;';
break;
case 39:
// '
escape = '&#x27;'; // modified from escape-html; used to be '&#39'
break;
case 60:
// <
escape = '&lt;';
break;
case 62:
// >
escape = '&gt;';
break;
default:
continue;
}
if (lastIndex !== index) {
html += str.substring(lastIndex, index);
}
lastIndex = index + 1;
html += escape;
}
return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
}
// end code copied and modified from escape-html
/**
* Escapes text to prevent scripting attacks.
*
* @param {*} text Text value to escape.
* @return {string} An escaped string.
*/
function escapeTextForBrowser(text) {
if (typeof text === 'boolean' || typeof text === 'number') {
// this shortcircuit helps perf for types that we know will never have
// special characters, especially given that this function is used often
// for numeric dom ids.
return '' + text;
}
return escapeHtml(text);
}
/**
* Escapes attribute value to prevent scripting attacks.
*
* @param {*} value Value to escape.
* @return {string} An escaped string.
*/
function quoteAttributeValueForBrowser(value) {
return '"' + escapeTextForBrowser(value) + '"';
}
/**
* Operations for dealing with DOM properties.
*/
/**
* Creates markup for the ID property.
*
* @param {string} id Unescaped ID.
* @return {string} Markup string.
*/
function createMarkupForRoot() {
return ROOT_ATTRIBUTE_NAME + '=""';
}
/**
* Creates markup for a property.
*
* @param {string} name
* @param {*} value
* @return {?string} Markup string, or null if the property was invalid.
*/
function createMarkupForProperty(name, value) {
var propertyInfo = getPropertyInfo(name);
if (name !== 'style' && shouldIgnoreAttribute(name, propertyInfo, false)) {
return '';
}
if (shouldRemoveAttribute(name, value, propertyInfo, false)) {
return '';
}
if (propertyInfo !== null) {
var attributeName = propertyInfo.attributeName;
var type = propertyInfo.type;
if (type === BOOLEAN || type === OVERLOADED_BOOLEAN && value === true) {
return attributeName + '=""';
} else {
return attributeName + '=' + quoteAttributeValueForBrowser(value);
}
} else if (isAttributeNameSafe(name)) {
return name + '=' + quoteAttributeValueForBrowser(value);
}
return '';
}
/**
* Creates markup for a custom property.
*
* @param {string} name
* @param {*} value
* @return {string} Markup string, or empty string if the property was invalid.
*/
function createMarkupForCustomAttribute(name, value) {
if (!isAttributeNameSafe(name) || value == null) {
return '';
}
return name + '=' + quoteAttributeValueForBrowser(value);
}
/**
* 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) {
return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
;
}
var currentlyRenderingComponent = null;
var firstWorkInProgressHook = null;
var workInProgressHook = null;
// Whether the work-in-progress hook is a re-rendered hook
var isReRender = false;
// Whether an update was scheduled during the currently executing render pass.
var didScheduleRenderPhaseUpdate = false;
// Lazily created map of render-phase updates
var renderPhaseUpdates = null;
// Counter to prevent infinite loops.
var numberOfReRenders = 0;
var RE_RENDER_LIMIT = 25;
function resolveCurrentlyRenderingComponent() {
!(currentlyRenderingComponent !== null) ? reactProdInvariant('321') : void 0;
return currentlyRenderingComponent;
}
function areHookInputsEqual(nextDeps, prevDeps) {
if (prevDeps === null) {
return false;
}
for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
if (is(nextDeps[i], prevDeps[i])) {
continue;
}
return false;
}
return true;
}
function createHook() {
if (numberOfReRenders > 0) {
reactProdInvariant('312');
}
return {
memoizedState: null,
queue: null,
next: null
};
}
function createWorkInProgressHook() {
if (workInProgressHook === null) {
// This is the first hook in the list
if (firstWorkInProgressHook === null) {
isReRender = false;
firstWorkInProgressHook = workInProgressHook = createHook();
} else {
// There's already a work-in-progress. Reuse it.
isReRender = true;
workInProgressHook = firstWorkInProgressHook;
}
} else {
if (workInProgressHook.next === null) {
isReRender = false;
// Append to the end of the list
workInProgressHook = workInProgressHook.next = createHook();
} else {
// There's already a work-in-progress. Reuse it.
isReRender = true;
workInProgressHook = workInProgressHook.next;
}
}
return workInProgressHook;
}
function prepareToUseHooks(componentIdentity) {
currentlyRenderingComponent = componentIdentity;
// The following should have already been reset
// didScheduleRenderPhaseUpdate = false;
// firstWorkInProgressHook = null;
// numberOfReRenders = 0;
// renderPhaseUpdates = null;
// workInProgressHook = null;
}
function finishHooks(Component, props, children, refOrContext) {
// This must be called after every function component to prevent hooks from
// being used in classes.
while (didScheduleRenderPhaseUpdate) {
// Updates were scheduled during the render phase. They are stored in
// the `renderPhaseUpdates` map. Call the component again, reusing the
// work-in-progress hooks and applying the additional updates on top. Keep
// restarting until no more updates are scheduled.
didScheduleRenderPhaseUpdate = false;
numberOfReRenders += 1;
// Start over from the beginning of the list
workInProgressHook = null;
children = Component(props, refOrContext);
}
currentlyRenderingComponent = null;
firstWorkInProgressHook = null;
numberOfReRenders = 0;
renderPhaseUpdates = null;
workInProgressHook = null;
return children;
}
function readContext(context, observedBits) {
var threadID = currentThreadID;
validateContextBounds(context, threadID);
return context[threadID];
}
function useContext(context, observedBits) {
resolveCurrentlyRenderingComponent();
var threadID = currentThreadID;
validateContextBounds(context, threadID);
return context[threadID];
}
function basicStateReducer(state, action) {
return typeof action === 'function' ? action(state) : action;
}
function useState(initialState) {
return useReducer(basicStateReducer,
// useReducer has a special case to support lazy useState initializers
initialState);
}
function useReducer(reducer, initialArg, init) {
currentlyRenderingComponent = resolveCurrentlyRenderingComponent();
workInProgressHook = createWorkInProgressHook();
if (isReRender) {
// This is a re-render. Apply the new render phase updates to the previous
var _queue = workInProgressHook.queue;
var _dispatch = _queue.dispatch;
if (renderPhaseUpdates !== null) {
// Render phase updates are stored in a map of queue -> linked list
var firstRenderPhaseUpdate = renderPhaseUpdates.get(_queue);
if (firstRenderPhaseUpdate !== undefined) {
renderPhaseUpdates.delete(_queue);
var newState = workInProgressHook.memoizedState;
var update = firstRenderPhaseUpdate;
do {
// Process this render phase update. We don't have to check the
// priority because it will always be the same as the current
// render's.
var _action = update.action;
newState = reducer(newState, _action);
update = update.next;
} while (update !== null);
workInProgressHook.memoizedState = newState;
return [newState, _dispatch];
}
}
return [workInProgressHook.memoizedState, _dispatch];
} else {
var initialState = void 0;
if (reducer === basicStateReducer) {
// Special case for `useState`.
initialState = typeof initialArg === 'function' ? initialArg() : initialArg;
} else {
initialState = init !== undefined ? init(initialArg) : initialArg;
}
workInProgressHook.memoizedState = initialState;
var _queue2 = workInProgressHook.queue = {
last: null,
dispatch: null
};
var _dispatch2 = _queue2.dispatch = dispatchAction.bind(null, currentlyRenderingComponent, _queue2);
return [workInProgressHook.memoizedState, _dispatch2];
}
}
function useMemo(nextCreate, deps) {
currentlyRenderingComponent = resolveCurrentlyRenderingComponent();
workInProgressHook = createWorkInProgressHook();
var nextDeps = deps === undefined ? null : deps;
if (workInProgressHook !== null) {
var prevState = workInProgressHook.memoizedState;
if (prevState !== null) {
if (nextDeps !== null) {
var prevDeps = prevState[1];
if (areHookInputsEqual(nextDeps, prevDeps)) {
return prevState[0];
}
}
}
}
var nextValue = nextCreate();
workInProgressHook.memoizedState = [nextValue, nextDeps];
return nextValue;
}
function useRef(initialValue) {
currentlyRenderingComponent = resolveCurrentlyRenderingComponent();
workInProgressHook = createWorkInProgressHook();
var previousRef = workInProgressHook.memoizedState;
if (previousRef === null) {
var ref = { current: initialValue };
workInProgressHook.memoizedState = ref;
return ref;
} else {
return previousRef;
}
}
function useLayoutEffect(create, inputs) {
}
function dispatchAction(componentIdentity, queue, action) {
!(numberOfReRenders < RE_RENDER_LIMIT) ? reactProdInvariant('301') : void 0;
if (componentIdentity === currentlyRenderingComponent) {
// This is a render phase update. Stash it in a lazily-created map of
// queue -> linked list of updates. After this render pass, we'll restart
// and apply the stashed updates on top of the work-in-progress hook.
didScheduleRenderPhaseUpdate = true;
var update = {
action: action,
next: null
};
if (renderPhaseUpdates === null) {
renderPhaseUpdates = new Map();
}
var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
if (firstRenderPhaseUpdate === undefined) {
renderPhaseUpdates.set(queue, update);
} else {
// Append the update to the end of the list.
var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
while (lastRenderPhaseUpdate.next !== null) {
lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
}
lastRenderPhaseUpdate.next = update;
}
} else {
// This means an update has happened after the function component has
// returned. On the server this is a no-op. In React Fiber, the update
// would be scheduled for a future render.
}
}
function useCallback(callback, deps) {
// Callbacks are passed as they are in the server environment.
return callback;
}
function noop() {}
var currentThreadID = 0;
function setCurrentThreadID(threadID) {
currentThreadID = threadID;
}
var Dispatcher = {
readContext: readContext,
useContext: useContext,
useMemo: useMemo,
useReducer: useReducer,
useRef: useRef,
useState: useState,
useLayoutEffect: useLayoutEffect,
useCallback: useCallback,
// useImperativeHandle is not run in the server environment
useImperativeHandle: noop,
// Effects are not run in the server environment.
useEffect: noop,
// Debugging effect
useDebugValue: noop
};
var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
var Namespaces = {
html: HTML_NAMESPACE,
mathml: MATH_NAMESPACE,
svg: SVG_NAMESPACE
};
// Assumes there is no parent namespace.
function getIntrinsicNamespace(type) {
switch (type) {
case 'svg':
return SVG_NAMESPACE;
case 'math':
return MATH_NAMESPACE;
default:
return HTML_NAMESPACE;
}
}
function getChildNamespace(parentNamespace, type) {
if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
// No (or default) parent namespace: potential entry point.
return getIntrinsicNamespace(type);
}
if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
// We're leaving SVG.
return HTML_NAMESPACE;
}
// By default, pass namespace below.
return parentNamespace;
}
// For HTML, certain tags should omit their close tag. We keep a whitelist for
// those special-case tags.
var omittedCloseTags = {
area: true,
base: true,
br: true,
col: true,
embed: true,
hr: true,
img: true,
input: true,
keygen: true,
link: true,
meta: true,
param: true,
source: true,
track: true,
wbr: true
// NOTE: menuitem's close tag should be omitted, but that causes problems.
};
// For HTML, certain tags cannot have children. This has the same purpose as
// `omittedCloseTags` except that `menuitem` should still have its closing tag.
var voidElementTags = _assign({
menuitem: true
}, omittedCloseTags);
// TODO: We can remove this if we add invariantWithStack()
// or add stack by default to invariants where possible.
var HTML = '__html';
function assertValidProps(tag, props) {
if (!props) {
return;
}
// Note the use of `==` which checks for null or undefined.
if (voidElementTags[tag]) {
!(props.children == null && props.dangerouslySetInnerHTML == null) ? reactProdInvariant('137', tag, '') : void 0;
}
if (props.dangerouslySetInnerHTML != null) {
!(props.children == null) ? reactProdInvariant('60') : void 0;
!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? reactProdInvariant('61') : void 0;
}
!(props.style == null || typeof props.style === 'object') ? reactProdInvariant('62', '') : void 0;
}
/**
* CSS properties which accept numbers but are not in units of "px".
*/
var isUnitlessNumber = {
animationIterationCount: true,
borderImageOutset: true,
borderImageSlice: true,
borderImageWidth: true,
boxFlex: true,
boxFlexGroup: true,
boxOrdinalGroup: true,
columnCount: true,
columns: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
flexOrder: true,
gridArea: true,
gridRow: true,
gridRowEnd: true,
gridRowSpan: true,
gridRowStart: true,
gridColumn: true,
gridColumnEnd: true,
gridColumnSpan: true,
gridColumnStart: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
// SVG-related properties
fillOpacity: true,
floodOpacity: true,
stopOpacity: true,
strokeDasharray: true,
strokeDashoffset: true,
strokeMiterlimit: true,
strokeOpacity: true,
strokeWidth: true
};
/**
* @param {string} prefix vendor-specific prefix, eg: Webkit
* @param {string} key style name, eg: transitionDuration
* @return {string} style name prefixed with `prefix`, properly camelCased, eg:
* WebkitTransitionDuration
*/
function prefixKey(prefix, key) {
return prefix + key.charAt(0).toUpperCase() + key.substring(1);
}
/**
* Support style names that may come passed in prefixed by adding permutations
* of vendor prefixes.
*/
var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
// infinite loop, because it iterates over the newly added props too.
Object.keys(isUnitlessNumber).forEach(function (prop) {
prefixes.forEach(function (prefix) {
isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
});
});
/**
* Convert a value into the proper css writable value. The style name `name`
* should be logical (no hyphens), as specified
* in `CSSProperty.isUnitlessNumber`.
*
* @param {string} name CSS property name such as `topMargin`.
* @param {*} value CSS property value such as `10px`.
* @return {string} Normalized style value with dimensions applied.
*/
function dangerousStyleValue(name, value, isCustomProperty) {
// Note that we've removed escapeTextForBrowser() calls here since the
// whole string will be escaped when the attribute is injected into
// the markup. If you provide unsafe user data here they can inject
// arbitrary CSS which may be problematic (I couldn't repro this):
// https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
// http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
// This is not an XSS hole but instead a potential CSS injection issue
// which has lead to a greater discussion about how we're going to
// trust URLs moving forward. See #2115901
var isEmpty = value == null || typeof value === 'boolean' || value === '';
if (isEmpty) {
return '';
}
if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
}
return ('' + value).trim();
}
var uppercasePattern = /([A-Z])/g;
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-`.
*/
function hyphenateStyleName(name) {
return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
}
function isCustomComponent(tagName, props) {
if (tagName.indexOf('-') === -1) {
return typeof props.is === 'string';
}
switch (tagName) {
// These are reserved SVG and MathML elements.
// We don't mind this whitelist too much because we expect it to never grow.
// The alternative is to track the namespace in a few places which is convoluted.
// https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
case 'annotation-xml':
case 'color-profile':
case 'font-face':
case 'font-face-src':
case 'font-face-uri':
case 'font-face-format':
case 'font-face-name':
case 'missing-glyph':
return false;
default:
return true;
}
}
/**
* Registers plugins so that they can extract and dispatch events.
*
* @see {EventPluginHub}
*/
/**
* Ordered list of injected plugins.
*/
/**
* Mapping from event name to dispatch config
*/
/**
* Mapping from registration name to plugin module
*/
/**
* Mapping from registration name to event name
*/
/**
* Mapping from lowercase registration names to the properly cased version,
* used to warn in the case of missing event handlers. Available
* only in false.
* @type {Object}
*/
// Trust the developer to only use possibleRegistrationNames in false
/**
* Injects an ordering of plugins (by plugin name). This allows the ordering
* to be decoupled from injection of the actual plugins so that ordering is
* always deterministic regardless of packaging, on-the-fly injection, etc.
*
* @param {array} InjectedEventPluginOrder
* @internal
* @see {EventPluginHub.injection.injectEventPluginOrder}
*/
/**
* Injects plugins to be used by `EventPluginHub`. The plugin names must be
* in the ordering injected by `injectEventPluginOrder`.
*
* Plugins can be injected as part of page initialization or on-the-fly.
*
* @param {object} injectedNamesToPlugins Map from names to plugin modules.
* @internal
* @see {EventPluginHub.injection.injectEventPluginsByName}
*/
// When adding attributes to the HTML or SVG whitelist, be sure to
// also add them to this module to ensure casing and incorrect name
// warnings.
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
// Based on reading the React.Children implementation. TODO: type this somewhere?
var toArray = React.Children.toArray;
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
var newlineEatingTags = {
listing: true,
pre: true,
textarea: true
};
// We accept any tag to be rendered but since this gets injected into arbitrary
// HTML, we want to make sure that it's a safe tag.
// http://www.w3.org/TR/REC-xml/#NT-Name
var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset
var validatedTagCache = {};
function validateDangerousTag(tag) {
if (!validatedTagCache.hasOwnProperty(tag)) {
!VALID_TAG_REGEX.test(tag) ? reactProdInvariant('65', tag) : void 0;
validatedTagCache[tag] = true;
}
}
var styleNameCache = {};
var processStyleName = function (styleName) {
if (styleNameCache.hasOwnProperty(styleName)) {
return styleNameCache[styleName];
}
var result = hyphenateStyleName(styleName);
styleNameCache[styleName] = result;
return result;
};
function createMarkupForStyles(styles) {
var serialized = '';
var delimiter = '';
for (var styleName in styles) {
if (!styles.hasOwnProperty(styleName)) {
continue;
}
var isCustomProperty = styleName.indexOf('--') === 0;
var styleValue = styles[styleName];
if (styleValue != null) {
serialized += delimiter + processStyleName(styleName) + ':';
serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
delimiter = ';';
}
}
return serialized || null;
}
function shouldConstruct(Component) {
return Component.prototype && Component.prototype.isReactComponent;
}
function getNonChildrenInnerMarkup(props) {
var innerHTML = props.dangerouslySetInnerHTML;
if (innerHTML != null) {
if (innerHTML.__html != null) {
return innerHTML.__html;
}
} else {
var content = props.children;
if (typeof content === 'string' || typeof content === 'number') {
return escapeTextForBrowser(content);
}
}
return null;
}
function flattenTopLevelChildren(children) {
if (!React.isValidElement(children)) {
return toArray(children);
}
var element = children;
if (element.type !== REACT_FRAGMENT_TYPE) {
return [element];
}
var fragmentChildren = element.props.children;
if (!React.isValidElement(fragmentChildren)) {
return toArray(fragmentChildren);
}
var fragmentChildElement = fragmentChildren;
return [fragmentChildElement];
}
function flattenOptionChildren(children) {
if (children === undefined || children === null) {
return children;
}
var content = '';
// Flatten children and warn if they aren't strings or numbers;
// invalid types are ignored.
React.Children.forEach(children, function (child) {
if (child == null) {
return;
}
content += child;
});
return content;
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
var STYLE = 'style';
var RESERVED_PROPS = {
children: null,
dangerouslySetInnerHTML: null,
suppressContentEditableWarning: null,
suppressHydrationWarning: null
};
function createOpenTagMarkup(tagVerbatim, tagLowercase, props, namespace, makeStaticMarkup, isRootElement) {
var ret = '<' + tagVerbatim;
for (var propKey in props) {
if (!hasOwnProperty.call(props, propKey)) {
continue;
}
var propValue = props[propKey];
if (propValue == null) {
continue;
}
if (propKey === STYLE) {
propValue = createMarkupForStyles(propValue);
}
var markup = null;
if (isCustomComponent(tagLowercase, props)) {
if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
markup = createMarkupForCustomAttribute(propKey, propValue);
}
} else {
markup = createMarkupForProperty(propKey, propValue);
}
if (markup) {
ret += ' ' + markup;
}
}
// For static pages, no need to put React ID and checksum. Saves lots of
// bytes.
if (makeStaticMarkup) {
return ret;
}
if (isRootElement) {
ret += ' ' + createMarkupForRoot();
}
return ret;
}
function validateRenderResult(child, type) {
if (child === undefined) {
reactProdInvariant('152', getComponentName(type) || 'Component');
}
}
function resolve(child, context, threadID) {
while (React.isValidElement(child)) {
// Safe because we just checked it's an element.
var element = child;
var Component = element.type;
if (typeof Component !== 'function') {
break;
}
processChild(element, Component);
}
// Extra closure so queue and replace can be captured properly
function processChild(element, Component) {
var publicContext = processContext(Component, context, threadID);
var queue = [];
var replace = false;
var updater = {
isMounted: function (publicInstance) {
return false;
},
enqueueForceUpdate: function (publicInstance) {
if (queue === null) {
return null;
}
},
enqueueReplaceState: function (publicInstance, completeState) {
replace = true;
queue = [completeState];
},
enqueueSetState: function (publicInstance, currentPartialState) {
if (queue === null) {
return null;
}
queue.push(currentPartialState);
}
};
var inst = void 0;
if (shouldConstruct(Component)) {
inst = new Component(element.props, publicContext, updater);
if (typeof Component.getDerivedStateFromProps === 'function') {
var partialState = Component.getDerivedStateFromProps.call(null, element.props, inst.state);
if (partialState != null) {
inst.state = _assign({}, inst.state, partialState);
}
}
} else {
var componentIdentity = {};
prepareToUseHooks(componentIdentity);
inst = Component(element.props, publicContext, updater);
inst = finishHooks(Component, element.props, inst, publicContext);
if (inst == null || inst.render == null) {
child = inst;
validateRenderResult(child, Component);
return;
}
}
inst.props = element.props;
inst.context = publicContext;
inst.updater = updater;
var initialState = inst.state;
if (initialState === undefined) {
inst.state = initialState = null;
}
if (typeof inst.UNSAFE_componentWillMount === 'function' || typeof inst.componentWillMount === 'function') {
if (typeof inst.componentWillMount === 'function') {
if (typeof Component.getDerivedStateFromProps !== 'function') {
inst.componentWillMount();
}
}
if (typeof inst.UNSAFE_componentWillMount === 'function' && typeof Component.getDerivedStateFromProps !== 'function') {
// In order to support react-lifecycles-compat polyfilled components,
// Unsafe lifecycles should not be invoked for any component with the new gDSFP.
inst.UNSAFE_componentWillMount();
}
if (queue.length) {
var oldQueue = queue;
var oldReplace = replace;
queue = null;
replace = false;
if (oldReplace && oldQueue.length === 1) {
inst.state = oldQueue[0];
} else {
var nextState = oldReplace ? oldQueue[0] : inst.state;
var dontMutate = true;
for (var i = oldReplace ? 1 : 0; i < oldQueue.length; i++) {
var partial = oldQueue[i];
var _partialState = typeof partial === 'function' ? partial.call(inst, nextState, element.props, publicContext) : partial;
if (_partialState != null) {
if (dontMutate) {
dontMutate = false;
nextState = _assign({}, nextState, _partialState);
} else {
_assign(nextState, _partialState);
}
}
}
inst.state = nextState;
}
} else {
queue = null;
}
}
child = inst.render();
validateRenderResult(child, Component);
var childContext = void 0;
if (typeof inst.getChildContext === 'function') {
var childContextTypes = Component.childContextTypes;
if (typeof childContextTypes === 'object') {
childContext = inst.getChildContext();
for (var contextKey in childContext) {
!(contextKey in childContextTypes) ? reactProdInvariant('108', getComponentName(Component) || 'Unknown', contextKey) : void 0;
}
} else {
}
}
if (childContext) {
context = _assign({}, context, childContext);
}
}
return { child: child, context: context };
}
var ReactDOMServerRenderer = function () {
// DEV-only
// TODO: type this more strictly:
function ReactDOMServerRenderer(children, makeStaticMarkup) {
_classCallCheck(this, ReactDOMServerRenderer);
var flatChildren = flattenTopLevelChildren(children);
var topFrame = {
type: null,
// Assume all trees start in the HTML namespace (not totally true, but
// this is what we did historically)
domNamespace: Namespaces.html,
children: flatChildren,
childIndex: 0,
context: emptyObject,
footer: ''
};
this.threadID = allocThreadID();
this.stack = [topFrame];
this.exhausted = false;
this.currentSelectValue = null;
this.previousWasTextNode = false;
this.makeStaticMarkup = makeStaticMarkup;
this.suspenseDepth = 0;
// Context (new API)
this.contextIndex = -1;
this.contextStack = [];
this.contextValueStack = [];
}
ReactDOMServerRenderer.prototype.destroy = function destroy() {
if (!this.exhausted) {
this.exhausted = true;
this.clearProviders();
freeThreadID(this.threadID);
}
};
/**
* Note: We use just two stacks regardless of how many context providers you have.
* Providers are always popped in the reverse order to how they were pushed
* so we always know on the way down which provider you'll encounter next on the way up.
* On the way down, we push the current provider, and its context value *before*
* we mutated it, onto the stacks. Therefore, on the way up, we always know which
* provider needs to be "restored" to which value.
* https://github.com/facebook/react/pull/12985#issuecomment-396301248
*/
ReactDOMServerRenderer.prototype.pushProvider = function pushProvider(provider) {
var index = ++this.contextIndex;
var context = provider.type._context;
var threadID = this.threadID;
validateContextBounds(context, threadID);
var previousValue = context[threadID];
// Remember which value to restore this context to on our way up.
this.contextStack[index] = context;
this.contextValueStack[index] = previousValue;
context[threadID] = provider.props.value;
};
ReactDOMServerRenderer.prototype.popProvider = function popProvider(provider) {
var index = this.contextIndex;
var context = this.contextStack[index];
var previousValue = this.contextValueStack[index];
// "Hide" these null assignments from Flow by using `any`
// because conceptually they are deletions--as long as we
// promise to never access values beyond `this.contextIndex`.
this.contextStack[index] = null;
this.contextValueStack[index] = null;
this.contextIndex--;
// Restore to the previous value we stored as we were walking down.
// We've already verified that this context has been expanded to accommodate
// this thread id, so we don't need to do it again.
context[this.threadID] = previousValue;
};
ReactDOMServerRenderer.prototype.clearProviders = function clearProviders() {
// Restore any remaining providers on the stack to previous values
for (var index = this.contextIndex; index >= 0; index--) {
var _context = this.contextStack[index];
var previousValue = this.contextValueStack[index];
_context[this.threadID] = previousValue;
}
};
ReactDOMServerRenderer.prototype.read = function read(bytes) {
if (this.exhausted) {
return null;
}
var prevThreadID = currentThreadID;
setCurrentThreadID(this.threadID);
var prevDispatcher = ReactCurrentDispatcher.current;
ReactCurrentDispatcher.current = Dispatcher;
try {
// Markup generated within <Suspense> ends up buffered until we know
// nothing in that boundary suspended
var out = [''];
var suspended = false;
while (out[0].length < bytes) {
if (this.stack.length === 0) {
this.exhausted = true;
freeThreadID(this.threadID);
break;
}
var frame = this.stack[this.stack.length - 1];
if (suspended || frame.childIndex >= frame.children.length) {
var _footer = frame.footer;
if (_footer !== '') {
this.previousWasTextNode = false;
}
this.stack.pop();
if (frame.type === 'select') {
this.currentSelectValue = null;
} else if (frame.type != null && frame.type.type != null && frame.type.type.$$typeof === REACT_PROVIDER_TYPE) {
var provider = frame.type;
this.popProvider(provider);
} else if (frame.type === REACT_SUSPENSE_TYPE) {
this.suspenseDepth--;
var buffered = out.pop();
if (suspended) {
suspended = false;
// If rendering was suspended at this boundary, render the fallbackFrame
var _fallbackFrame = frame.fallbackFrame;
!_fallbackFrame ? reactProdInvariant('303') : void 0;
this.stack.push(_fallbackFrame);
// Skip flushing output since we're switching to the fallback
continue;
} else {
out[this.suspenseDepth] += buffered;
}
}
// Flush output
out[this.suspenseDepth] += _footer;
continue;
}
var child = frame.children[frame.childIndex++];
var outBuffer = '';
try {
outBuffer += this.render(child, frame.context, frame.domNamespace);
} catch (err) {
if (enableSuspenseServerRenderer && typeof err.then === 'function') {
suspended = true;
} else {
throw err;
}
} finally {
}
if (out.length <= this.suspenseDepth) {
out.push('');
}
out[this.suspenseDepth] += outBuffer;
}
return out[0];
} finally {
ReactCurrentDispatcher.current = prevDispatcher;
setCurrentThreadID(prevThreadID);
}
};
ReactDOMServerRenderer.prototype.render = function render(child, context, parentNamespace) {
if (typeof child === 'string' || typeof child === 'number') {
var text = '' + child;
if (text === '') {
return '';
}
if (this.makeStaticMarkup) {
return escapeTextForBrowser(text);
}
if (this.previousWasTextNode) {
return '<!-- -->' + escapeTextForBrowser(text);
}
this.previousWasTextNode = true;
return escapeTextForBrowser(text);
} else {
var nextChild = void 0;
var _resolve = resolve(child, context, this.threadID);
nextChild = _resolve.child;
context = _resolve.context;
if (nextChild === null || nextChild === false) {
return '';
} else if (!React.isValidElement(nextChild)) {
if (nextChild != null && nextChild.$$typeof != null) {
// Catch unexpected special types early.
var $$typeof = nextChild.$$typeof;
!($$typeof !== REACT_PORTAL_TYPE) ? reactProdInvariant('257') : void 0;
// Catch-all to prevent an infinite loop if React.Children.toArray() supports some new type.
reactProdInvariant('258', $$typeof.toString());
}
var nextChildren = toArray(nextChild);
var frame = {
type: null,
domNamespace: parentNamespace,
children: nextChildren,
childIndex: 0,
context: context,
footer: ''
};
this.stack.push(frame);
return '';
}
// Safe because we just checked it's an element.
var nextElement = nextChild;
var elementType = nextElement.type;
if (typeof elementType === 'string') {
return this.renderDOM(nextElement, context, parentNamespace);
}
switch (elementType) {
case REACT_STRICT_MODE_TYPE:
case REACT_CONCURRENT_MODE_TYPE:
case REACT_PROFILER_TYPE:
case REACT_FRAGMENT_TYPE:
{
var _nextChildren = toArray(nextChild.props.children);
var _frame = {
type: null,
domNamespace: parentNamespace,
children: _nextChildren,
childIndex: 0,
context: context,
footer: ''
};
this.stack.push(_frame);
return '';
}
case REACT_SUSPENSE_TYPE:
{
if (enableSuspenseServerRenderer) {
var fallback = nextChild.props.fallback;
if (fallback === undefined) {
// If there is no fallback, then this just behaves as a fragment.
var _nextChildren3 = toArray(nextChild.props.children);
var _frame3 = {
type: null,
domNamespace: parentNamespace,
children: _nextChildren3,
childIndex: 0,
context: context,
footer: ''
};
this.stack.push(_frame3);
return '';
}
var fallbackChildren = toArray(fallback);
var _nextChildren2 = toArray(nextChild.props.children);
var _fallbackFrame2 = {
type: null,
domNamespace: parentNamespace,
children: fallbackChildren,
childIndex: 0,
context: context,
footer: '',
out: ''
};
var _frame2 = {
fallbackFrame: _fallbackFrame2,
type: REACT_SUSPENSE_TYPE,
domNamespace: parentNamespace,
children: _nextChildren2,
childIndex: 0,
context: context,
footer: '<!--/$-->'
};
this.stack.push(_frame2);
this.suspenseDepth++;
return '<!--$-->';
} else {
reactProdInvariant('294');
}
}
// eslint-disable-next-line-no-fallthrough
default:
break;
}
if (typeof elementType === 'object' && elementType !== null) {
switch (elementType.$$typeof) {
case REACT_FORWARD_REF_TYPE:
{
var element = nextChild;
var _nextChildren4 = void 0;
var componentIdentity = {};
prepareToUseHooks(componentIdentity);
_nextChildren4 = elementType.render(element.props, element.ref);
_nextChildren4 = finishHooks(elementType.render, element.props, _nextChildren4, element.ref);
_nextChildren4 = toArray(_nextChildren4);
var _frame4 = {
type: null,
domNamespace: parentNamespace,
children: _nextChildren4,
childIndex: 0,
context: context,
footer: ''
};
this.stack.push(_frame4);
return '';
}
case REACT_MEMO_TYPE:
{
var _element = nextChild;
var _nextChildren5 = [React.createElement(elementType.type, _assign({ ref: _element.ref }, _element.props))];
var _frame5 = {
type: null,
domNamespace: parentNamespace,
children: _nextChildren5,
childIndex: 0,
context: context,
footer: ''
};
this.stack.push(_frame5);
return '';
}
case REACT_PROVIDER_TYPE:
{
var provider = nextChild;
var nextProps = provider.props;
var _nextChildren6 = toArray(nextProps.children);
var _frame6 = {
type: provider,
domNamespace: parentNamespace,
children: _nextChildren6,
childIndex: 0,
context: context,
footer: ''
};
this.pushProvider(provider);
this.stack.push(_frame6);
return '';
}
case REACT_CONTEXT_TYPE:
{
var reactContext = nextChild.type;
// The logic below for Context differs depending on PROD or DEV mode. In
// DEV mode, we create a separate object for Context.Consumer that acts
// like a proxy to Context. This proxy object adds unnecessary code in PROD
// so we use the old behaviour (Context.Consumer references Context) to
// reduce size and overhead. The separate object references context via
// a property called "_context", which also gives us the ability to check
// in DEV mode if this property exists or not and warn if it does not.
var _nextProps = nextChild.props;
var threadID = this.threadID;
validateContextBounds(reactContext, threadID);
var nextValue = reactContext[threadID];
var _nextChildren7 = toArray(_nextProps.children(nextValue));
var _frame7 = {
type: nextChild,
domNamespace: parentNamespace,
children: _nextChildren7,
childIndex: 0,
context: context,
footer: ''
};
this.stack.push(_frame7);
return '';
}
case REACT_LAZY_TYPE:
reactProdInvariant('295');
}
}
var info = '';
reactProdInvariant('130', elementType == null ? elementType : typeof elementType, info);
}
};
ReactDOMServerRenderer.prototype.renderDOM = function renderDOM(element, context, parentNamespace) {
var tag = element.type.toLowerCase();
var namespace = parentNamespace;
if (parentNamespace === Namespaces.html) {
namespace = getIntrinsicNamespace(tag);
}
validateDangerousTag(tag);
var props = element.props;
if (tag === 'input') {
props = _assign({
type: undefined
}, props, {
defaultChecked: undefined,
defaultValue: undefined,
value: props.value != null ? props.value : props.defaultValue,
checked: props.checked != null ? props.checked : props.defaultChecked
});
} else if (tag === 'textarea') {
var initialValue = props.value;
if (initialValue == null) {
var defaultValue = props.defaultValue;
// TODO (yungsters): Remove support for children content in <textarea>.
var textareaChildren = props.children;
if (textareaChildren != null) {
!(defaultValue == null) ? reactProdInvariant('92') : void 0;
if (Array.isArray(textareaChildren)) {
!(textareaChildren.length <= 1) ? reactProdInvariant('93') : void 0;
textareaChildren = textareaChildren[0];
}
defaultValue = '' + textareaChildren;
}
if (defaultValue == null) {
defaultValue = '';
}
initialValue = defaultValue;
}
props = _assign({}, props, {
value: undefined,
children: '' + initialValue
});
} else if (tag === 'select') {
this.currentSelectValue = props.value != null ? props.value : props.defaultValue;
props = _assign({}, props, {
value: undefined
});
} else if (tag === 'option') {
var selected = null;
var selectValue = this.currentSelectValue;
var optionChildren = flattenOptionChildren(props.children);
if (selectValue != null) {
var value = void 0;
if (props.value != null) {
value = props.value + '';
} else {
value = optionChildren;
}
selected = false;
if (Array.isArray(selectValue)) {
// multiple
for (var j = 0; j < selectValue.length; j++) {
if ('' + selectValue[j] === value) {
selected = true;
break;
}
}
} else {
selected = '' + selectValue === value;
}
props = _assign({
selected: undefined,
children: undefined
}, props, {
selected: selected,
children: optionChildren
});
}
}
assertValidProps(tag, props);
var out = createOpenTagMarkup(element.type, tag, props, namespace, this.makeStaticMarkup, this.stack.length === 1);
var footer = '';
if (omittedCloseTags.hasOwnProperty(tag)) {
out += '/>';
} else {
out += '>';
footer = '</' + element.type + '>';
}
var children = void 0;
var innerMarkup = getNonChildrenInnerMarkup(props);
if (innerMarkup != null) {
children = [];
if (newlineEatingTags[tag] && innerMarkup.charAt(0) === '\n') {
// text/html ignores the first character in these tags if it's a newline
// Prefer to break application/xml over text/html (for now) by adding
// a newline specifically to get eaten by the parser. (Alternately for
// textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first
// \r is normalized out by HTMLTextAreaElement#value.)
// See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre>
// See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions>
// See: <http://www.w3.org/TR/html5/syntax.html#newlines>
// See: Parsing of "textarea" "listing" and "pre" elements
// from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody>
out += '\n';
}
out += innerMarkup;
} else {
children = toArray(props.children);
}
var frame = {
domNamespace: getChildNamespace(parentNamespace, element.type),
type: tag,
children: children,
childIndex: 0,
context: context,
footer: footer
};
this.stack.push(frame);
this.previousWasTextNode = false;
return out;
};
return ReactDOMServerRenderer;
}();
/**
* Render a ReactElement to its initial HTML. This should only be used on the
* server.
* See https://reactjs.org/docs/react-dom-server.html#rendertostring
*/
function renderToString(element) {
var renderer = new ReactDOMServerRenderer(element, false);
try {
var markup = renderer.read(Infinity);
return markup;
} finally {
renderer.destroy();
}
}
/**
* Similar to renderToString, except this doesn't create extra DOM attributes
* such as data-react-id that React uses internally.
* See https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup
*/
function renderToStaticMarkup(element) {
var renderer = new ReactDOMServerRenderer(element, true);
try {
var markup = renderer.read(Infinity);
return markup;
} finally {
renderer.destroy();
}
}
function renderToNodeStream() {
reactProdInvariant('207');
}
function renderToStaticNodeStream() {
reactProdInvariant('208');
}
// Note: when changing this, also consider https://github.com/facebook/react/issues/11526
var ReactDOMServerBrowser = {
renderToString: renderToString,
renderToStaticMarkup: renderToStaticMarkup,
renderToNodeStream: renderToNodeStream,
renderToStaticNodeStream: renderToStaticNodeStream,
version: ReactVersion
};
var ReactDOMServerBrowser$1 = ({
default: ReactDOMServerBrowser
});
var ReactDOMServer = ( ReactDOMServerBrowser$1 && ReactDOMServerBrowser ) || ReactDOMServerBrowser$1;
// TODO: decide on the top-level export form.
// This is hacky but makes it work with both Rollup and Jest
var server_browser = ReactDOMServer.default || ReactDOMServer;
return server_browser;
})));