import Stylis from 'stylis/stylis.min'; import _insertRulePlugin from 'stylis-rule-sheet'; import React, { cloneElement, createContext, Component, createElement } from 'react'; import unitless from '@emotion/unitless'; import { isElement, isValidElementType, ForwardRef } from 'react-is'; import memoize from 'memoize-one'; import stream from 'stream'; import PropTypes from 'prop-types'; import validAttr from '@emotion/is-prop-valid'; import merge from 'merge-anything'; // var interleave = (function (strings, interpolations) { var result = [strings[0]]; for (var i = 0, len = interpolations.length; i < len; i += 1) { result.push(interpolations[i], strings[i + 1]); } return result; }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }; var objectWithoutProperties = function (obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }; var possibleConstructorReturn = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }; // var isPlainObject = (function (x) { return (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === 'object' && x.constructor === Object; }); // var EMPTY_ARRAY = Object.freeze([]); var EMPTY_OBJECT = Object.freeze({}); // function isFunction(test) { return typeof test === 'function'; } // function getComponentName(target) { return (process.env.NODE_ENV !== 'production' ? typeof target === 'string' && target : false) || target.displayName || target.name || 'Component'; } // function isStatelessFunction(test) { return typeof test === 'function' && !(test.prototype && test.prototype.isReactComponent); } // function isStyledComponent(target) { return target && typeof target.styledComponentId === 'string'; } // var SC_ATTR = typeof process !== 'undefined' && (process.env.REACT_APP_SC_ATTR || process.env.SC_ATTR) || 'data-styled'; var SC_VERSION_ATTR = 'data-styled-version'; var SC_STREAM_ATTR = 'data-styled-streamed'; var IS_BROWSER = typeof window !== 'undefined' && 'HTMLElement' in window; var DISABLE_SPEEDY = typeof SC_DISABLE_SPEEDY === 'boolean' && SC_DISABLE_SPEEDY || typeof process !== 'undefined' && (process.env.REACT_APP_SC_DISABLE_SPEEDY || process.env.SC_DISABLE_SPEEDY) || process.env.NODE_ENV !== 'production'; // Shared empty execution context when generating static styles var STATIC_EXECUTION_CONTEXT = {}; // /** * Parse errors.md and turn it into a simple hash of code: message */ var ERRORS = process.env.NODE_ENV !== 'production' ? { "1": "Cannot create styled-component for component: %s.\n\n", "2": "Can't collect styles once you've consumed a `ServerStyleSheet`'s styles! `ServerStyleSheet` is a one off instance for each server-side render cycle.\n\n- Are you trying to reuse it across renders?\n- Are you accidentally calling collectStyles twice?\n\n", "3": "Streaming SSR is only supported in a Node.js environment; Please do not try to call this method in the browser.\n\n", "4": "The `StyleSheetManager` expects a valid target or sheet prop!\n\n- Does this error occur on the client and is your target falsy?\n- Does this error occur on the server and is the sheet falsy?\n\n", "5": "The clone method cannot be used on the client!\n\n- Are you running in a client-like environment on the server?\n- Are you trying to run SSR on the client?\n\n", "6": "Trying to insert a new style tag, but the given Node is unmounted!\n\n- Are you using a custom target that isn't mounted?\n- Does your document not have a valid head element?\n- Have you accidentally removed a style tag manually?\n\n", "7": "ThemeProvider: Please return an object from your \"theme\" prop function, e.g.\n\n```js\ntheme={() => ({})}\n```\n\n", "8": "ThemeProvider: Please make your \"theme\" prop an object.\n\n", "9": "Missing document `
`\n\n", "10": "Cannot find a StyleSheet instance. Usually this happens if there are multiple copies of styled-components loaded at once. Check out this issue for how to troubleshoot and fix the common cases where this situation can happen: https://github.com/styled-components/styled-components/issues/1941#issuecomment-417862021\n\n", "11": "_This error was replaced with a dev-time warning, it will be deleted for v4 final._ [createGlobalStyle] received children which will not be rendered. Please use the component without passing children elements.\n\n", "12": "It seems you are interpolating a keyframe declaration (%s) into an untagged string. This was supported in styled-components v3, but is not longer supported in v4 as keyframes are now injected on-demand. Please wrap your string in the css\\`\\` helper which ensures the styles are injected correctly. See https://www.styled-components.com/docs/api#css\n\n", "13": "%s is not a styled component and cannot be referred to via component selector. See https://www.styled-components.com/docs/advanced#referring-to-other-components for more details.\n" } : {}; /** * super basic version of sprintf */ function format() { var a = arguments.length <= 0 ? undefined : arguments[0]; var b = []; for (var c = 1, len = arguments.length; c < len; c += 1) { b.push(arguments.length <= c ? undefined : arguments[c]); } b.forEach(function (d) { a = a.replace(/%[a-z]/, d); }); return a; } /** * Create an error file out of errors.md for development and a simple web link to the full errors * in production mode. */ var StyledComponentsError = function (_Error) { inherits(StyledComponentsError, _Error); function StyledComponentsError(code) { classCallCheck(this, StyledComponentsError); for (var _len = arguments.length, interpolations = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { interpolations[_key - 1] = arguments[_key]; } if (process.env.NODE_ENV === 'production') { var _this = possibleConstructorReturn(this, _Error.call(this, 'An error occurred. See https://github.com/styled-components/styled-components/blob/master/packages/styled-components/src/utils/errors.md#' + code + ' for more information.' + (interpolations.length > 0 ? ' Additional arguments: ' + interpolations.join(', ') : ''))); } else { var _this = possibleConstructorReturn(this, _Error.call(this, format.apply(undefined, [ERRORS[code]].concat(interpolations)).trim())); } return possibleConstructorReturn(_this); } return StyledComponentsError; }(Error); // var SC_COMPONENT_ID = /^[^\S\n]*?\/\* sc-component-id:\s*(\S+)\s+\*\//gm; var extractComps = (function (maybeCSS) { var css = '' + (maybeCSS || ''); // Definitely a string, and a clone var existingComponents = []; css.replace(SC_COMPONENT_ID, function (match, componentId, matchIndex) { existingComponents.push({ componentId: componentId, matchIndex: matchIndex }); return match; }); return existingComponents.map(function (_ref, i) { var componentId = _ref.componentId, matchIndex = _ref.matchIndex; var nextComp = existingComponents[i + 1]; var cssFromDOM = nextComp ? css.slice(matchIndex, nextComp.matchIndex) : css.slice(matchIndex); return { componentId: componentId, cssFromDOM: cssFromDOM }; }); }); // var COMMENT_REGEX = /^\s*\/\/.*$/gm; // NOTE: This stylis instance is only used to split rules from SSR'd style tags var stylisSplitter = new Stylis({ global: false, cascade: true, keyframe: false, prefix: false, compress: false, semicolon: true }); var stylis = new Stylis({ global: false, cascade: true, keyframe: false, prefix: true, compress: false, semicolon: false // NOTE: This means "autocomplete missing semicolons" }); // Wrap `insertRulePlugin to build a list of rules, // and then make our own plugin to return the rules. This // makes it easier to hook into the existing SSR architecture var parsingRules = []; // eslint-disable-next-line consistent-return var returnRulesPlugin = function returnRulesPlugin(context) { if (context === -2) { var parsedRules = parsingRules; parsingRules = []; return parsedRules; } }; var parseRulesPlugin = _insertRulePlugin(function (rule) { parsingRules.push(rule); }); var _componentId = void 0; var _selector = void 0; var _selectorRegexp = void 0; var selfReferenceReplacer = function selfReferenceReplacer(match, offset, string) { if ( // the first self-ref is always untouched offset > 0 && // there should be at least two self-refs to do a replacement (.b > .b) string.slice(0, offset).indexOf(_selector) !== -1 && // no consecutive self refs (.b.b); that is a precedence boost and treated differently string.slice(offset - _selector.length, offset) !== _selector) { return '.' + _componentId; } return match; }; /** * When writing a style like * * & + & { * color: red; * } * * The second ampersand should be a reference to the static component class. stylis * has no knowledge of static class so we have to intelligently replace the base selector. */ var selfReferenceReplacementPlugin = function selfReferenceReplacementPlugin(context, _, selectors) { if (context === 2 && selectors.length && selectors[0].lastIndexOf(_selector) > 0) { // eslint-disable-next-line no-param-reassign selectors[0] = selectors[0].replace(_selectorRegexp, selfReferenceReplacer); } }; stylis.use([selfReferenceReplacementPlugin, parseRulesPlugin, returnRulesPlugin]); stylisSplitter.use([parseRulesPlugin, returnRulesPlugin]); var splitByRules = function splitByRules(css) { return stylisSplitter('', css); }; function stringifyRules(rules, selector, prefix) { var componentId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '&'; var flatCSS = rules.join('').replace(COMMENT_REGEX, ''); // replace JS comments var cssStr = selector && prefix ? prefix + ' ' + selector + ' { ' + flatCSS + ' }' : flatCSS; // stylis has no concept of state to be passed to plugins // but since JS is single=threaded, we can rely on that to ensure // these properties stay in sync with the current stylis run _componentId = componentId; _selector = selector; _selectorRegexp = new RegExp('\\' + _selector + '\\b', 'g'); return stylis(prefix || !selector ? '' : selector, cssStr); } // /* eslint-disable camelcase, no-undef */ var getNonce = (function () { return typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null; }); // /* These are helpers for the StyleTags to keep track of the injected * rule names for each (component) ID that they're keeping track of. * They're crucial for detecting whether a name has already been * injected. * (This excludes rehydrated names) */ /* adds a new ID:name pairing to a names dictionary */ var addNameForId = function addNameForId(names, id, name) { if (name) { // eslint-disable-next-line no-param-reassign var namesForId = names[id] || (names[id] = Object.create(null)); namesForId[name] = true; } }; /* resets an ID entirely by overwriting it in the dictionary */ var resetIdNames = function resetIdNames(names, id) { // eslint-disable-next-line no-param-reassign names[id] = Object.create(null); }; /* factory for a names dictionary checking the existance of an ID:name pairing */ var hasNameForId = function hasNameForId(names) { return function (id, name) { return names[id] !== undefined && names[id][name]; }; }; /* stringifies names for the html/element output */ var stringifyNames = function stringifyNames(names) { var str = ''; // eslint-disable-next-line guard-for-in for (var id in names) { str += Object.keys(names[id]).join(' ') + ' '; } return str.trim(); }; /* clones the nested names dictionary */ var cloneNames = function cloneNames(names) { var clone = Object.create(null); // eslint-disable-next-line guard-for-in for (var id in names) { clone[id] = _extends({}, names[id]); } return clone; }; // /* These are helpers that deal with the insertRule (aka speedy) API * They are used in the StyleTags and specifically the speedy tag */ /* retrieve a sheet for a given style tag */ var sheetForTag = function sheetForTag(tag) { // $FlowFixMe if (tag.sheet) return tag.sheet; /* Firefox quirk requires us to step through all stylesheets to find one owned by the given tag */ var size = tag.ownerDocument.styleSheets.length; for (var i = 0; i < size; i += 1) { var sheet = tag.ownerDocument.styleSheets[i]; // $FlowFixMe if (sheet.ownerNode === tag) return sheet; } /* we should always be able to find a tag */ throw new StyledComponentsError(10); }; /* insert a rule safely and return whether it was actually injected */ var safeInsertRule = function safeInsertRule(sheet, cssRule, index) { /* abort early if cssRule string is falsy */ if (!cssRule) return false; var maxIndex = sheet.cssRules.length; try { /* use insertRule and cap passed index with maxIndex (no of cssRules) */ sheet.insertRule(cssRule, index <= maxIndex ? index : maxIndex); } catch (err) { /* any error indicates an invalid rule */ return false; } return true; }; /* deletes `size` rules starting from `removalIndex` */ var deleteRules = function deleteRules(sheet, removalIndex, size) { var lowerBound = removalIndex - size; for (var i = removalIndex; i > lowerBound; i -= 1) { sheet.deleteRule(i); } }; // /* this marker separates component styles and is important for rehydration */ var makeTextMarker = function makeTextMarker(id) { return '\n/* sc-component-id: ' + id + ' */\n'; }; /* add up all numbers in array up until and including the index */ var addUpUntilIndex = function addUpUntilIndex(sizes, index) { var totalUpToIndex = 0; for (var i = 0; i <= index; i += 1) { totalUpToIndex += sizes[i]; } return totalUpToIndex; }; /* create a new style tag after lastEl */ var makeStyleTag = function makeStyleTag(target, tagEl, insertBefore) { var targetDocument = document; if (target) targetDocument = target.ownerDocument;else if (tagEl) targetDocument = tagEl.ownerDocument; var el = targetDocument.createElement('style'); el.setAttribute(SC_ATTR, ''); el.setAttribute(SC_VERSION_ATTR, "4.4.1"); var nonce = getNonce(); if (nonce) { el.setAttribute('nonce', nonce); } /* Work around insertRule quirk in EdgeHTML */ el.appendChild(targetDocument.createTextNode('')); if (target && !tagEl) { /* Append to target when no previous element was passed */ target.appendChild(el); } else { if (!tagEl || !target || !tagEl.parentNode) { throw new StyledComponentsError(6); } /* Insert new style tag after the previous one */ tagEl.parentNode.insertBefore(el, insertBefore ? tagEl : tagEl.nextSibling); } return el; }; /* takes a css factory function and outputs an html styled tag factory */ var wrapAsHtmlTag = function wrapAsHtmlTag(css, names) { return function (additionalAttrs) { var nonce = getNonce(); var attrs = [nonce && 'nonce="' + nonce + '"', SC_ATTR + '="' + stringifyNames(names) + '"', SC_VERSION_ATTR + '="' + "4.4.1" + '"', additionalAttrs]; var htmlAttr = attrs.filter(Boolean).join(' '); return ''; }; }; /* takes a css factory function and outputs an element factory */ var wrapAsElement = function wrapAsElement(css, names) { return function () { var _props; var props = (_props = {}, _props[SC_ATTR] = stringifyNames(names), _props[SC_VERSION_ATTR] = "4.4.1", _props); var nonce = getNonce(); if (nonce) { // $FlowFixMe props.nonce = nonce; } // eslint-disable-next-line react/no-danger return React.createElement('style', _extends({}, props, { dangerouslySetInnerHTML: { __html: css() } })); }; }; var getIdsFromMarkersFactory = function getIdsFromMarkersFactory(markers) { return function () { return Object.keys(markers); }; }; /* speedy tags utilise insertRule */ var makeSpeedyTag = function makeSpeedyTag(el, getImportRuleTag) { var names = Object.create(null); var markers = Object.create(null); var sizes = []; var extractImport = getImportRuleTag !== undefined; /* indicates whether getImportRuleTag was called */ var usedImportRuleTag = false; var insertMarker = function insertMarker(id) { var prev = markers[id]; if (prev !== undefined) { return prev; } markers[id] = sizes.length; sizes.push(0); resetIdNames(names, id); return markers[id]; }; var insertRules = function insertRules(id, cssRules, name) { var marker = insertMarker(id); var sheet = sheetForTag(el); var insertIndex = addUpUntilIndex(sizes, marker); var injectedRules = 0; var importRules = []; var cssRulesSize = cssRules.length; for (var i = 0; i < cssRulesSize; i += 1) { var cssRule = cssRules[i]; var mayHaveImport = extractImport; /* @import rules are reordered to appear first */ if (mayHaveImport && cssRule.indexOf('@import') !== -1) { importRules.push(cssRule); } else if (safeInsertRule(sheet, cssRule, insertIndex + injectedRules)) { mayHaveImport = false; injectedRules += 1; } } if (extractImport && importRules.length > 0) { usedImportRuleTag = true; // $FlowFixMe getImportRuleTag().insertRules(id + '-import', importRules); } sizes[marker] += injectedRules; /* add up no of injected rules */ addNameForId(names, id, name); }; var removeRules = function removeRules(id) { var marker = markers[id]; if (marker === undefined) return; // $FlowFixMe if (el.isConnected === false) return; var size = sizes[marker]; var sheet = sheetForTag(el); var removalIndex = addUpUntilIndex(sizes, marker) - 1; deleteRules(sheet, removalIndex, size); sizes[marker] = 0; resetIdNames(names, id); if (extractImport && usedImportRuleTag) { // $FlowFixMe getImportRuleTag().removeRules(id + '-import'); } }; var css = function css() { var _sheetForTag = sheetForTag(el), cssRules = _sheetForTag.cssRules; var str = ''; // eslint-disable-next-line guard-for-in for (var id in markers) { str += makeTextMarker(id); var marker = markers[id]; var end = addUpUntilIndex(sizes, marker); var size = sizes[marker]; for (var i = end - size; i < end; i += 1) { var rule = cssRules[i]; if (rule !== undefined) { str += rule.cssText; } } } return str; }; return { clone: function clone() { throw new StyledComponentsError(5); }, css: css, getIds: getIdsFromMarkersFactory(markers), hasNameForId: hasNameForId(names), insertMarker: insertMarker, insertRules: insertRules, removeRules: removeRules, sealed: false, styleTag: el, toElement: wrapAsElement(css, names), toHTML: wrapAsHtmlTag(css, names) }; }; var makeTextNode = function makeTextNode(targetDocument, id) { return targetDocument.createTextNode(makeTextMarker(id)); }; var makeBrowserTag = function makeBrowserTag(el, getImportRuleTag) { var names = Object.create(null); var markers = Object.create(null); var extractImport = getImportRuleTag !== undefined; /* indicates whether getImportRuleTag was called */ var usedImportRuleTag = false; var insertMarker = function insertMarker(id) { var prev = markers[id]; if (prev !== undefined) { return prev; } markers[id] = makeTextNode(el.ownerDocument, id); el.appendChild(markers[id]); names[id] = Object.create(null); return markers[id]; }; var insertRules = function insertRules(id, cssRules, name) { var marker = insertMarker(id); var importRules = []; var cssRulesSize = cssRules.length; for (var i = 0; i < cssRulesSize; i += 1) { var rule = cssRules[i]; var mayHaveImport = extractImport; if (mayHaveImport && rule.indexOf('@import') !== -1) { importRules.push(rule); } else { mayHaveImport = false; var separator = i === cssRulesSize - 1 ? '' : ' '; marker.appendData('' + rule + separator); } } addNameForId(names, id, name); if (extractImport && importRules.length > 0) { usedImportRuleTag = true; // $FlowFixMe getImportRuleTag().insertRules(id + '-import', importRules); } }; var removeRules = function removeRules(id) { var marker = markers[id]; if (marker === undefined) return; /* create new empty text node and replace the current one */ var newMarker = makeTextNode(el.ownerDocument, id); el.replaceChild(newMarker, marker); markers[id] = newMarker; resetIdNames(names, id); if (extractImport && usedImportRuleTag) { // $FlowFixMe getImportRuleTag().removeRules(id + '-import'); } }; var css = function css() { var str = ''; // eslint-disable-next-line guard-for-in for (var id in markers) { str += markers[id].data; } return str; }; return { clone: function clone() { throw new StyledComponentsError(5); }, css: css, getIds: getIdsFromMarkersFactory(markers), hasNameForId: hasNameForId(names), insertMarker: insertMarker, insertRules: insertRules, removeRules: removeRules, sealed: false, styleTag: el, toElement: wrapAsElement(css, names), toHTML: wrapAsHtmlTag(css, names) }; }; var makeServerTag = function makeServerTag(namesArg, markersArg) { var names = namesArg === undefined ? Object.create(null) : namesArg; var markers = markersArg === undefined ? Object.create(null) : markersArg; var insertMarker = function insertMarker(id) { var prev = markers[id]; if (prev !== undefined) { return prev; } return markers[id] = ['']; }; var insertRules = function insertRules(id, cssRules, name) { var marker = insertMarker(id); marker[0] += cssRules.join(' '); addNameForId(names, id, name); }; var removeRules = function removeRules(id) { var marker = markers[id]; if (marker === undefined) return; marker[0] = ''; resetIdNames(names, id); }; var css = function css() { var str = ''; // eslint-disable-next-line guard-for-in for (var id in markers) { var cssForId = markers[id][0]; if (cssForId) { str += makeTextMarker(id) + cssForId; } } return str; }; var clone = function clone() { var namesClone = cloneNames(names); var markersClone = Object.create(null); // eslint-disable-next-line guard-for-in for (var id in markers) { markersClone[id] = [markers[id][0]]; } return makeServerTag(namesClone, markersClone); }; var tag = { clone: clone, css: css, getIds: getIdsFromMarkersFactory(markers), hasNameForId: hasNameForId(names), insertMarker: insertMarker, insertRules: insertRules, removeRules: removeRules, sealed: false, styleTag: null, toElement: wrapAsElement(css, names), toHTML: wrapAsHtmlTag(css, names) }; return tag; }; var makeTag = function makeTag(target, tagEl, forceServer, insertBefore, getImportRuleTag) { if (IS_BROWSER && !forceServer) { var el = makeStyleTag(target, tagEl, insertBefore); if (DISABLE_SPEEDY) { return makeBrowserTag(el, getImportRuleTag); } else { return makeSpeedyTag(el, getImportRuleTag); } } return makeServerTag(); }; var rehydrate = function rehydrate(tag, els, extracted) { /* add all extracted components to the new tag */ for (var i = 0, len = extracted.length; i < len; i += 1) { var _extracted$i = extracted[i], componentId = _extracted$i.componentId, cssFromDOM = _extracted$i.cssFromDOM; var cssRules = splitByRules(cssFromDOM); tag.insertRules(componentId, cssRules); } /* remove old HTMLStyleElements, since they have been rehydrated */ for (var _i = 0, _len = els.length; _i < _len; _i += 1) { var el = els[_i]; if (el.parentNode) { el.parentNode.removeChild(el); } } }; // var SPLIT_REGEX = /\s+/; /* determine the maximum number of components before tags are sharded */ var MAX_SIZE = void 0; if (IS_BROWSER) { /* in speedy mode we can keep a lot more rules in a sheet before a slowdown can be expected */ MAX_SIZE = DISABLE_SPEEDY ? 40 : 1000; } else { /* for servers we do not need to shard at all */ MAX_SIZE = -1; } var sheetRunningId = 0; var master = void 0; var StyleSheet = function () { /* a map from ids to tags */ /* deferred rules for a given id */ /* this is used for not reinjecting rules via hasNameForId() */ /* when rules for an id are removed using remove() we have to ignore rehydratedNames for it */ /* a list of tags belonging to this StyleSheet */ /* a tag for import rules */ /* current capacity until a new tag must be created */ /* children (aka clones) of this StyleSheet inheriting all and future injections */ function StyleSheet() { var _this = this; var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : IS_BROWSER ? document.head : null; var forceServer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; classCallCheck(this, StyleSheet); this.getImportRuleTag = function () { var importRuleTag = _this.importRuleTag; if (importRuleTag !== undefined) { return importRuleTag; } var firstTag = _this.tags[0]; var insertBefore = true; return _this.importRuleTag = makeTag(_this.target, firstTag ? firstTag.styleTag : null, _this.forceServer, insertBefore); }; sheetRunningId += 1; this.id = sheetRunningId; this.forceServer = forceServer; this.target = forceServer ? null : target; this.tagMap = {}; this.deferred = {}; this.rehydratedNames = {}; this.ignoreRehydratedNames = {}; this.tags = []; this.capacity = 1; this.clones = []; } /* rehydrate all SSR'd style tags */ StyleSheet.prototype.rehydrate = function rehydrate$$1() { if (!IS_BROWSER || this.forceServer) return this; var els = []; var extracted = []; var isStreamed = false; /* retrieve all of our SSR style elements from the DOM */ var nodes = document.querySelectorAll('style[' + SC_ATTR + '][' + SC_VERSION_ATTR + '="' + "4.4.1" + '"]'); var nodesSize = nodes.length; /* abort rehydration if no previous style tags were found */ if (!nodesSize) return this; for (var i = 0; i < nodesSize; i += 1) { var el = nodes[i]; /* check if style tag is a streamed tag */ if (!isStreamed) isStreamed = !!el.getAttribute(SC_STREAM_ATTR); /* retrieve all component names */ var elNames = (el.getAttribute(SC_ATTR) || '').trim().split(SPLIT_REGEX); var elNamesSize = elNames.length; for (var j = 0, name; j < elNamesSize; j += 1) { name = elNames[j]; /* add rehydrated name to sheet to avoid re-adding styles */ this.rehydratedNames[name] = true; } /* extract all components and their CSS */ extracted.push.apply(extracted, extractComps(el.textContent)); /* store original HTMLStyleElement */ els.push(el); } /* abort rehydration if nothing was extracted */ var extractedSize = extracted.length; if (!extractedSize) return this; /* create a tag to be used for rehydration */ var tag = this.makeTag(null); rehydrate(tag, els, extracted); /* reset capacity and adjust MAX_SIZE by the initial size of the rehydration */ this.capacity = Math.max(1, MAX_SIZE - extractedSize); this.tags.push(tag); /* retrieve all component ids */ for (var _j = 0; _j < extractedSize; _j += 1) { this.tagMap[extracted[_j].componentId] = tag; } return this; }; /* retrieve a "master" instance of StyleSheet which is typically used when no other is available * The master StyleSheet is targeted by createGlobalStyle, keyframes, and components outside of any * StyleSheetManager's context */ /* reset the internal "master" instance */ StyleSheet.reset = function reset() { var forceServer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; master = new StyleSheet(undefined, forceServer).rehydrate(); }; /* adds "children" to the StyleSheet that inherit all of the parents' rules * while their own rules do not affect the parent */ StyleSheet.prototype.clone = function clone() { var sheet = new StyleSheet(this.target, this.forceServer); /* add to clone array */ this.clones.push(sheet); /* clone all tags */ sheet.tags = this.tags.map(function (tag) { var ids = tag.getIds(); var newTag = tag.clone(); /* reconstruct tagMap */ for (var i = 0; i < ids.length; i += 1) { sheet.tagMap[ids[i]] = newTag; } return newTag; }); /* clone other maps */ sheet.rehydratedNames = _extends({}, this.rehydratedNames); sheet.deferred = _extends({}, this.deferred); return sheet; }; /* force StyleSheet to create a new tag on the next injection */ StyleSheet.prototype.sealAllTags = function sealAllTags() { this.capacity = 1; this.tags.forEach(function (tag) { // eslint-disable-next-line no-param-reassign tag.sealed = true; }); }; StyleSheet.prototype.makeTag = function makeTag$$1(tag) { var lastEl = tag ? tag.styleTag : null; var insertBefore = false; return makeTag(this.target, lastEl, this.forceServer, insertBefore, this.getImportRuleTag); }; /* get a tag for a given componentId, assign the componentId to one, or shard */ StyleSheet.prototype.getTagForId = function getTagForId(id) { /* simply return a tag, when the componentId was already assigned one */ var prev = this.tagMap[id]; if (prev !== undefined && !prev.sealed) { return prev; } var tag = this.tags[this.tags.length - 1]; /* shard (create a new tag) if the tag is exhausted (See MAX_SIZE) */ this.capacity -= 1; if (this.capacity === 0) { this.capacity = MAX_SIZE; tag = this.makeTag(tag); this.tags.push(tag); } return this.tagMap[id] = tag; }; /* mainly for createGlobalStyle to check for its id */ StyleSheet.prototype.hasId = function hasId(id) { return this.tagMap[id] !== undefined; }; /* caching layer checking id+name to already have a corresponding tag and injected rules */ StyleSheet.prototype.hasNameForId = function hasNameForId(id, name) { /* exception for rehydrated names which are checked separately */ if (this.ignoreRehydratedNames[id] === undefined && this.rehydratedNames[name]) { return true; } var tag = this.tagMap[id]; return tag !== undefined && tag.hasNameForId(id, name); }; /* registers a componentId and registers it on its tag */ StyleSheet.prototype.deferredInject = function deferredInject(id, cssRules) { /* don't inject when the id is already registered */ if (this.tagMap[id] !== undefined) return; var clones = this.clones; for (var i = 0; i < clones.length; i += 1) { clones[i].deferredInject(id, cssRules); } this.getTagForId(id).insertMarker(id); this.deferred[id] = cssRules; }; /* injects rules for a given id with a name that will need to be cached */ StyleSheet.prototype.inject = function inject(id, cssRules, name) { var clones = this.clones; for (var i = 0; i < clones.length; i += 1) { clones[i].inject(id, cssRules, name); } var tag = this.getTagForId(id); /* add deferred rules for component */ if (this.deferred[id] !== undefined) { // Combine passed cssRules with previously deferred CSS rules // NOTE: We cannot mutate the deferred array itself as all clones // do the same (see clones[i].inject) var rules = this.deferred[id].concat(cssRules); tag.insertRules(id, rules, name); this.deferred[id] = undefined; } else { tag.insertRules(id, cssRules, name); } }; /* removes all rules for a given id, which doesn't remove its marker but resets it */ StyleSheet.prototype.remove = function remove(id) { var tag = this.tagMap[id]; if (tag === undefined) return; var clones = this.clones; for (var i = 0; i < clones.length; i += 1) { clones[i].remove(id); } /* remove all rules from the tag */ tag.removeRules(id); /* ignore possible rehydrated names */ this.ignoreRehydratedNames[id] = true; /* delete possible deferred rules */ this.deferred[id] = undefined; }; StyleSheet.prototype.toHTML = function toHTML() { return this.tags.map(function (tag) { return tag.toHTML(); }).join(''); }; StyleSheet.prototype.toReactElements = function toReactElements() { var id = this.id; return this.tags.map(function (tag, i) { var key = 'sc-' + id + '-' + i; return cloneElement(tag.toElement(), { key: key }); }); }; createClass(StyleSheet, null, [{ key: 'master', get: function get$$1() { return master || (master = new StyleSheet().rehydrate()); } /* NOTE: This is just for backwards-compatibility with jest-styled-components */ }, { key: 'instance', get: function get$$1() { return StyleSheet.master; } }]); return StyleSheet; }(); // var Keyframes = function () { function Keyframes(name, rules) { var _this = this; classCallCheck(this, Keyframes); this.inject = function (styleSheet) { if (!styleSheet.hasNameForId(_this.id, _this.name)) { styleSheet.inject(_this.id, _this.rules, _this.name); } }; this.toString = function () { throw new StyledComponentsError(12, String(_this.name)); }; this.name = name; this.rules = rules; this.id = 'sc-keyframes-' + name; } Keyframes.prototype.getName = function getName() { return this.name; }; return Keyframes; }(); // /** * inlined version of * https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/hyphenateStyleName.js */ 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-`. * * @param {string} string * @return {string} */ function hyphenateStyleName(string) { return string.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-'); } // // Taken from https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/shared/dangerousStyleValue.js function addUnitIfNeeded(name, value) { // https://github.com/amilajack/eslint-plugin-flowtype-errors/issues/133 // $FlowFixMe if (value == null || typeof value === 'boolean' || value === '') { return ''; } if (typeof value === 'number' && value !== 0 && !(name in unitless)) { return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers } return String(value).trim(); } // /** * It's falsish not falsy because 0 is allowed. */ var isFalsish = function isFalsish(chunk) { return chunk === undefined || chunk === null || chunk === false || chunk === ''; }; var objToCssArray = function objToCssArray(obj, prevKey) { var rules = []; var keys = Object.keys(obj); keys.forEach(function (key) { if (!isFalsish(obj[key])) { if (isPlainObject(obj[key])) { rules.push.apply(rules, objToCssArray(obj[key], key)); return rules; } else if (isFunction(obj[key])) { rules.push(hyphenateStyleName(key) + ':', obj[key], ';'); return rules; } rules.push(hyphenateStyleName(key) + ': ' + addUnitIfNeeded(key, obj[key]) + ';'); } return rules; }); return prevKey ? [prevKey + ' {'].concat(rules, ['}']) : rules; }; function flatten(chunk, executionContext, styleSheet) { if (Array.isArray(chunk)) { var ruleSet = []; for (var i = 0, len = chunk.length, result; i < len; i += 1) { result = flatten(chunk[i], executionContext, styleSheet); if (result === null) continue;else if (Array.isArray(result)) ruleSet.push.apply(ruleSet, result);else ruleSet.push(result); } return ruleSet; } if (isFalsish(chunk)) { return null; } /* Handle other components */ if (isStyledComponent(chunk)) { return '.' + chunk.styledComponentId; } /* Either execute or defer the function */ if (isFunction(chunk)) { if (isStatelessFunction(chunk) && executionContext) { var _result = chunk(executionContext); if (process.env.NODE_ENV !== 'production' && isElement(_result)) { // eslint-disable-next-line no-console console.warn(getComponentName(chunk) + ' is not a styled component and cannot be referred to via component selector. See https://www.styled-components.com/docs/advanced#referring-to-other-components for more details.'); } return flatten(_result, executionContext, styleSheet); } else return chunk; } if (chunk instanceof Keyframes) { if (styleSheet) { chunk.inject(styleSheet); return chunk.getName(); } else return chunk; } /* Handle objects */ return isPlainObject(chunk) ? objToCssArray(chunk) : chunk.toString(); } // function css(styles) { for (var _len = arguments.length, interpolations = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { interpolations[_key - 1] = arguments[_key]; } if (isFunction(styles) || isPlainObject(styles)) { // $FlowFixMe return flatten(interleave(EMPTY_ARRAY, [styles].concat(interpolations))); } // $FlowFixMe return flatten(interleave(styles, interpolations)); } // function constructWithOptions(componentConstructor, tag) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : EMPTY_OBJECT; if (!isValidElementType(tag)) { throw new StyledComponentsError(1, String(tag)); } /* This is callable directly as a template function */ // $FlowFixMe: Not typed to avoid destructuring arguments var templateFunction = function templateFunction() { return componentConstructor(tag, options, css.apply(undefined, arguments)); }; /* If config methods are called, wrap up a new template function and merge options */ templateFunction.withConfig = function (config) { return constructWithOptions(componentConstructor, tag, _extends({}, options, config)); }; /* Modify/inject new props at runtime */ templateFunction.attrs = function (attrs) { return constructWithOptions(componentConstructor, tag, _extends({}, options, { attrs: Array.prototype.concat(options.attrs, attrs).filter(Boolean) })); }; return templateFunction; } // // Source: https://github.com/garycourt/murmurhash-js/blob/master/murmurhash2_gc.js function murmurhash(c) { for (var e = c.length | 0, a = e | 0, d = 0, b; e >= 4;) { b = c.charCodeAt(d) & 255 | (c.charCodeAt(++d) & 255) << 8 | (c.charCodeAt(++d) & 255) << 16 | (c.charCodeAt(++d) & 255) << 24, b = 1540483477 * (b & 65535) + ((1540483477 * (b >>> 16) & 65535) << 16), b ^= b >>> 24, b = 1540483477 * (b & 65535) + ((1540483477 * (b >>> 16) & 65535) << 16), a = 1540483477 * (a & 65535) + ((1540483477 * (a >>> 16) & 65535) << 16) ^ b, e -= 4, ++d; } switch (e) { case 3: a ^= (c.charCodeAt(d + 2) & 255) << 16; case 2: a ^= (c.charCodeAt(d + 1) & 255) << 8; case 1: a ^= c.charCodeAt(d) & 255, a = 1540483477 * (a & 65535) + ((1540483477 * (a >>> 16) & 65535) << 16); } a ^= a >>> 13; a = 1540483477 * (a & 65535) + ((1540483477 * (a >>> 16) & 65535) << 16); return (a ^ a >>> 15) >>> 0; } // /* eslint-disable no-bitwise */ /* This is the "capacity" of our alphabet i.e. 2x26 for all letters plus their capitalised * counterparts */ var charsLength = 52; /* start at 75 for 'a' until 'z' (25) and then start at 65 for capitalised letters */ var getAlphabeticChar = function getAlphabeticChar(code) { return String.fromCharCode(code + (code > 25 ? 39 : 97)); }; /* input a number, usually a hash and convert it to base-52 */ function generateAlphabeticName(code) { var name = ''; var x = void 0; /* get a char and divide by alphabet-length */ for (x = code; x > charsLength; x = Math.floor(x / charsLength)) { name = getAlphabeticChar(x % charsLength) + name; } return getAlphabeticChar(x % charsLength) + name; } // function hasFunctionObjectKey(obj) { // eslint-disable-next-line guard-for-in, no-restricted-syntax for (var key in obj) { if (isFunction(obj[key])) { return true; } } return false; } function isStaticRules(rules, attrs) { for (var i = 0; i < rules.length; i += 1) { var rule = rules[i]; // recursive case if (Array.isArray(rule) && !isStaticRules(rule, attrs)) { return false; } else if (isFunction(rule) && !isStyledComponent(rule)) { // functions are allowed to be static if they're just being // used to get the classname of a nested styled component return false; } } if (attrs.some(function (x) { return isFunction(x) || hasFunctionObjectKey(x); })) return false; return true; } // /* combines hashStr (murmurhash) and nameGenerator for convenience */ var hasher = function hasher(str) { return generateAlphabeticName(murmurhash(str)); }; /* ComponentStyle is all the CSS-specific stuff, not the React-specific stuff. */ var ComponentStyle = function () { function ComponentStyle(rules, attrs, componentId) { classCallCheck(this, ComponentStyle); this.rules = rules; this.isStatic = process.env.NODE_ENV === 'production' && isStaticRules(rules, attrs); this.componentId = componentId; if (!StyleSheet.master.hasId(componentId)) { StyleSheet.master.deferredInject(componentId, []); } } /* * Flattens a rule set into valid CSS * Hashes it, wraps the whole chunk in a .hash1234 {} * Returns the hash to be injected on render() * */ ComponentStyle.prototype.generateAndInjectStyles = function generateAndInjectStyles(executionContext, styleSheet) { var isStatic = this.isStatic, componentId = this.componentId, lastClassName = this.lastClassName; if (IS_BROWSER && isStatic && typeof lastClassName === 'string' && styleSheet.hasNameForId(componentId, lastClassName)) { return lastClassName; } var flatCSS = flatten(this.rules, executionContext, styleSheet); var name = hasher(this.componentId + flatCSS.join('')); if (!styleSheet.hasNameForId(componentId, name)) { styleSheet.inject(this.componentId, stringifyRules(flatCSS, '.' + name, undefined, componentId), name); } this.lastClassName = name; return name; }; ComponentStyle.generateName = function generateName(str) { return hasher(str); }; return ComponentStyle; }(); // var LIMIT = 200; var createWarnTooManyClasses = (function (displayName) { var generatedClasses = {}; var warningSeen = false; return function (className) { if (!warningSeen) { generatedClasses[className] = true; if (Object.keys(generatedClasses).length >= LIMIT) { // Unable to find latestRule in test environment. /* eslint-disable no-console, prefer-template */ console.warn('Over ' + LIMIT + ' classes were generated for component ' + displayName + '. \n' + 'Consider using the attrs method, together with a style object for frequently changed styles.\n' + 'Example:\n' + ' const Component = styled.div.attrs(props => ({\n' + ' style: {\n' + ' background: props.background,\n' + ' },\n' + ' }))`width: 100%;`\n\n' + '