'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var hyphenate = _interopDefault(require('fbjs/lib/hyphenateStyleName')); var React = require('react'); var React__default = _interopDefault(React); var Stylis = _interopDefault(require('stylis')); var _insertRulePlugin = _interopDefault(require('stylis-rule-sheet')); var PropTypes = _interopDefault(require('prop-types')); var stream = _interopDefault(require('stream')); var hoistStatics = _interopDefault(require('hoist-non-react-statics')); var reactIs = require('react-is'); 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; }); // /** * 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": "A plain React class (%s) has been interpolated into styles, probably as a component selector (https://www.styled-components.com/docs/advanced#referring-to-other-components). Only styled-component classes can be targeted in this fashion." } : {}; /** * super basic version of sprintf */ function format() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var a = args[0]; var b = []; var c = void 0; for (c = 1; c < args.length; c += 1) { b.push(args[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 _len2 = arguments.length, interpolations = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { interpolations[_key2 - 1] = arguments[_key2]; } 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/src/utils/errors.md#' + code + ' for more information. ' + (interpolations ? 'Additional arguments: ' + interpolations.join(', ') : ''))); } else { var _this = possibleConstructorReturn(this, _Error.call(this, format.apply(undefined, [ERRORS[code]].concat(interpolations)))); } return possibleConstructorReturn(_this); } return StyledComponentsError; }(Error); // var objToCss = function objToCss(obj, prevKey) { var css = Object.keys(obj).filter(function (key) { var chunk = obj[key]; return chunk !== undefined && chunk !== null && chunk !== false && chunk !== ''; }).map(function (key) { if (isPlainObject(obj[key])) return objToCss(obj[key], key); return hyphenate(key) + ': ' + obj[key] + ';'; }).join(' '); return prevKey ? prevKey + ' {\n ' + css + '\n}' : css; }; var flatten = function flatten(chunks, executionContext) { return chunks.reduce(function (ruleSet, chunk) { /* Remove falsey values */ if (chunk === undefined || chunk === null || chunk === false || chunk === '') { return ruleSet; } /* Flatten ruleSet */ if (Array.isArray(chunk)) { ruleSet.push.apply(ruleSet, flatten(chunk, executionContext)); return ruleSet; } /* Handle other components */ if (chunk.hasOwnProperty('styledComponentId')) { // $FlowFixMe not sure how to make this pass ruleSet.push('.' + chunk.styledComponentId); return ruleSet; } /* Either execute or defer the function */ if (typeof chunk === 'function') { if (executionContext) { var nextChunk = chunk(executionContext); /* Throw if a React Element was given styles */ if (React__default.isValidElement(nextChunk)) { var elementName = chunk.displayName || chunk.name; throw new StyledComponentsError(11, elementName); } ruleSet.push.apply(ruleSet, flatten([nextChunk], executionContext)); } else ruleSet.push(chunk); return ruleSet; } /* Handle objects */ ruleSet.push( // $FlowFixMe have to add %checks somehow to isPlainObject isPlainObject(chunk) ? objToCss(chunk) : chunk.toString()); return ruleSet; }, []); }; // var isRuleSet = function isRuleSet(interpolation) { return !!(interpolation && Array.isArray(interpolation) && interpolation.length > 0 && interpolation[0] && Array.isArray(interpolation[0])); }; var flatten$1 = function flatten$$1(chunks, executionContext) { /* Fall back to old flattener for non-rule-set chunks */ if (!isRuleSet(chunks)) { return flatten(chunks, executionContext); } return chunks.reduce(function (ruleSet, chunk) { if (!Array.isArray(chunk)) { return ruleSet; } var appendChunks = []; var newChunk = chunk.reduce(function (rules, rule) { /* Remove falsey values */ if (rule === undefined || rule === null || rule === false || rule === '') { return rules; } /* Flatten nested rule set */ if (isRuleSet(rule)) { // $FlowFixMe Don't know what's wrong here appendChunks = [].concat(appendChunks, flatten$$1(rule, executionContext)); return rules; } /* Stringify unexpected array */ if (Array.isArray(rule)) { return [].concat(rules, flatten(rule, executionContext)); } /* Either execute or defer the function */ if (typeof rule === 'function') { if (executionContext) { var res = rule(executionContext); if (isRuleSet(res)) { appendChunks = [].concat(appendChunks, flatten$$1(res, executionContext)); return rules; } /* Flatten non-ruleset values */ return [].concat(rules, flatten$$1([res], executionContext)); } else { return [].concat(rules, [rule]); } } /* Handle other components */ if ((typeof rule === 'undefined' ? 'undefined' : _typeof(rule)) === 'object' && rule.hasOwnProperty('styledComponentId')) { return [].concat(rules, ['.' + rule.styledComponentId]); } /* Convert object to css string */ if ((typeof rule === 'undefined' ? 'undefined' : _typeof(rule)) === 'object' && isPlainObject(rule)) { return [].concat(rules, [objToCss(rule)]); } return [].concat(rules, [rule.toString()]); }, []); if (executionContext) { var newChunkStr = newChunk.join(''); if (appendChunks.length) { return [].concat(ruleSet, [newChunkStr], appendChunks); } return [].concat(ruleSet, [newChunkStr]); } return [].concat(ruleSet, [newChunk], appendChunks); }, []); }; // var stringifyRules = function stringifyRules(rules, selector, prefix) { return [rules.reduce(function (str, partial, index) { return str + ( // NOTE: This is to not prefix keyframes with the animation name (index > 0 || !prefix) && selector ? selector : '') + (partial && Array.isArray(partial) ? partial.join('') : partial.toString()); }, '')]; }; // var css = (function (interpolations) { return flatten$1(interpolations); }); // function isStyledComponent(target) /* : %checks */{ return ( // $FlowFixMe TODO: flow for styledComponentId typeof target === 'function' && typeof target.styledComponentId === 'string' ); } // /* This function is DEPRECATED and will be removed on the next major version release. * It was needed to rehydrate all style blocks prepended to chunks before React * tries to rehydrate its HTML stream. Since the master StyleSheet will now detect * the use of streamed style tags and will perform the rehydration earlier when needed * this function will not be needed anymore */ function consolidateStreamedStyles() { if (process.env.NODE_ENV !== 'production') { // eslint-disable-next-line no-console console.warn('styled-components automatically does streaming SSR rehydration now.\n' + 'Calling consolidateStreamedStyles manually is no longer necessary and a noop now.\n' + '- Please remove the consolidateStreamedStyles call from your client.'); } } // /* 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 */ var generateAlphabeticName = 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; }; // var SC_ATTR = typeof process !== 'undefined' && process.env.SC_ATTR || 'data-styled-components'; var SC_STREAM_ATTR = 'data-styled-streamed'; var CONTEXT_KEY = '__styled-components-stylesheet__'; var IS_BROWSER = typeof window !== 'undefined' && 'HTMLElement' in window; var DISABLE_SPEEDY = process.env.NODE_ENV !== 'production'; // 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 }; }); }); // // 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); }); stylis.use([parseRulesPlugin, returnRulesPlugin]); stylisSplitter.use([parseRulesPlugin, returnRulesPlugin]); var splitByRules = function splitByRules(css) { return stylisSplitter('', css); }; // /* eslint-disable camelcase, no-undef */ var getNonce = (function () { return typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null; }); // // Helper to call a given function, only once var once = (function (cb) { var called = false; return function () { if (!called) { called = true; cb(); } }; }); // /* 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 = document.styleSheets.length; for (var i = 0; i < size; i += 1) { var sheet = document.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 el = document.createElement('style'); el.setAttribute(SC_ATTR, ''); var nonce = getNonce(); if (nonce) { el.setAttribute('nonce', nonce); } /* Work around insertRule quirk in EdgeHTML */ el.appendChild(document.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) + '"', 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); var nonce = getNonce(); if (nonce) { // $FlowFixMe props.nonce = nonce; } // eslint-disable-next-line react/no-danger return React__default.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 whther 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; var size = sizes[marker]; var sheet = sheetForTag(el); var removalIndex = addUpUntilIndex(sizes, marker); 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(id) { return document.createTextNode(makeTextMarker(id)); }; var makeBrowserTag = function makeBrowserTag(el, getImportRuleTag) { var names = Object.create(null); var markers = Object.create(null); var extractImport = getImportRuleTag !== undefined; /* indicates whther getImportRuleTag was called */ var usedImportRuleTag = false; var insertMarker = function insertMarker(id) { var prev = markers[id]; if (prev !== undefined) { return prev; } markers[id] = makeTextNode(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(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 makeServerTagInternal = function makeServerTagInternal(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 makeServerTagInternal(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 makeServerTag = function makeServerTag() { return makeServerTagInternal(); }; 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(); }; /* wraps a given tag so that rehydration is performed once when necessary */ var makeRehydrationTag = function makeRehydrationTag(tag, els, extracted, immediateRehydration) { /* rehydration function that adds all rules to the new tag */ var rehydrate = once(function () { /* 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); } } }); if (immediateRehydration) rehydrate(); return _extends({}, tag, { /* add rehydration hook to insertion methods */ insertMarker: function insertMarker(id) { rehydrate(); return tag.insertMarker(id); }, insertRules: function insertRules(id, cssRules, name) { rehydrate(); return tag.insertRules(id, cssRules, name); } }); }; // 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() { 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 + ']'); var nodesSize = nodes.length; /* abort rehydration if no previous style tags were found */ if (nodesSize === 0) { return this; } for (var i = 0; i < nodesSize; i += 1) { // $FlowFixMe: We can trust that all elements in this query are style elements 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; j < elNamesSize; j += 1) { var name = elNames[j]; /* add rehydrated name to sheet to avoid readding 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 === 0) { return this; } /* create a tag to be used for rehydration */ var tag = this.makeTag(null); var rehydrationTag = makeRehydrationTag(tag, els, extracted, isStreamed); /* reset capacity and adjust MAX_SIZE by the initial size of the rehydration */ this.capacity = Math.max(1, MAX_SIZE - extractedSize); this.tags.push(rehydrationTag); /* retrieve all component ids */ for (var _j = 0; _j < extractedSize; _j += 1) { this.tagMap[extracted[_j].componentId] = rehydrationTag; } return this; }; /* retrieve a "master" instance of StyleSheet which is typically used when no other is available * The master StyleSheet is targeted by injectGlobal, 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 injectGlobal 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 React.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 _StyleSheetManager$ch; var StyleSheetManager = function (_Component) { inherits(StyleSheetManager, _Component); function StyleSheetManager() { classCallCheck(this, StyleSheetManager); return possibleConstructorReturn(this, _Component.apply(this, arguments)); } StyleSheetManager.prototype.getChildContext = function getChildContext() { var _ref; return _ref = {}, _ref[CONTEXT_KEY] = this.sheetInstance, _ref; }; StyleSheetManager.prototype.componentWillMount = function componentWillMount() { if (this.props.sheet) { this.sheetInstance = this.props.sheet; } else if (this.props.target) { this.sheetInstance = new StyleSheet(this.props.target); } else { throw new StyledComponentsError(4); } }; StyleSheetManager.prototype.render = function render() { /* eslint-disable react/prop-types */ // Flow v0.43.1 will report an error accessing the `children` property, // but v0.47.0 will not. It is necessary to use a type cast instead of // a "fixme" comment to satisfy both Flow versions. return React__default.Children.only(this.props.children); }; return StyleSheetManager; }(React.Component); StyleSheetManager.childContextTypes = (_StyleSheetManager$ch = {}, _StyleSheetManager$ch[CONTEXT_KEY] = PropTypes.oneOfType([PropTypes.instanceOf(StyleSheet), PropTypes.instanceOf(ServerStyleSheet)]).isRequired, _StyleSheetManager$ch); process.env.NODE_ENV !== "production" ? StyleSheetManager.propTypes = { sheet: PropTypes.oneOfType([PropTypes.instanceOf(StyleSheet), PropTypes.instanceOf(ServerStyleSheet)]), target: PropTypes.shape({ appendChild: PropTypes.func.isRequired }) } : void 0; // var ServerStyleSheet = function () { function ServerStyleSheet() { classCallCheck(this, ServerStyleSheet); /* The master sheet might be reset, so keep a reference here */ this.masterSheet = StyleSheet.master; this.instance = this.masterSheet.clone(); this.closed = false; } ServerStyleSheet.prototype.complete = function complete() { if (!this.closed) { /* Remove closed StyleSheets from the master sheet */ var index = this.masterSheet.clones.indexOf(this.instance); this.masterSheet.clones.splice(index, 1); this.closed = true; } }; ServerStyleSheet.prototype.collectStyles = function collectStyles(children) { if (this.closed) { throw new StyledComponentsError(2); } return React__default.createElement( StyleSheetManager, { sheet: this.instance }, children ); }; ServerStyleSheet.prototype.getStyleTags = function getStyleTags() { this.complete(); return this.instance.toHTML(); }; ServerStyleSheet.prototype.getStyleElement = function getStyleElement() { this.complete(); return this.instance.toReactElements(); }; ServerStyleSheet.prototype.interleaveWithNodeStream = function interleaveWithNodeStream(readableStream) { var _this = this; if (IS_BROWSER) { throw new StyledComponentsError(3); } /* the tag index keeps track of which tags have already been emitted */ var instance = this.instance; var instanceTagIndex = 0; var streamAttr = SC_STREAM_ATTR + '="true"'; var transformer = new stream.Transform({ transform: function appendStyleChunks(chunk, /* encoding */_, callback) { var tags = instance.tags; var html = ''; /* retrieve html for each new style tag */ for (; instanceTagIndex < tags.length; instanceTagIndex += 1) { var tag = tags[instanceTagIndex]; html += tag.toHTML(streamAttr); } /* force our StyleSheets to emit entirely new tags */ instance.sealAllTags(); /* prepend style html to chunk */ this.push(html + chunk); callback(); } }); readableStream.on('end', function () { return _this.complete(); }); readableStream.on('error', function (err) { _this.complete(); // forward the error to the transform stream transformer.emit('error', err); }); return readableStream.pipe(transformer); }; return ServerStyleSheet; }(); // 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({\n' + ' style: ({ background }) => ({\n' + ' background,\n' + ' }),\n' + ' })`width: 100%;`\n\n' + '