styled-components 3.1.5 → 3.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -1
- package/dist/styled-components-no-parser.browser.cjs.js +9 -3
- package/dist/styled-components-no-parser.browser.cjs.js.map +1 -1
- package/dist/styled-components-no-parser.browser.es.js +9 -3
- package/dist/styled-components-no-parser.browser.es.js.map +1 -1
- package/dist/styled-components-no-parser.cjs.js +16 -9
- package/dist/styled-components-no-parser.cjs.js.map +1 -1
- package/dist/styled-components-no-parser.es.js +16 -9
- package/dist/styled-components-no-parser.es.js.map +1 -1
- package/dist/styled-components.browser.cjs.js +9 -3
- package/dist/styled-components.browser.cjs.js.map +1 -1
- package/dist/styled-components.browser.es.js +9 -3
- package/dist/styled-components.browser.es.js.map +1 -1
- package/dist/styled-components.cjs.js +16 -9
- package/dist/styled-components.cjs.js.map +1 -1
- package/dist/styled-components.es.js +16 -9
- package/dist/styled-components.es.js.map +1 -1
- package/dist/styled-components.js +9 -3
- package/dist/styled-components.js.map +1 -1
- package/dist/styled-components.min.js +1 -1
- package/dist/styled-components.min.js.map +1 -1
- package/package.json +1 -1
- package/src/models/BrowserStyleSheet.js +5 -1
- package/src/models/ServerStyleSheet.js +9 -11
- package/src/models/StyleSheet.js +10 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,12 @@ All notable changes to this project will be documented in this file. If a contri
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## [v3.1.6] - 2018-02-03
|
|
10
|
+
|
|
11
|
+
- Bugfix for the last style tag sometimes being emitted multiple times during streaming ([see #1479](https://github.com/styled-components/styled-components/pull/1479))
|
|
12
|
+
|
|
13
|
+
- Bugfix for speedy mode rehydration and added handling for out-of-order style injection ([see #1482](https://github.com/styled-components/styled-components/pull/1482))
|
|
14
|
+
|
|
9
15
|
## [v3.1.5] - 2018-02-01
|
|
10
16
|
|
|
11
17
|
- Apply a workaround to re-enable "speedy" mode for IE/Edge ([see #1468](https://github.com/styled-components/styled-components/pull/1468))
|
|
@@ -385,7 +391,8 @@ All notable changes to this project will be documented in this file. If a contri
|
|
|
385
391
|
|
|
386
392
|
- Fixed compatibility with other react-broadcast-based systems (like `react-router` v4)
|
|
387
393
|
|
|
388
|
-
[Unreleased]: https://github.com/styled-components/styled-components/compare/v3.1.
|
|
394
|
+
[Unreleased]: https://github.com/styled-components/styled-components/compare/v3.1.6...master
|
|
395
|
+
[v3.1.6]: https://github.com/styled-components/styled-components/compare/v3.1.5...v3.1.6
|
|
389
396
|
[v3.1.5]: https://github.com/styled-components/styled-components/compare/v3.1.4...v3.1.5
|
|
390
397
|
[v3.1.4]: https://github.com/styled-components/styled-components/compare/v3.1.3...v3.1.4
|
|
391
398
|
[v3.1.3]: https://github.com/styled-components/styled-components/compare/v3.1.1...v3.1.3
|
|
@@ -693,7 +693,7 @@ var BrowserStyleSheet = {
|
|
|
693
693
|
});
|
|
694
694
|
}
|
|
695
695
|
|
|
696
|
-
tags.push(new BrowserTag(el, el.getAttribute(LOCAL_ATTR) === 'true', el.
|
|
696
|
+
tags.push(new BrowserTag(el, el.getAttribute(LOCAL_ATTR) === 'true', el.textContent));
|
|
697
697
|
}
|
|
698
698
|
|
|
699
699
|
/* Factory for making more tags */
|
|
@@ -740,6 +740,7 @@ var StyleSheet = function () {
|
|
|
740
740
|
this.tags = tags;
|
|
741
741
|
this.names = names;
|
|
742
742
|
this.constructComponentTagMap();
|
|
743
|
+
this.isStreaming = false;
|
|
743
744
|
}
|
|
744
745
|
|
|
745
746
|
// helper for `ComponentStyle` to know when it cache static styles.
|
|
@@ -835,7 +836,12 @@ var StyleSheet = function () {
|
|
|
835
836
|
|
|
836
837
|
StyleSheet.prototype.getOrCreateTag = function getOrCreateTag(componentId, isLocal) {
|
|
837
838
|
var existingTag = this.componentTags[componentId];
|
|
838
|
-
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* in a streaming context, once a tag is sealed it can never be added to again
|
|
842
|
+
* or those styles will never make it to the client
|
|
843
|
+
*/
|
|
844
|
+
if (existingTag && this.isStreaming ? !existingTag.isSealed() : existingTag) {
|
|
839
845
|
return existingTag;
|
|
840
846
|
}
|
|
841
847
|
|
|
@@ -1033,7 +1039,7 @@ var ServerStyleSheet = function () {
|
|
|
1033
1039
|
classCallCheck(this, ServerStyleSheet);
|
|
1034
1040
|
|
|
1035
1041
|
this.instance = StyleSheet.clone(StyleSheet.instance);
|
|
1036
|
-
this.isStreaming = false;
|
|
1042
|
+
this.instance.isStreaming = false;
|
|
1037
1043
|
}
|
|
1038
1044
|
|
|
1039
1045
|
ServerStyleSheet.prototype.collectStyles = function collectStyles(children) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styled-components-no-parser.browser.cjs.js","sources":["../src/models/BrowserStyleSheet.js","../src/models/StyleSheet.js","../src/models/ServerStyleSheet.js","../src/models/ThemeProvider.js","../src/models/StyledComponent.js","../src/models/ComponentStyle.js","../src/constructors/styled.js","../src/constructors/keyframes.js"],"sourcesContent":["// @flow\n/* eslint-disable no-underscore-dangle */\n/*\n * Browser Style Sheet with Rehydration\n *\n * <style data-styled-components=\"x y z\"\n * data-styled-components-is-local=\"true\">\n * /· sc-component-id: a ·/\n * .sc-a { ... }\n * .x { ... }\n * /· sc-component-id: b ·/\n * .sc-b { ... }\n * .y { ... }\n * .z { ... }\n * </style>\n *\n * Note: replace · with * in the above snippet.\n * */\nimport extractCompsFromCSS from '../utils/extractCompsFromCSS'\nimport stringifyRules from '../utils/stringifyRules'\nimport getNonce from '../utils/nonce'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR } from './StyleSheet'\n\ndeclare var __DEV__: ?string\n\nconst DISABLE_SPEEDY =\n (typeof __DEV__ === 'boolean' && __DEV__) ||\n process.env.NODE_ENV !== 'production'\n\nconst COMPONENTS_PER_TAG = 40\nconst SPEEDY_COMPONENTS_PER_TAG = 1000 // insertRule allows more injections before a perf slowdown\n\n// Source: https://github.com/threepointone/glamor/blob/master/src/sheet.js#L32-L43\nconst sheetForTag = (tag: HTMLStyleElement): CSSStyleSheet => {\n if (tag.sheet) {\n // $FlowFixMe\n return tag.sheet\n }\n\n for (let i = 0; i < document.styleSheets.length; i += 1) {\n if (document.styleSheets[i].ownerNode === tag) {\n // $FlowFixMe\n return document.styleSheets[i]\n }\n }\n\n // NOTE: This should never happen\n throw new Error('')\n}\n\n// Safely (try/catch) injects rule at index and returns whether it was successful\nconst safeInsertRule = (\n sheet: CSSStyleSheet,\n cssRule: string,\n index: number\n): boolean => {\n if (cssRule === undefined || cssRule.length === 0) {\n return false\n }\n\n const maxIndex = sheet.cssRules.length\n const cappedIndex = index <= maxIndex ? index : maxIndex\n\n try {\n sheet.insertRule(cssRule, cappedIndex)\n } catch (err) {\n // NOTE: An invalid rule here means it's not supported by the browser or obviously malformed\n return false\n }\n\n return true\n}\n\n// Counts up the number of rules inside the array until a specific component entry is found\n// This is used to determine the necessary insertRule index\nconst sizeUpToComponentIndex = (\n componentSizes: Array<number>,\n componentIndex: number\n) => {\n let cssRulesSize = 0\n for (let i = 0; i <= componentIndex; i += 1) {\n cssRulesSize += componentSizes[i]\n }\n\n return cssRulesSize\n}\n\nclass BaseBrowserTag {\n components: { [string]: Object }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n}\n\nlet BrowserTag\nif (!DISABLE_SPEEDY) {\n BrowserTag = class SpeedyBrowserTag extends BaseBrowserTag implements Tag {\n // Store component ruleSizes in an array per component (in order)\n componentSizes: Array<number>\n components: { [string]: Object }\n\n isLocal: boolean\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: ?string\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.componentSizes = []\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // workaround for an IE/Edge bug: https://twitter.com/probablyup/status/958138927981977600\n newEl.appendChild(document.createTextNode(''))\n\n // $FlowFixMe\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n this.ready = true\n\n // Retrieve the sheet for the new style tag\n const sheet = sheetForTag(newEl)\n\n Object.keys(this.components).forEach(componentId => {\n const comp = this.components[componentId]\n const { cssFromDOM } = comp\n const rules = stringifyRules([cssFromDOM])\n const rulesSize = rules.length\n\n let injectedRules = 0\n for (let j = 0; j < rulesSize; j += 1) {\n if (safeInsertRule(sheet, rules[j], sheet.cssRules.length)) {\n injectedRules += 1\n }\n }\n\n comp.componentIndex = this.componentSizes.length\n comp.css = rules.join(' ')\n this.componentSizes.push(injectedRules)\n })\n }\n\n isSealed() {\n return this.size >= SPEEDY_COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n this.components[componentId] = {\n componentIndex: this.componentSizes.length,\n css: '',\n }\n\n this.componentSizes.push(0)\n this.size += 1\n }\n\n inject(componentId: string, cssRules: Array<string>, name: ?string) {\n if (!this.ready) this.replaceElement()\n\n const comp = this.components[componentId]\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n const cssRulesSize = cssRules.length\n const sheet = sheetForTag(this.el)\n const { componentIndex } = comp\n\n // Determine start index for injection\n const insertIndex = sizeUpToComponentIndex(\n this.componentSizes,\n componentIndex\n )\n\n // Inject each rule shifting index forward for each one (in-order injection)\n let injectedRules = 0\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = cssRules[i]\n if (safeInsertRule(sheet, cssRule, insertIndex + injectedRules)) {\n comp.css += ` ${cssRule}`\n injectedRules += 1\n }\n }\n\n // Update number of rules for component\n this.componentSizes[componentIndex] += injectedRules\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toRawCSS() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n\n toHTML() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n }\n} else {\n BrowserTag = class TextNodeBrowserTag extends BaseBrowserTag implements Tag {\n isLocal: boolean\n components: { [string]: Object }\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: string = ''\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce !== null) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n isSealed() {\n return this.size >= COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n const comp = { componentId, textNode: document.createTextNode('') }\n this.el.appendChild(comp.textNode)\n this.size += 1\n this.components[componentId] = comp\n }\n\n inject(componentId: string, css: Array<string>, name: ?string) {\n if (!this.ready) this.replaceElement()\n const comp = this.components[componentId]\n\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n if (comp.textNode.data === '') {\n comp.textNode.appendData(`\\n/* sc-component-id: ${componentId} */\\n`)\n }\n\n comp.textNode.appendData(css.join(' '))\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toHTML() {\n return this.el.outerHTML\n }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n this.ready = true\n // We have nothing to inject. Use the current el.\n if (this.size === 0) return\n\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n newEl.appendChild(document.createTextNode('\\n'))\n\n Object.keys(this.components).forEach(key => {\n const comp = this.components[key]\n\n // eslint-disable-next-line no-param-reassign\n comp.textNode = document.createTextNode(comp.cssFromDOM)\n newEl.appendChild(comp.textNode)\n })\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // The ol' switcheroo\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n }\n }\n}\n\n/* Factory function to separate DOM operations from logical ones*/\nexport default {\n create() {\n const tags = []\n const names = {}\n\n /* Construct existing state from DOM */\n const nodes = document.querySelectorAll(`[${SC_ATTR}]`)\n const nodesLength = nodes.length\n\n for (let i = 0; i < nodesLength; i += 1) {\n // $FlowFixMe: We can trust that all elements in this query are style elements\n const el = (nodes[i]: HTMLStyleElement)\n const attr = el.getAttribute(SC_ATTR)\n\n if (attr) {\n attr\n .trim()\n .split(/\\s+/)\n .forEach(name => {\n names[name] = true\n })\n }\n\n tags.push(\n new BrowserTag(el, el.getAttribute(LOCAL_ATTR) === 'true', el.innerHTML)\n )\n }\n\n /* Factory for making more tags */\n const tagConstructor = (isLocal: boolean): Tag => {\n const el = document.createElement('style')\n el.type = 'text/css'\n el.setAttribute(SC_ATTR, '')\n el.setAttribute(LOCAL_ATTR, isLocal ? 'true' : 'false')\n if (!document.head) {\n throw new Error(\n process.env.NODE_ENV !== 'production' ? 'Missing document <head>' : ''\n )\n }\n document.head.appendChild(el)\n return new BrowserTag(el, isLocal)\n }\n\n return new StyleSheet(tagConstructor, tags, names)\n },\n}\n","// @flow\nimport React from 'react'\nimport BrowserStyleSheet from './BrowserStyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\nexport const SC_ATTR = 'data-styled-components'\nexport const LOCAL_ATTR = 'data-styled-components-is-local'\nexport const CONTEXT_KEY = '__styled-components-stylesheet__'\n\n/* eslint-disable flowtype/object-type-delimiter */\nexport interface Tag {\n isLocal: boolean;\n\n isSealed(): boolean;\n getComponentIds(): Array<string>;\n addComponent(componentId: string): void;\n inject(componentId: string, css: Array<string>, name: ?string): void;\n toHTML(): string;\n toReactElement(key: string): React.Element<*>;\n clone(): Tag;\n}\n/* eslint-enable flowtype/object-type-delimiter */\n\nlet instance = null\n// eslint-disable-next-line no-use-before-define\nexport const clones: Array<StyleSheet> = []\n\nconst IS_BROWSER = typeof document !== 'undefined'\n\nexport default class StyleSheet {\n tagConstructor: boolean => Tag\n tags: Array<Tag>\n names: { [string]: boolean }\n hashes: { [string]: string } = {}\n deferredInjections: { [string]: Array<string> } = {}\n componentTags: { [string]: Tag }\n\n // helper for `ComponentStyle` to know when it cache static styles.\n // staticly styled-component can not safely cache styles on the server\n // without all `ComponentStyle` instances saving a reference to the\n // the styleSheet instance they last rendered with,\n // or listening to creation / reset events. otherwise you might create\n // a component with one stylesheet and render it another api response\n // with another, losing styles on from your server-side render.\n stylesCacheable = IS_BROWSER\n\n constructor(\n tagConstructor: boolean => Tag,\n tags: Array<Tag> = [],\n names: { [string]: boolean } = {}\n ) {\n this.tagConstructor = tagConstructor\n this.tags = tags\n this.names = names\n this.constructComponentTagMap()\n }\n\n constructComponentTagMap() {\n this.componentTags = {}\n\n this.tags.forEach(tag => {\n tag.getComponentIds().forEach(componentId => {\n this.componentTags[componentId] = tag\n })\n })\n }\n\n /* Best level of caching—get the name from the hash straight away. */\n getName(hash: any) {\n return this.hashes[hash.toString()]\n }\n\n /* Second level of caching—if the name is already in the dom, don't\n * inject anything and record the hash for getName next time. */\n alreadyInjected(hash: any, name: string) {\n if (!this.names[name]) return false\n\n this.hashes[hash.toString()] = name\n return true\n }\n\n /* Third type of caching—don't inject components' componentId twice. */\n hasInjectedComponent(componentId: string) {\n return !!this.componentTags[componentId]\n }\n\n deferredInject(componentId: string, isLocal: boolean, css: Array<string>) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.deferredInject(componentId, isLocal, css)\n })\n }\n\n this.getOrCreateTag(componentId, isLocal)\n this.deferredInjections[componentId] = css\n }\n\n inject(\n componentId: string,\n isLocal: boolean,\n css: Array<string>,\n hash: ?any,\n name: ?string\n ) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.inject(componentId, isLocal, css)\n })\n }\n\n const tag = this.getOrCreateTag(componentId, isLocal)\n\n const deferredInjection = this.deferredInjections[componentId]\n if (deferredInjection) {\n tag.inject(componentId, deferredInjection)\n delete this.deferredInjections[componentId]\n }\n\n tag.inject(componentId, css, name)\n\n if (hash && name) {\n this.hashes[hash.toString()] = name\n }\n }\n\n toHTML() {\n return this.tags.map(tag => tag.toHTML()).join('')\n }\n\n toReactElements() {\n return this.tags.map((tag, i) => tag.toReactElement(`sc-${i}`))\n }\n\n getOrCreateTag(componentId: string, isLocal: boolean) {\n const existingTag = this.componentTags[componentId]\n if (existingTag) {\n return existingTag\n }\n\n const lastTag = this.tags[this.tags.length - 1]\n const componentTag =\n !lastTag || lastTag.isSealed() || lastTag.isLocal !== isLocal\n ? this.createNewTag(isLocal)\n : lastTag\n this.componentTags[componentId] = componentTag\n componentTag.addComponent(componentId)\n return componentTag\n }\n\n createNewTag(isLocal: boolean) {\n const newTag = this.tagConstructor(isLocal)\n this.tags.push(newTag)\n return newTag\n }\n\n static get instance() {\n return instance || (instance = StyleSheet.create())\n }\n\n static reset(isServer: ?boolean) {\n instance = StyleSheet.create(isServer)\n }\n\n /* We can make isServer totally implicit once Jest 20 drops and we\n * can change environment on a per-test basis. */\n static create(isServer: ?boolean = !IS_BROWSER) {\n return (isServer ? ServerStyleSheet : BrowserStyleSheet).create()\n }\n\n static clone(oldSheet: StyleSheet) {\n const newSheet = new StyleSheet(\n oldSheet.tagConstructor,\n oldSheet.tags.map(tag => tag.clone()),\n { ...oldSheet.names }\n )\n\n newSheet.hashes = { ...oldSheet.hashes }\n newSheet.deferredInjections = { ...oldSheet.deferredInjections }\n clones.push(newSheet)\n\n return newSheet\n }\n}\n","// @flow\n/* eslint-disable no-underscore-dangle */\nimport React from 'react'\nimport stream from 'stream'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR, clones } from './StyleSheet'\nimport StyleSheetManager from './StyleSheetManager'\nimport getNonce from '../utils/nonce'\n\ndeclare var __SERVER__: boolean\n\nclass ServerTag implements Tag {\n emitted: boolean\n isLocal: boolean\n isProduction: boolean\n components: { [string]: Object }\n size: number\n names: Array<string>\n\n constructor(isLocal: boolean) {\n this.emitted = false\n this.isLocal = isLocal\n this.isProduction = process.env.NODE_ENV === 'production'\n this.components = {}\n this.size = 0\n this.names = []\n }\n\n isSealed() {\n return this.emitted\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n\n addComponent(componentId: string) {\n if (this.components[componentId]) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? `Trying to add Component '${componentId}' twice!`\n : ''\n )\n }\n this.components[componentId] = { componentId, css: '' }\n this.size += 1\n }\n\n concatenateCSS() {\n return Object.keys(this.components).reduce(\n (styles, k) => styles + this.components[k].css,\n ''\n )\n }\n\n inject(componentId: string, css: Array<string>, name: ?string) {\n const comp = this.components[componentId]\n\n if (!comp) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'Must add a new component before you can inject css into it'\n : ''\n )\n }\n\n if (comp.css === '') {\n comp.css = `/* sc-component-id: ${componentId} */\\n`\n }\n\n const cssRulesSize = css.length\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = css[i]\n comp.css += `${cssRule}\\n`.replace(/\\n*$/, '\\n')\n }\n\n if (name) this.names.push(name)\n }\n\n toHTML() {\n const attrs: Array<string> = [\n 'type=\"text/css\"',\n `${SC_ATTR}=\"${this.names.join(' ')}\"`,\n `${LOCAL_ATTR}=\"${this.isLocal ? 'true' : 'false'}\"`,\n ]\n\n const nonce = getNonce()\n if (nonce) {\n attrs.push(`nonce=\"${nonce}\"`)\n }\n\n this.emitted = true\n return `<style ${attrs.join(' ')}>${this.concatenateCSS()}</style>`\n }\n\n toReactElement(key: string) {\n const attrs: Object = {\n [SC_ATTR]: this.names.join(' '),\n [LOCAL_ATTR]: this.isLocal.toString(),\n }\n\n const nonce = getNonce()\n if (nonce) {\n attrs.nonce = nonce\n }\n\n this.emitted = true\n\n return (\n <style\n key={key}\n type=\"text/css\"\n {...attrs}\n dangerouslySetInnerHTML={{ __html: this.concatenateCSS() }}\n />\n )\n }\n\n clone() {\n const copy = new ServerTag(this.isLocal)\n copy.names = [].concat(this.names)\n copy.size = this.size\n copy.components = Object.keys(this.components).reduce((acc, key) => {\n acc[key] = { ...this.components[key] } // eslint-disable-line no-param-reassign\n return acc\n }, {})\n\n return copy\n }\n}\n\nexport default class ServerStyleSheet {\n closed: boolean\n instance: StyleSheet\n isStreaming: boolean\n lastIndex: number\n\n constructor() {\n this.instance = StyleSheet.clone(StyleSheet.instance)\n this.isStreaming = false\n }\n\n collectStyles(children: any) {\n if (this.closed) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Can't collect styles once you've called getStyleTags!\"\n : ''\n )\n }\n return (\n <StyleSheetManager sheet={this.instance}>{children}</StyleSheetManager>\n )\n }\n\n close() {\n clones.splice(clones.indexOf(this.instance), 1)\n this.closed = true\n }\n\n getStyleTags(): string {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toHTML()\n }\n\n getStyleElement() {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toReactElements()\n }\n\n interleaveWithNodeStream(readableStream: stream.Readable) {\n if (__SERVER__) {\n const ourStream = new stream.Readable()\n\n // $FlowFixMe\n ourStream._read = () => {}\n\n this.isStreaming = true\n this.lastIndex = 0\n\n readableStream.on('data', chunk => {\n ourStream.push(\n this.instance.tags\n .slice(this.lastIndex)\n .map(tag => tag.toHTML())\n .join('') + chunk\n )\n\n this.lastIndex = this.instance.tags.length - 1\n })\n\n readableStream.on('end', () => {\n ourStream.push(null)\n this.close()\n })\n\n readableStream.on('error', err => {\n ourStream.emit('error', err)\n this.close()\n })\n\n return ourStream\n } else {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'streaming only works in Node.js, please do not try to call this method in the browser'\n : ''\n )\n }\n }\n\n static create() {\n return new StyleSheet(isLocal => new ServerTag(isLocal))\n }\n}\n","// @flow\n/* globals React$Element */\nimport React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport isPlainObject from 'is-plain-object'\nimport createBroadcast from '../utils/create-broadcast'\nimport type { Broadcast } from '../utils/create-broadcast'\nimport once from '../utils/once'\n\n// NOTE: DO NOT CHANGE, changing this is a semver major change!\nexport const CHANNEL = '__styled-components__'\nexport const CHANNEL_NEXT = `${CHANNEL}next__`\n\nexport const CONTEXT_CHANNEL_SHAPE = PropTypes.shape({\n getTheme: PropTypes.func,\n subscribe: PropTypes.func,\n unsubscribe: PropTypes.func,\n})\n\nexport type Theme = { [key: string]: mixed }\ntype ThemeProviderProps = {|\n children?: React$Element<any>,\n theme: Theme | ((outerTheme: Theme) => void),\n|}\n\nlet warnChannelDeprecated\nif (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated = once(() => {\n // eslint-disable-next-line no-console\n console.error(\n `Warning: Usage of \\`context.${CHANNEL}\\` as a function is deprecated. It will be replaced with the object on \\`.context.${CHANNEL_NEXT}\\` in a future version.`\n )\n })\n}\n\nconst isFunction = test => typeof test === 'function'\n\n/**\n * Provide a theme to an entire react component tree via context and event listeners (have to do\n * both context and event emitter as pure components block context updates)\n */\nclass ThemeProvider extends Component {\n getTheme: (theme?: Theme | ((outerTheme: Theme) => void)) => Theme\n outerTheme: Theme\n unsubscribeToOuterId: string\n props: ThemeProviderProps\n broadcast: Broadcast\n unsubscribeToOuterId: number = -1\n\n constructor() {\n super()\n this.getTheme = this.getTheme.bind(this)\n }\n\n componentWillMount() {\n // If there is a ThemeProvider wrapper anywhere around this theme provider, merge this theme\n // with the outer theme\n const outerContext = this.context[CHANNEL_NEXT]\n if (outerContext !== undefined) {\n this.unsubscribeToOuterId = outerContext.subscribe(theme => {\n this.outerTheme = theme\n\n if (this.broadcast !== undefined) {\n this.publish(this.props.theme)\n }\n })\n }\n\n this.broadcast = createBroadcast(this.getTheme())\n }\n\n getChildContext() {\n return {\n ...this.context,\n [CHANNEL_NEXT]: {\n getTheme: this.getTheme,\n subscribe: this.broadcast.subscribe,\n unsubscribe: this.broadcast.unsubscribe,\n },\n [CHANNEL]: subscriber => {\n if (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated()\n }\n\n // Patch the old `subscribe` provide via `CHANNEL` for older clients.\n const unsubscribeId = this.broadcast.subscribe(subscriber)\n return () => this.broadcast.unsubscribe(unsubscribeId)\n },\n }\n }\n\n componentWillReceiveProps(nextProps: ThemeProviderProps) {\n if (this.props.theme !== nextProps.theme) {\n this.publish(nextProps.theme)\n }\n }\n\n componentWillUnmount() {\n if (this.unsubscribeToOuterId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeToOuterId)\n }\n }\n\n // Get the theme from the props, supporting both (outerTheme) => {} as well as object notation\n getTheme(passedTheme: (outerTheme: Theme) => void | Theme) {\n const theme = passedTheme || this.props.theme\n if (isFunction(theme)) {\n const mergedTheme = theme(this.outerTheme)\n if (\n process.env.NODE_ENV !== 'production' &&\n !isPlainObject(mergedTheme)\n ) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!'\n : ''\n )\n }\n return mergedTheme\n }\n if (!isPlainObject(theme)) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please make your theme prop a plain object'\n : ''\n )\n }\n return { ...this.outerTheme, ...(theme: Object) }\n }\n\n publish(theme: Theme | ((outerTheme: Theme) => void)) {\n this.broadcast.publish(this.getTheme(theme))\n }\n\n render() {\n if (!this.props.children) {\n return null\n }\n return React.Children.only(this.props.children)\n }\n}\n\nThemeProvider.childContextTypes = {\n [CHANNEL]: PropTypes.func, // legacy\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\nThemeProvider.contextTypes = {\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\n\nexport default ThemeProvider\n","// @flow\n\nimport { Component, createElement } from 'react'\nimport PropTypes from 'prop-types'\n\nimport type { Theme } from './ThemeProvider'\nimport createWarnTooManyClasses from '../utils/createWarnTooManyClasses'\n\nimport validAttr from '../utils/validAttr'\nimport isTag from '../utils/isTag'\nimport isStyledComponent from '../utils/isStyledComponent'\nimport getComponentName from '../utils/getComponentName'\nimport determineTheme from '../utils/determineTheme'\nimport escape from '../utils/escape'\nimport type { RuleSet, Target } from '../types'\n\nimport { CHANNEL, CHANNEL_NEXT, CONTEXT_CHANNEL_SHAPE } from './ThemeProvider'\nimport StyleSheet, { CONTEXT_KEY } from './StyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\n// HACK for generating all static styles without needing to allocate\n// an empty execution context every single time...\nconst STATIC_EXECUTION_CONTEXT = {}\n\nexport default (ComponentStyle: Function, constructWithOptions: Function) => {\n const identifiers = {}\n\n /* We depend on components having unique IDs */\n const generateId = (_displayName: string, parentComponentId: string) => {\n const displayName =\n typeof _displayName !== 'string' ? 'sc' : escape(_displayName)\n\n let componentId\n\n /**\n * only fall back to hashing the component injection order if\n * a proper displayName isn't provided by the babel plugin\n */\n if (!_displayName) {\n const nr = (identifiers[displayName] || 0) + 1\n identifiers[displayName] = nr\n\n componentId = `${displayName}-${ComponentStyle.generateName(\n displayName + nr\n )}`\n } else {\n componentId = `${displayName}-${ComponentStyle.generateName(displayName)}`\n }\n\n return parentComponentId !== undefined\n ? `${parentComponentId}-${componentId}`\n : componentId\n }\n\n class BaseStyledComponent extends Component {\n static target: Target\n static styledComponentId: string\n static attrs: Object\n static componentStyle: Object\n static warnTooManyClasses: Function\n\n attrs = {}\n state = {\n theme: null,\n generatedClassName: '',\n }\n unsubscribeId: number = -1\n\n unsubscribeFromContext() {\n if (this.unsubscribeId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeId)\n }\n }\n\n buildExecutionContext(theme: any, props: any) {\n const { attrs } = this.constructor\n const context = { ...props, theme }\n if (attrs === undefined) {\n return context\n }\n\n this.attrs = Object.keys(attrs).reduce((acc, key) => {\n const attr = attrs[key]\n // eslint-disable-next-line no-param-reassign\n acc[key] = typeof attr === 'function' ? attr(context) : attr\n return acc\n }, {})\n\n return { ...context, ...this.attrs }\n }\n\n generateAndInjectStyles(theme: any, props: any) {\n const { attrs, componentStyle, warnTooManyClasses } = this.constructor\n const styleSheet = this.context[CONTEXT_KEY] || StyleSheet.instance\n\n // staticaly styled-components don't need to build an execution context object,\n // and shouldn't be increasing the number of class names\n if (componentStyle.isStatic && attrs === undefined) {\n return componentStyle.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n styleSheet\n )\n } else {\n const executionContext = this.buildExecutionContext(theme, props)\n const className = componentStyle.generateAndInjectStyles(\n executionContext,\n styleSheet\n )\n\n if (\n process.env.NODE_ENV !== 'production' &&\n warnTooManyClasses !== undefined\n ) {\n warnTooManyClasses(className)\n }\n\n return className\n }\n }\n\n componentWillMount() {\n const { componentStyle } = this.constructor\n const styledContext = this.context[CHANNEL_NEXT]\n\n // If this is a staticaly-styled component, we don't need to the theme\n // to generate or build styles.\n if (componentStyle.isStatic) {\n const generatedClassName = this.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n this.props\n )\n this.setState({ generatedClassName })\n // If there is a theme in the context, subscribe to the event emitter. This\n // is necessary due to pure components blocking context updates, this circumvents\n // that by updating when an event is emitted\n } else if (styledContext !== undefined) {\n const { subscribe } = styledContext\n this.unsubscribeId = subscribe(nextTheme => {\n // This will be called once immediately\n const theme = determineTheme(\n this.props,\n nextTheme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n\n this.setState({ theme, generatedClassName })\n })\n } else {\n // eslint-disable-next-line react/prop-types\n const theme = this.props.theme || {}\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n this.setState({ theme, generatedClassName })\n }\n }\n\n componentWillReceiveProps(nextProps: {\n theme?: Theme,\n [key: string]: any,\n }) {\n // If this is a staticaly-styled component, we don't need to listen to\n // props changes to update styles\n const { componentStyle } = this.constructor\n if (componentStyle.isStatic) {\n return\n }\n\n this.setState(oldState => {\n const theme = determineTheme(\n nextProps,\n oldState.theme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n nextProps\n )\n\n return { theme, generatedClassName }\n })\n }\n\n componentWillUnmount() {\n this.unsubscribeFromContext()\n }\n\n render() {\n // eslint-disable-next-line react/prop-types\n const { innerRef } = this.props\n const { generatedClassName } = this.state\n const { styledComponentId, target } = this.constructor\n\n const isTargetTag = isTag(target)\n\n const className = [\n // eslint-disable-next-line react/prop-types\n this.props.className,\n styledComponentId,\n this.attrs.className,\n generatedClassName,\n ]\n .filter(Boolean)\n .join(' ')\n\n const baseProps = {\n ...this.attrs,\n className,\n }\n\n if (isStyledComponent(target)) {\n baseProps.innerRef = innerRef\n } else {\n baseProps.ref = innerRef\n }\n\n const propsForElement = Object.keys(this.props).reduce(\n (acc, propName) => {\n // Don't pass through non HTML tags through to HTML elements\n // always omit innerRef\n if (\n propName !== 'innerRef' &&\n propName !== 'className' &&\n (!isTargetTag || validAttr(propName))\n ) {\n // eslint-disable-next-line no-param-reassign\n acc[propName] = this.props[propName]\n }\n\n return acc\n },\n baseProps\n )\n\n return createElement(target, propsForElement)\n }\n }\n\n const createStyledComponent = (\n target: Target,\n options: Object,\n rules: RuleSet\n ) => {\n const {\n displayName = isTag(target)\n ? `styled.${target}`\n : `Styled(${getComponentName(target)})`,\n componentId = generateId(options.displayName, options.parentComponentId),\n ParentComponent = BaseStyledComponent,\n rules: extendingRules,\n attrs,\n } = options\n\n const styledComponentId =\n options.displayName && options.componentId\n ? `${escape(options.displayName)}-${options.componentId}`\n : componentId\n\n const componentStyle = new ComponentStyle(\n extendingRules === undefined ? rules : extendingRules.concat(rules),\n attrs,\n styledComponentId\n )\n\n class StyledComponent extends ParentComponent {\n static contextTypes = {\n [CHANNEL]: PropTypes.func,\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n [CONTEXT_KEY]: PropTypes.oneOfType([\n PropTypes.instanceOf(StyleSheet),\n PropTypes.instanceOf(ServerStyleSheet),\n ]),\n }\n\n static displayName = displayName\n static styledComponentId = styledComponentId\n static attrs = attrs\n static componentStyle = componentStyle\n static target = target\n\n static withComponent(tag) {\n const { componentId: previousComponentId, ...optionsToCopy } = options\n\n const newComponentId =\n previousComponentId &&\n `${previousComponentId}-${\n isTag(tag) ? tag : escape(getComponentName(tag))\n }`\n\n const newOptions = {\n ...optionsToCopy,\n componentId: newComponentId,\n ParentComponent: StyledComponent,\n }\n\n return createStyledComponent(tag, newOptions, rules)\n }\n\n static get extend() {\n const {\n rules: rulesFromOptions,\n componentId: parentComponentId,\n ...optionsToCopy\n } = options\n\n const newRules =\n rulesFromOptions === undefined\n ? rules\n : rulesFromOptions.concat(rules)\n\n const newOptions = {\n ...optionsToCopy,\n rules: newRules,\n parentComponentId,\n ParentComponent: StyledComponent,\n }\n\n return constructWithOptions(createStyledComponent, target, newOptions)\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n StyledComponent.warnTooManyClasses = createWarnTooManyClasses(displayName)\n }\n\n return StyledComponent\n }\n\n return createStyledComponent\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\n\nimport type { RuleSet, NameGenerator, Flattener, Stringifier } from '../types'\nimport StyleSheet from './StyleSheet'\nimport isStyledComponent from '../utils/isStyledComponent'\n\nconst isStaticRules = (rules: RuleSet, attrs?: Object): boolean => {\n for (let i = 0; i < rules.length; i += 1) {\n const rule = rules[i]\n\n // recursive case\n if (Array.isArray(rule) && !isStaticRules(rule)) {\n return false\n } else if (typeof rule === 'function' && !isStyledComponent(rule)) {\n // functions are allowed to be static if they're just being\n // used to get the classname of a nested styled copmonent\n return false\n }\n }\n\n if (attrs !== undefined) {\n // eslint-disable-next-line guard-for-in, no-restricted-syntax\n for (const key in attrs) {\n const value = attrs[key]\n if (typeof value === 'function') {\n return false\n }\n }\n }\n\n return true\n}\n\nconst isHRMEnabled =\n typeof module !== 'undefined' &&\n module.hot &&\n process.env.NODE_ENV !== 'production'\n\n/*\n ComponentStyle is all the CSS-specific stuff, not\n the React-specific stuff.\n */\nexport default (\n nameGenerator: NameGenerator,\n flatten: Flattener,\n stringifyRules: Stringifier\n) => {\n class ComponentStyle {\n rules: RuleSet\n componentId: string\n isStatic: boolean\n lastClassName: ?string\n\n constructor(rules: RuleSet, attrs?: Object, componentId: string) {\n this.rules = rules\n this.isStatic = !isHRMEnabled && isStaticRules(rules, attrs)\n this.componentId = componentId\n if (!StyleSheet.instance.hasInjectedComponent(this.componentId)) {\n const placeholder =\n process.env.NODE_ENV !== 'production' ? `.${componentId} {}` : ''\n StyleSheet.instance.deferredInject(componentId, true, [placeholder])\n }\n }\n\n /*\n * Flattens a rule set into valid CSS\n * Hashes it, wraps the whole chunk in a .hash1234 {}\n * Returns the hash to be injected on render()\n * */\n generateAndInjectStyles(executionContext: Object, styleSheet: StyleSheet) {\n const { isStatic, lastClassName } = this\n if (isStatic && lastClassName !== undefined) {\n return lastClassName\n }\n\n const flatCSS = flatten(this.rules, executionContext)\n const hash = hashStr(this.componentId + flatCSS.join(''))\n\n const { stylesCacheable } = styleSheet\n const existingName = styleSheet.getName(hash)\n\n if (existingName !== undefined) {\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n return existingName\n }\n\n const name = nameGenerator(hash)\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n if (styleSheet.alreadyInjected(hash, name)) {\n return name\n }\n\n const css = stringifyRules(flatCSS, `.${name}`)\n // NOTE: this can only be set when we inject the class-name.\n // For some reason, presumably due to how css is stringifyRules behaves in\n // differently between client and server, styles break.\n styleSheet.inject(this.componentId, true, css, hash, name)\n return name\n }\n\n static generateName(str: string) {\n return nameGenerator(hashStr(str))\n }\n }\n\n return ComponentStyle\n}\n","// @flow\nimport type { Target } from '../types'\nimport domElements from '../utils/domElements'\n\nexport default (styledComponent: Function, constructWithOptions: Function) => {\n const styled = (tag: Target) => constructWithOptions(styledComponent, tag)\n\n // Shorthands for all valid HTML Elements\n domElements.forEach(domElement => {\n styled[domElement] = styled(domElement)\n })\n\n return styled\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\nimport type { Interpolation, NameGenerator, Stringifier } from '../types'\nimport StyleSheet from '../models/StyleSheet'\n\nconst replaceWhitespace = (str: string): string => str.replace(/\\s|\\\\n/g, '')\n\nexport default (\n nameGenerator: NameGenerator,\n stringifyRules: Stringifier,\n css: Function\n) => (\n strings: Array<string>,\n ...interpolations: Array<Interpolation>\n): string => {\n const rules = css(strings, ...interpolations)\n const hash = hashStr(replaceWhitespace(JSON.stringify(rules)))\n\n const existingName = StyleSheet.instance.getName(hash)\n if (existingName) return existingName\n\n const name = nameGenerator(hash)\n if (StyleSheet.instance.alreadyInjected(hash, name)) return name\n\n const generatedCSS = stringifyRules(rules, name, '@keyframes')\n StyleSheet.instance.inject(\n `sc-keyframes-${name}`,\n true,\n generatedCSS,\n hash,\n name\n )\n return name\n}\n"],"names":["deferredInjections","constructComponentTagMap","nonce","componentWillMount","state","unsubscribeId","attrs","reduce","length","i"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,iGAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SCMEA;;;;;;SAmBOC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAoDD,YAAA,SAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBCNYC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5EpB,kCAAA;AACA,yCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BA0BEC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+JCSEC;;;eAIAC;;;;;;;;;;;;;;;;;+BAe2BC,OAAYC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BCnEfC,QAA0BC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA0ClD,OAAA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChDJ;;;;;;;;;;;;;;;;;;;SCSK,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"styled-components-no-parser.browser.cjs.js","sources":["../src/models/BrowserStyleSheet.js","../src/models/StyleSheet.js","../src/models/ServerStyleSheet.js","../src/models/ThemeProvider.js","../src/models/StyledComponent.js","../src/models/ComponentStyle.js","../src/constructors/styled.js","../src/constructors/keyframes.js"],"sourcesContent":["// @flow\n/* eslint-disable no-underscore-dangle */\n/*\n * Browser Style Sheet with Rehydration\n *\n * <style data-styled-components=\"x y z\"\n * data-styled-components-is-local=\"true\">\n * /· sc-component-id: a ·/\n * .sc-a { ... }\n * .x { ... }\n * /· sc-component-id: b ·/\n * .sc-b { ... }\n * .y { ... }\n * .z { ... }\n * </style>\n *\n * Note: replace · with * in the above snippet.\n * */\nimport extractCompsFromCSS from '../utils/extractCompsFromCSS'\nimport stringifyRules from '../utils/stringifyRules'\nimport getNonce from '../utils/nonce'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR } from './StyleSheet'\n\ndeclare var __DEV__: ?string\n\nconst DISABLE_SPEEDY =\n (typeof __DEV__ === 'boolean' && __DEV__) ||\n process.env.NODE_ENV !== 'production'\n\nconst COMPONENTS_PER_TAG = 40\nconst SPEEDY_COMPONENTS_PER_TAG = 1000 // insertRule allows more injections before a perf slowdown\n\n// Source: https://github.com/threepointone/glamor/blob/master/src/sheet.js#L32-L43\nconst sheetForTag = (tag: HTMLStyleElement): CSSStyleSheet => {\n if (tag.sheet) {\n // $FlowFixMe\n return tag.sheet\n }\n\n for (let i = 0; i < document.styleSheets.length; i += 1) {\n if (document.styleSheets[i].ownerNode === tag) {\n // $FlowFixMe\n return document.styleSheets[i]\n }\n }\n\n // NOTE: This should never happen\n throw new Error('')\n}\n\n// Safely (try/catch) injects rule at index and returns whether it was successful\nconst safeInsertRule = (\n sheet: CSSStyleSheet,\n cssRule: string,\n index: number\n): boolean => {\n if (cssRule === undefined || cssRule.length === 0) {\n return false\n }\n\n const maxIndex = sheet.cssRules.length\n const cappedIndex = index <= maxIndex ? index : maxIndex\n\n try {\n sheet.insertRule(cssRule, cappedIndex)\n } catch (err) {\n // NOTE: An invalid rule here means it's not supported by the browser or obviously malformed\n return false\n }\n\n return true\n}\n\n// Counts up the number of rules inside the array until a specific component entry is found\n// This is used to determine the necessary insertRule index\nconst sizeUpToComponentIndex = (\n componentSizes: Array<number>,\n componentIndex: number\n) => {\n let cssRulesSize = 0\n for (let i = 0; i <= componentIndex; i += 1) {\n cssRulesSize += componentSizes[i]\n }\n\n return cssRulesSize\n}\n\nclass BaseBrowserTag {\n components: { [string]: Object }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n}\n\nlet BrowserTag\nif (!DISABLE_SPEEDY) {\n BrowserTag = class SpeedyBrowserTag extends BaseBrowserTag implements Tag {\n // Store component ruleSizes in an array per component (in order)\n componentSizes: Array<number>\n components: { [string]: Object }\n\n isLocal: boolean\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: ?string\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.componentSizes = []\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // workaround for an IE/Edge bug: https://twitter.com/probablyup/status/958138927981977600\n newEl.appendChild(document.createTextNode(''))\n\n // $FlowFixMe\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n this.ready = true\n\n // Retrieve the sheet for the new style tag\n const sheet = sheetForTag(newEl)\n\n Object.keys(this.components).forEach(componentId => {\n const comp = this.components[componentId]\n const { cssFromDOM } = comp\n const rules = stringifyRules([cssFromDOM])\n const rulesSize = rules.length\n\n let injectedRules = 0\n for (let j = 0; j < rulesSize; j += 1) {\n if (safeInsertRule(sheet, rules[j], sheet.cssRules.length)) {\n injectedRules += 1\n }\n }\n\n comp.componentIndex = this.componentSizes.length\n comp.css = rules.join(' ')\n this.componentSizes.push(injectedRules)\n })\n }\n\n isSealed() {\n return this.size >= SPEEDY_COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n this.components[componentId] = {\n componentIndex: this.componentSizes.length,\n css: '',\n }\n\n this.componentSizes.push(0)\n this.size += 1\n }\n\n inject(componentId: string, cssRules: Array<string>, name: ?string) {\n if (!this.ready) this.replaceElement()\n\n const comp = this.components[componentId]\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n const cssRulesSize = cssRules.length\n const sheet = sheetForTag(this.el)\n const { componentIndex } = comp\n\n // Determine start index for injection\n const insertIndex = sizeUpToComponentIndex(\n this.componentSizes,\n componentIndex\n )\n\n // Inject each rule shifting index forward for each one (in-order injection)\n let injectedRules = 0\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = cssRules[i]\n if (safeInsertRule(sheet, cssRule, insertIndex + injectedRules)) {\n comp.css += ` ${cssRule}`\n injectedRules += 1\n }\n }\n\n // Update number of rules for component\n this.componentSizes[componentIndex] += injectedRules\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toRawCSS() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n\n toHTML() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n }\n} else {\n BrowserTag = class TextNodeBrowserTag extends BaseBrowserTag implements Tag {\n isLocal: boolean\n components: { [string]: Object }\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: string = ''\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce !== null) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n isSealed() {\n return this.size >= COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n const comp = { componentId, textNode: document.createTextNode('') }\n this.el.appendChild(comp.textNode)\n this.size += 1\n this.components[componentId] = comp\n }\n\n inject(componentId: string, css: Array<string>, name: ?string) {\n if (!this.ready) this.replaceElement()\n const comp = this.components[componentId]\n\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n if (comp.textNode.data === '') {\n comp.textNode.appendData(`\\n/* sc-component-id: ${componentId} */\\n`)\n }\n\n comp.textNode.appendData(css.join(' '))\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toHTML() {\n return this.el.outerHTML\n }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n this.ready = true\n // We have nothing to inject. Use the current el.\n if (this.size === 0) return\n\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n newEl.appendChild(document.createTextNode('\\n'))\n\n Object.keys(this.components).forEach(key => {\n const comp = this.components[key]\n\n // eslint-disable-next-line no-param-reassign\n comp.textNode = document.createTextNode(comp.cssFromDOM)\n newEl.appendChild(comp.textNode)\n })\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // The ol' switcheroo\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n }\n }\n}\n\n/* Factory function to separate DOM operations from logical ones*/\nexport default {\n create() {\n const tags = []\n const names = {}\n\n /* Construct existing state from DOM */\n const nodes = document.querySelectorAll(`[${SC_ATTR}]`)\n const nodesLength = nodes.length\n\n for (let i = 0; i < nodesLength; i += 1) {\n // $FlowFixMe: We can trust that all elements in this query are style elements\n const el = (nodes[i]: HTMLStyleElement)\n const attr = el.getAttribute(SC_ATTR)\n\n if (attr) {\n attr\n .trim()\n .split(/\\s+/)\n .forEach(name => {\n names[name] = true\n })\n }\n\n tags.push(\n new BrowserTag(\n el,\n el.getAttribute(LOCAL_ATTR) === 'true',\n el.textContent\n )\n )\n }\n\n /* Factory for making more tags */\n const tagConstructor = (isLocal: boolean): Tag => {\n const el = document.createElement('style')\n el.type = 'text/css'\n el.setAttribute(SC_ATTR, '')\n el.setAttribute(LOCAL_ATTR, isLocal ? 'true' : 'false')\n if (!document.head) {\n throw new Error(\n process.env.NODE_ENV !== 'production' ? 'Missing document <head>' : ''\n )\n }\n document.head.appendChild(el)\n return new BrowserTag(el, isLocal)\n }\n\n return new StyleSheet(tagConstructor, tags, names)\n },\n}\n","// @flow\nimport React from 'react'\nimport BrowserStyleSheet from './BrowserStyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\nexport const SC_ATTR = 'data-styled-components'\nexport const LOCAL_ATTR = 'data-styled-components-is-local'\nexport const CONTEXT_KEY = '__styled-components-stylesheet__'\n\n/* eslint-disable flowtype/object-type-delimiter */\nexport interface Tag {\n isLocal: boolean;\n\n isSealed(): boolean;\n getComponentIds(): Array<string>;\n addComponent(componentId: string): void;\n inject(componentId: string, css: Array<string>, name: ?string): void;\n toHTML(): string;\n toReactElement(key: string): React.Element<*>;\n clone(): Tag;\n}\n/* eslint-enable flowtype/object-type-delimiter */\n\nlet instance = null\n// eslint-disable-next-line no-use-before-define\nexport const clones: Array<StyleSheet> = []\n\nconst IS_BROWSER = typeof document !== 'undefined'\n\nexport default class StyleSheet {\n tagConstructor: boolean => Tag\n tags: Array<Tag>\n names: { [string]: boolean }\n hashes: { [string]: string } = {}\n deferredInjections: { [string]: Array<string> } = {}\n componentTags: { [string]: Tag }\n isStreaming: boolean\n\n // helper for `ComponentStyle` to know when it cache static styles.\n // staticly styled-component can not safely cache styles on the server\n // without all `ComponentStyle` instances saving a reference to the\n // the styleSheet instance they last rendered with,\n // or listening to creation / reset events. otherwise you might create\n // a component with one stylesheet and render it another api response\n // with another, losing styles on from your server-side render.\n stylesCacheable = IS_BROWSER\n\n constructor(\n tagConstructor: boolean => Tag,\n tags: Array<Tag> = [],\n names: { [string]: boolean } = {}\n ) {\n this.tagConstructor = tagConstructor\n this.tags = tags\n this.names = names\n this.constructComponentTagMap()\n this.isStreaming = false\n }\n\n constructComponentTagMap() {\n this.componentTags = {}\n\n this.tags.forEach(tag => {\n tag.getComponentIds().forEach(componentId => {\n this.componentTags[componentId] = tag\n })\n })\n }\n\n /* Best level of caching—get the name from the hash straight away. */\n getName(hash: any) {\n return this.hashes[hash.toString()]\n }\n\n /* Second level of caching—if the name is already in the dom, don't\n * inject anything and record the hash for getName next time. */\n alreadyInjected(hash: any, name: string) {\n if (!this.names[name]) return false\n\n this.hashes[hash.toString()] = name\n return true\n }\n\n /* Third type of caching—don't inject components' componentId twice. */\n hasInjectedComponent(componentId: string) {\n return !!this.componentTags[componentId]\n }\n\n deferredInject(componentId: string, isLocal: boolean, css: Array<string>) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.deferredInject(componentId, isLocal, css)\n })\n }\n\n this.getOrCreateTag(componentId, isLocal)\n this.deferredInjections[componentId] = css\n }\n\n inject(\n componentId: string,\n isLocal: boolean,\n css: Array<string>,\n hash: ?any,\n name: ?string\n ) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.inject(componentId, isLocal, css)\n })\n }\n\n const tag = this.getOrCreateTag(componentId, isLocal)\n\n const deferredInjection = this.deferredInjections[componentId]\n if (deferredInjection) {\n tag.inject(componentId, deferredInjection)\n delete this.deferredInjections[componentId]\n }\n\n tag.inject(componentId, css, name)\n\n if (hash && name) {\n this.hashes[hash.toString()] = name\n }\n }\n\n toHTML() {\n return this.tags.map(tag => tag.toHTML()).join('')\n }\n\n toReactElements() {\n return this.tags.map((tag, i) => tag.toReactElement(`sc-${i}`))\n }\n\n getOrCreateTag(componentId: string, isLocal: boolean) {\n const existingTag = this.componentTags[componentId]\n\n /**\n * in a streaming context, once a tag is sealed it can never be added to again\n * or those styles will never make it to the client\n */\n if (\n existingTag && this.isStreaming ? !existingTag.isSealed() : existingTag\n ) {\n return existingTag\n }\n\n const lastTag = this.tags[this.tags.length - 1]\n const componentTag =\n !lastTag || lastTag.isSealed() || lastTag.isLocal !== isLocal\n ? this.createNewTag(isLocal)\n : lastTag\n this.componentTags[componentId] = componentTag\n componentTag.addComponent(componentId)\n return componentTag\n }\n\n createNewTag(isLocal: boolean) {\n const newTag = this.tagConstructor(isLocal)\n this.tags.push(newTag)\n return newTag\n }\n\n static get instance() {\n return instance || (instance = StyleSheet.create())\n }\n\n static reset(isServer: ?boolean) {\n instance = StyleSheet.create(isServer)\n }\n\n /* We can make isServer totally implicit once Jest 20 drops and we\n * can change environment on a per-test basis. */\n static create(isServer: ?boolean = !IS_BROWSER) {\n return (isServer ? ServerStyleSheet : BrowserStyleSheet).create()\n }\n\n static clone(oldSheet: StyleSheet) {\n const newSheet = new StyleSheet(\n oldSheet.tagConstructor,\n oldSheet.tags.map(tag => tag.clone()),\n { ...oldSheet.names }\n )\n\n newSheet.hashes = { ...oldSheet.hashes }\n newSheet.deferredInjections = { ...oldSheet.deferredInjections }\n clones.push(newSheet)\n\n return newSheet\n }\n}\n","// @flow\n/* eslint-disable no-underscore-dangle */\nimport React from 'react'\nimport stream from 'stream'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR, clones } from './StyleSheet'\nimport StyleSheetManager from './StyleSheetManager'\nimport getNonce from '../utils/nonce'\n\ndeclare var __SERVER__: boolean\n\nclass ServerTag implements Tag {\n emitted: boolean\n isLocal: boolean\n isProduction: boolean\n components: { [string]: Object }\n size: number\n names: Array<string>\n\n constructor(isLocal: boolean) {\n this.emitted = false\n this.isLocal = isLocal\n this.isProduction = process.env.NODE_ENV === 'production'\n this.components = {}\n this.size = 0\n this.names = []\n }\n\n isSealed() {\n return this.emitted\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n\n addComponent(componentId: string) {\n if (this.components[componentId]) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? `Trying to add Component '${componentId}' twice!`\n : ''\n )\n }\n this.components[componentId] = { componentId, css: '' }\n this.size += 1\n }\n\n concatenateCSS() {\n return Object.keys(this.components).reduce(\n (styles, k) => styles + this.components[k].css,\n ''\n )\n }\n\n inject(componentId: string, css: Array<string>, name: ?string) {\n const comp = this.components[componentId]\n\n if (!comp) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'Must add a new component before you can inject css into it'\n : ''\n )\n }\n\n if (comp.css === '') {\n comp.css = `/* sc-component-id: ${componentId} */\\n`\n }\n\n const cssRulesSize = css.length\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = css[i]\n comp.css += `${cssRule}\\n`.replace(/\\n*$/, '\\n')\n }\n\n if (name) this.names.push(name)\n }\n\n toHTML() {\n const attrs: Array<string> = [\n 'type=\"text/css\"',\n `${SC_ATTR}=\"${this.names.join(' ')}\"`,\n `${LOCAL_ATTR}=\"${this.isLocal ? 'true' : 'false'}\"`,\n ]\n\n const nonce = getNonce()\n if (nonce) {\n attrs.push(`nonce=\"${nonce}\"`)\n }\n\n this.emitted = true\n return `<style ${attrs.join(' ')}>${this.concatenateCSS()}</style>`\n }\n\n toReactElement(key: string) {\n const attrs: Object = {\n [SC_ATTR]: this.names.join(' '),\n [LOCAL_ATTR]: this.isLocal.toString(),\n }\n\n const nonce = getNonce()\n if (nonce) {\n attrs.nonce = nonce\n }\n\n this.emitted = true\n\n return (\n <style\n key={key}\n type=\"text/css\"\n {...attrs}\n dangerouslySetInnerHTML={{ __html: this.concatenateCSS() }}\n />\n )\n }\n\n clone() {\n const copy = new ServerTag(this.isLocal)\n copy.names = [].concat(this.names)\n copy.size = this.size\n copy.components = Object.keys(this.components).reduce((acc, key) => {\n acc[key] = { ...this.components[key] } // eslint-disable-line no-param-reassign\n return acc\n }, {})\n\n return copy\n }\n}\n\nexport default class ServerStyleSheet {\n closed: boolean\n instance: StyleSheet\n\n constructor() {\n this.instance = StyleSheet.clone(StyleSheet.instance)\n this.instance.isStreaming = false\n }\n\n collectStyles(children: any) {\n if (this.closed) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Can't collect styles once you've called getStyleTags!\"\n : ''\n )\n }\n return (\n <StyleSheetManager sheet={this.instance}>{children}</StyleSheetManager>\n )\n }\n\n close() {\n clones.splice(clones.indexOf(this.instance), 1)\n this.closed = true\n }\n\n getStyleTags(): string {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toHTML()\n }\n\n getStyleElement() {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toReactElements()\n }\n\n interleaveWithNodeStream(readableStream: stream.Readable) {\n if (__SERVER__) {\n const ourStream = new stream.Readable()\n\n // $FlowFixMe\n ourStream._read = () => {}\n\n this.instance.isStreaming = true\n\n readableStream.on('data', chunk => {\n ourStream.push(\n this.instance.tags.reduce((html, tag) => {\n if (!tag.isSealed()) {\n html += tag.toHTML() // eslint-disable-line no-param-reassign\n }\n\n return html\n }, '') + chunk\n )\n })\n\n readableStream.on('end', () => {\n ourStream.push(null)\n this.close()\n })\n\n readableStream.on('error', err => {\n ourStream.emit('error', err)\n this.close()\n })\n\n return ourStream\n } else {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'streaming only works in Node.js, please do not try to call this method in the browser'\n : ''\n )\n }\n }\n\n static create() {\n return new StyleSheet(isLocal => new ServerTag(isLocal))\n }\n}\n","// @flow\n/* globals React$Element */\nimport React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport isPlainObject from 'is-plain-object'\nimport createBroadcast from '../utils/create-broadcast'\nimport type { Broadcast } from '../utils/create-broadcast'\nimport once from '../utils/once'\n\n// NOTE: DO NOT CHANGE, changing this is a semver major change!\nexport const CHANNEL = '__styled-components__'\nexport const CHANNEL_NEXT = `${CHANNEL}next__`\n\nexport const CONTEXT_CHANNEL_SHAPE = PropTypes.shape({\n getTheme: PropTypes.func,\n subscribe: PropTypes.func,\n unsubscribe: PropTypes.func,\n})\n\nexport type Theme = { [key: string]: mixed }\ntype ThemeProviderProps = {|\n children?: React$Element<any>,\n theme: Theme | ((outerTheme: Theme) => void),\n|}\n\nlet warnChannelDeprecated\nif (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated = once(() => {\n // eslint-disable-next-line no-console\n console.error(\n `Warning: Usage of \\`context.${CHANNEL}\\` as a function is deprecated. It will be replaced with the object on \\`.context.${CHANNEL_NEXT}\\` in a future version.`\n )\n })\n}\n\nconst isFunction = test => typeof test === 'function'\n\n/**\n * Provide a theme to an entire react component tree via context and event listeners (have to do\n * both context and event emitter as pure components block context updates)\n */\nclass ThemeProvider extends Component {\n getTheme: (theme?: Theme | ((outerTheme: Theme) => void)) => Theme\n outerTheme: Theme\n unsubscribeToOuterId: string\n props: ThemeProviderProps\n broadcast: Broadcast\n unsubscribeToOuterId: number = -1\n\n constructor() {\n super()\n this.getTheme = this.getTheme.bind(this)\n }\n\n componentWillMount() {\n // If there is a ThemeProvider wrapper anywhere around this theme provider, merge this theme\n // with the outer theme\n const outerContext = this.context[CHANNEL_NEXT]\n if (outerContext !== undefined) {\n this.unsubscribeToOuterId = outerContext.subscribe(theme => {\n this.outerTheme = theme\n\n if (this.broadcast !== undefined) {\n this.publish(this.props.theme)\n }\n })\n }\n\n this.broadcast = createBroadcast(this.getTheme())\n }\n\n getChildContext() {\n return {\n ...this.context,\n [CHANNEL_NEXT]: {\n getTheme: this.getTheme,\n subscribe: this.broadcast.subscribe,\n unsubscribe: this.broadcast.unsubscribe,\n },\n [CHANNEL]: subscriber => {\n if (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated()\n }\n\n // Patch the old `subscribe` provide via `CHANNEL` for older clients.\n const unsubscribeId = this.broadcast.subscribe(subscriber)\n return () => this.broadcast.unsubscribe(unsubscribeId)\n },\n }\n }\n\n componentWillReceiveProps(nextProps: ThemeProviderProps) {\n if (this.props.theme !== nextProps.theme) {\n this.publish(nextProps.theme)\n }\n }\n\n componentWillUnmount() {\n if (this.unsubscribeToOuterId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeToOuterId)\n }\n }\n\n // Get the theme from the props, supporting both (outerTheme) => {} as well as object notation\n getTheme(passedTheme: (outerTheme: Theme) => void | Theme) {\n const theme = passedTheme || this.props.theme\n if (isFunction(theme)) {\n const mergedTheme = theme(this.outerTheme)\n if (\n process.env.NODE_ENV !== 'production' &&\n !isPlainObject(mergedTheme)\n ) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!'\n : ''\n )\n }\n return mergedTheme\n }\n if (!isPlainObject(theme)) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please make your theme prop a plain object'\n : ''\n )\n }\n return { ...this.outerTheme, ...(theme: Object) }\n }\n\n publish(theme: Theme | ((outerTheme: Theme) => void)) {\n this.broadcast.publish(this.getTheme(theme))\n }\n\n render() {\n if (!this.props.children) {\n return null\n }\n return React.Children.only(this.props.children)\n }\n}\n\nThemeProvider.childContextTypes = {\n [CHANNEL]: PropTypes.func, // legacy\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\nThemeProvider.contextTypes = {\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\n\nexport default ThemeProvider\n","// @flow\n\nimport { Component, createElement } from 'react'\nimport PropTypes from 'prop-types'\n\nimport type { Theme } from './ThemeProvider'\nimport createWarnTooManyClasses from '../utils/createWarnTooManyClasses'\n\nimport validAttr from '../utils/validAttr'\nimport isTag from '../utils/isTag'\nimport isStyledComponent from '../utils/isStyledComponent'\nimport getComponentName from '../utils/getComponentName'\nimport determineTheme from '../utils/determineTheme'\nimport escape from '../utils/escape'\nimport type { RuleSet, Target } from '../types'\n\nimport { CHANNEL, CHANNEL_NEXT, CONTEXT_CHANNEL_SHAPE } from './ThemeProvider'\nimport StyleSheet, { CONTEXT_KEY } from './StyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\n// HACK for generating all static styles without needing to allocate\n// an empty execution context every single time...\nconst STATIC_EXECUTION_CONTEXT = {}\n\nexport default (ComponentStyle: Function, constructWithOptions: Function) => {\n const identifiers = {}\n\n /* We depend on components having unique IDs */\n const generateId = (_displayName: string, parentComponentId: string) => {\n const displayName =\n typeof _displayName !== 'string' ? 'sc' : escape(_displayName)\n\n let componentId\n\n /**\n * only fall back to hashing the component injection order if\n * a proper displayName isn't provided by the babel plugin\n */\n if (!_displayName) {\n const nr = (identifiers[displayName] || 0) + 1\n identifiers[displayName] = nr\n\n componentId = `${displayName}-${ComponentStyle.generateName(\n displayName + nr\n )}`\n } else {\n componentId = `${displayName}-${ComponentStyle.generateName(displayName)}`\n }\n\n return parentComponentId !== undefined\n ? `${parentComponentId}-${componentId}`\n : componentId\n }\n\n class BaseStyledComponent extends Component {\n static target: Target\n static styledComponentId: string\n static attrs: Object\n static componentStyle: Object\n static warnTooManyClasses: Function\n\n attrs = {}\n state = {\n theme: null,\n generatedClassName: '',\n }\n unsubscribeId: number = -1\n\n unsubscribeFromContext() {\n if (this.unsubscribeId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeId)\n }\n }\n\n buildExecutionContext(theme: any, props: any) {\n const { attrs } = this.constructor\n const context = { ...props, theme }\n if (attrs === undefined) {\n return context\n }\n\n this.attrs = Object.keys(attrs).reduce((acc, key) => {\n const attr = attrs[key]\n // eslint-disable-next-line no-param-reassign\n acc[key] = typeof attr === 'function' ? attr(context) : attr\n return acc\n }, {})\n\n return { ...context, ...this.attrs }\n }\n\n generateAndInjectStyles(theme: any, props: any) {\n const { attrs, componentStyle, warnTooManyClasses } = this.constructor\n const styleSheet = this.context[CONTEXT_KEY] || StyleSheet.instance\n\n // staticaly styled-components don't need to build an execution context object,\n // and shouldn't be increasing the number of class names\n if (componentStyle.isStatic && attrs === undefined) {\n return componentStyle.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n styleSheet\n )\n } else {\n const executionContext = this.buildExecutionContext(theme, props)\n const className = componentStyle.generateAndInjectStyles(\n executionContext,\n styleSheet\n )\n\n if (\n process.env.NODE_ENV !== 'production' &&\n warnTooManyClasses !== undefined\n ) {\n warnTooManyClasses(className)\n }\n\n return className\n }\n }\n\n componentWillMount() {\n const { componentStyle } = this.constructor\n const styledContext = this.context[CHANNEL_NEXT]\n\n // If this is a staticaly-styled component, we don't need to the theme\n // to generate or build styles.\n if (componentStyle.isStatic) {\n const generatedClassName = this.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n this.props\n )\n this.setState({ generatedClassName })\n // If there is a theme in the context, subscribe to the event emitter. This\n // is necessary due to pure components blocking context updates, this circumvents\n // that by updating when an event is emitted\n } else if (styledContext !== undefined) {\n const { subscribe } = styledContext\n this.unsubscribeId = subscribe(nextTheme => {\n // This will be called once immediately\n const theme = determineTheme(\n this.props,\n nextTheme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n\n this.setState({ theme, generatedClassName })\n })\n } else {\n // eslint-disable-next-line react/prop-types\n const theme = this.props.theme || {}\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n this.setState({ theme, generatedClassName })\n }\n }\n\n componentWillReceiveProps(nextProps: {\n theme?: Theme,\n [key: string]: any,\n }) {\n // If this is a staticaly-styled component, we don't need to listen to\n // props changes to update styles\n const { componentStyle } = this.constructor\n if (componentStyle.isStatic) {\n return\n }\n\n this.setState(oldState => {\n const theme = determineTheme(\n nextProps,\n oldState.theme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n nextProps\n )\n\n return { theme, generatedClassName }\n })\n }\n\n componentWillUnmount() {\n this.unsubscribeFromContext()\n }\n\n render() {\n // eslint-disable-next-line react/prop-types\n const { innerRef } = this.props\n const { generatedClassName } = this.state\n const { styledComponentId, target } = this.constructor\n\n const isTargetTag = isTag(target)\n\n const className = [\n // eslint-disable-next-line react/prop-types\n this.props.className,\n styledComponentId,\n this.attrs.className,\n generatedClassName,\n ]\n .filter(Boolean)\n .join(' ')\n\n const baseProps = {\n ...this.attrs,\n className,\n }\n\n if (isStyledComponent(target)) {\n baseProps.innerRef = innerRef\n } else {\n baseProps.ref = innerRef\n }\n\n const propsForElement = Object.keys(this.props).reduce(\n (acc, propName) => {\n // Don't pass through non HTML tags through to HTML elements\n // always omit innerRef\n if (\n propName !== 'innerRef' &&\n propName !== 'className' &&\n (!isTargetTag || validAttr(propName))\n ) {\n // eslint-disable-next-line no-param-reassign\n acc[propName] = this.props[propName]\n }\n\n return acc\n },\n baseProps\n )\n\n return createElement(target, propsForElement)\n }\n }\n\n const createStyledComponent = (\n target: Target,\n options: Object,\n rules: RuleSet\n ) => {\n const {\n displayName = isTag(target)\n ? `styled.${target}`\n : `Styled(${getComponentName(target)})`,\n componentId = generateId(options.displayName, options.parentComponentId),\n ParentComponent = BaseStyledComponent,\n rules: extendingRules,\n attrs,\n } = options\n\n const styledComponentId =\n options.displayName && options.componentId\n ? `${escape(options.displayName)}-${options.componentId}`\n : componentId\n\n const componentStyle = new ComponentStyle(\n extendingRules === undefined ? rules : extendingRules.concat(rules),\n attrs,\n styledComponentId\n )\n\n class StyledComponent extends ParentComponent {\n static contextTypes = {\n [CHANNEL]: PropTypes.func,\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n [CONTEXT_KEY]: PropTypes.oneOfType([\n PropTypes.instanceOf(StyleSheet),\n PropTypes.instanceOf(ServerStyleSheet),\n ]),\n }\n\n static displayName = displayName\n static styledComponentId = styledComponentId\n static attrs = attrs\n static componentStyle = componentStyle\n static target = target\n\n static withComponent(tag) {\n const { componentId: previousComponentId, ...optionsToCopy } = options\n\n const newComponentId =\n previousComponentId &&\n `${previousComponentId}-${\n isTag(tag) ? tag : escape(getComponentName(tag))\n }`\n\n const newOptions = {\n ...optionsToCopy,\n componentId: newComponentId,\n ParentComponent: StyledComponent,\n }\n\n return createStyledComponent(tag, newOptions, rules)\n }\n\n static get extend() {\n const {\n rules: rulesFromOptions,\n componentId: parentComponentId,\n ...optionsToCopy\n } = options\n\n const newRules =\n rulesFromOptions === undefined\n ? rules\n : rulesFromOptions.concat(rules)\n\n const newOptions = {\n ...optionsToCopy,\n rules: newRules,\n parentComponentId,\n ParentComponent: StyledComponent,\n }\n\n return constructWithOptions(createStyledComponent, target, newOptions)\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n StyledComponent.warnTooManyClasses = createWarnTooManyClasses(displayName)\n }\n\n return StyledComponent\n }\n\n return createStyledComponent\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\n\nimport type { RuleSet, NameGenerator, Flattener, Stringifier } from '../types'\nimport StyleSheet from './StyleSheet'\nimport isStyledComponent from '../utils/isStyledComponent'\n\nconst isStaticRules = (rules: RuleSet, attrs?: Object): boolean => {\n for (let i = 0; i < rules.length; i += 1) {\n const rule = rules[i]\n\n // recursive case\n if (Array.isArray(rule) && !isStaticRules(rule)) {\n return false\n } else if (typeof rule === 'function' && !isStyledComponent(rule)) {\n // functions are allowed to be static if they're just being\n // used to get the classname of a nested styled copmonent\n return false\n }\n }\n\n if (attrs !== undefined) {\n // eslint-disable-next-line guard-for-in, no-restricted-syntax\n for (const key in attrs) {\n const value = attrs[key]\n if (typeof value === 'function') {\n return false\n }\n }\n }\n\n return true\n}\n\nconst isHRMEnabled =\n typeof module !== 'undefined' &&\n module.hot &&\n process.env.NODE_ENV !== 'production'\n\n/*\n ComponentStyle is all the CSS-specific stuff, not\n the React-specific stuff.\n */\nexport default (\n nameGenerator: NameGenerator,\n flatten: Flattener,\n stringifyRules: Stringifier\n) => {\n class ComponentStyle {\n rules: RuleSet\n componentId: string\n isStatic: boolean\n lastClassName: ?string\n\n constructor(rules: RuleSet, attrs?: Object, componentId: string) {\n this.rules = rules\n this.isStatic = !isHRMEnabled && isStaticRules(rules, attrs)\n this.componentId = componentId\n if (!StyleSheet.instance.hasInjectedComponent(this.componentId)) {\n const placeholder =\n process.env.NODE_ENV !== 'production' ? `.${componentId} {}` : ''\n StyleSheet.instance.deferredInject(componentId, true, [placeholder])\n }\n }\n\n /*\n * Flattens a rule set into valid CSS\n * Hashes it, wraps the whole chunk in a .hash1234 {}\n * Returns the hash to be injected on render()\n * */\n generateAndInjectStyles(executionContext: Object, styleSheet: StyleSheet) {\n const { isStatic, lastClassName } = this\n if (isStatic && lastClassName !== undefined) {\n return lastClassName\n }\n\n const flatCSS = flatten(this.rules, executionContext)\n const hash = hashStr(this.componentId + flatCSS.join(''))\n\n const { stylesCacheable } = styleSheet\n const existingName = styleSheet.getName(hash)\n\n if (existingName !== undefined) {\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n return existingName\n }\n\n const name = nameGenerator(hash)\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n if (styleSheet.alreadyInjected(hash, name)) {\n return name\n }\n\n const css = stringifyRules(flatCSS, `.${name}`)\n // NOTE: this can only be set when we inject the class-name.\n // For some reason, presumably due to how css is stringifyRules behaves in\n // differently between client and server, styles break.\n styleSheet.inject(this.componentId, true, css, hash, name)\n return name\n }\n\n static generateName(str: string) {\n return nameGenerator(hashStr(str))\n }\n }\n\n return ComponentStyle\n}\n","// @flow\nimport type { Target } from '../types'\nimport domElements from '../utils/domElements'\n\nexport default (styledComponent: Function, constructWithOptions: Function) => {\n const styled = (tag: Target) => constructWithOptions(styledComponent, tag)\n\n // Shorthands for all valid HTML Elements\n domElements.forEach(domElement => {\n styled[domElement] = styled(domElement)\n })\n\n return styled\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\nimport type { Interpolation, NameGenerator, Stringifier } from '../types'\nimport StyleSheet from '../models/StyleSheet'\n\nconst replaceWhitespace = (str: string): string => str.replace(/\\s|\\\\n/g, '')\n\nexport default (\n nameGenerator: NameGenerator,\n stringifyRules: Stringifier,\n css: Function\n) => (\n strings: Array<string>,\n ...interpolations: Array<Interpolation>\n): string => {\n const rules = css(strings, ...interpolations)\n const hash = hashStr(replaceWhitespace(JSON.stringify(rules)))\n\n const existingName = StyleSheet.instance.getName(hash)\n if (existingName) return existingName\n\n const name = nameGenerator(hash)\n if (StyleSheet.instance.alreadyInjected(hash, name)) return name\n\n const generatedCSS = stringifyRules(rules, name, '@keyframes')\n StyleSheet.instance.inject(\n `sc-keyframes-${name}`,\n true,\n generatedCSS,\n hash,\n name\n )\n return name\n}\n"],"names":["deferredInjections","isStreaming","nonce","componentWillMount","state","unsubscribeId","attrs","reduce","length","i"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,iGAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SCMEA;;;;;;;SAoBOC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBC6CWC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5EpB,kCAAA;AACA,yCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BA0BEC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+JCSEC;;;eAIAC;;;;;;;;;;;;;;;;;+BAe2BC,OAAYC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BCnEfC,QAA0BC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA0ClD,OAAA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChDJ;;;;;;;;;;;;;;;;;;;SCSK,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -686,7 +686,7 @@ var BrowserStyleSheet = {
|
|
|
686
686
|
});
|
|
687
687
|
}
|
|
688
688
|
|
|
689
|
-
tags.push(new BrowserTag(el, el.getAttribute(LOCAL_ATTR) === 'true', el.
|
|
689
|
+
tags.push(new BrowserTag(el, el.getAttribute(LOCAL_ATTR) === 'true', el.textContent));
|
|
690
690
|
}
|
|
691
691
|
|
|
692
692
|
/* Factory for making more tags */
|
|
@@ -733,6 +733,7 @@ var StyleSheet = function () {
|
|
|
733
733
|
this.tags = tags;
|
|
734
734
|
this.names = names;
|
|
735
735
|
this.constructComponentTagMap();
|
|
736
|
+
this.isStreaming = false;
|
|
736
737
|
}
|
|
737
738
|
|
|
738
739
|
// helper for `ComponentStyle` to know when it cache static styles.
|
|
@@ -828,7 +829,12 @@ var StyleSheet = function () {
|
|
|
828
829
|
|
|
829
830
|
StyleSheet.prototype.getOrCreateTag = function getOrCreateTag(componentId, isLocal) {
|
|
830
831
|
var existingTag = this.componentTags[componentId];
|
|
831
|
-
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* in a streaming context, once a tag is sealed it can never be added to again
|
|
835
|
+
* or those styles will never make it to the client
|
|
836
|
+
*/
|
|
837
|
+
if (existingTag && this.isStreaming ? !existingTag.isSealed() : existingTag) {
|
|
832
838
|
return existingTag;
|
|
833
839
|
}
|
|
834
840
|
|
|
@@ -1026,7 +1032,7 @@ var ServerStyleSheet = function () {
|
|
|
1026
1032
|
classCallCheck(this, ServerStyleSheet);
|
|
1027
1033
|
|
|
1028
1034
|
this.instance = StyleSheet.clone(StyleSheet.instance);
|
|
1029
|
-
this.isStreaming = false;
|
|
1035
|
+
this.instance.isStreaming = false;
|
|
1030
1036
|
}
|
|
1031
1037
|
|
|
1032
1038
|
ServerStyleSheet.prototype.collectStyles = function collectStyles(children) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styled-components-no-parser.browser.es.js","sources":["../src/models/BrowserStyleSheet.js","../src/models/StyleSheet.js","../src/models/ServerStyleSheet.js","../src/models/ThemeProvider.js","../src/models/StyledComponent.js","../src/models/ComponentStyle.js","../src/constructors/styled.js","../src/constructors/keyframes.js"],"sourcesContent":["// @flow\n/* eslint-disable no-underscore-dangle */\n/*\n * Browser Style Sheet with Rehydration\n *\n * <style data-styled-components=\"x y z\"\n * data-styled-components-is-local=\"true\">\n * /· sc-component-id: a ·/\n * .sc-a { ... }\n * .x { ... }\n * /· sc-component-id: b ·/\n * .sc-b { ... }\n * .y { ... }\n * .z { ... }\n * </style>\n *\n * Note: replace · with * in the above snippet.\n * */\nimport extractCompsFromCSS from '../utils/extractCompsFromCSS'\nimport stringifyRules from '../utils/stringifyRules'\nimport getNonce from '../utils/nonce'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR } from './StyleSheet'\n\ndeclare var __DEV__: ?string\n\nconst DISABLE_SPEEDY =\n (typeof __DEV__ === 'boolean' && __DEV__) ||\n process.env.NODE_ENV !== 'production'\n\nconst COMPONENTS_PER_TAG = 40\nconst SPEEDY_COMPONENTS_PER_TAG = 1000 // insertRule allows more injections before a perf slowdown\n\n// Source: https://github.com/threepointone/glamor/blob/master/src/sheet.js#L32-L43\nconst sheetForTag = (tag: HTMLStyleElement): CSSStyleSheet => {\n if (tag.sheet) {\n // $FlowFixMe\n return tag.sheet\n }\n\n for (let i = 0; i < document.styleSheets.length; i += 1) {\n if (document.styleSheets[i].ownerNode === tag) {\n // $FlowFixMe\n return document.styleSheets[i]\n }\n }\n\n // NOTE: This should never happen\n throw new Error('')\n}\n\n// Safely (try/catch) injects rule at index and returns whether it was successful\nconst safeInsertRule = (\n sheet: CSSStyleSheet,\n cssRule: string,\n index: number\n): boolean => {\n if (cssRule === undefined || cssRule.length === 0) {\n return false\n }\n\n const maxIndex = sheet.cssRules.length\n const cappedIndex = index <= maxIndex ? index : maxIndex\n\n try {\n sheet.insertRule(cssRule, cappedIndex)\n } catch (err) {\n // NOTE: An invalid rule here means it's not supported by the browser or obviously malformed\n return false\n }\n\n return true\n}\n\n// Counts up the number of rules inside the array until a specific component entry is found\n// This is used to determine the necessary insertRule index\nconst sizeUpToComponentIndex = (\n componentSizes: Array<number>,\n componentIndex: number\n) => {\n let cssRulesSize = 0\n for (let i = 0; i <= componentIndex; i += 1) {\n cssRulesSize += componentSizes[i]\n }\n\n return cssRulesSize\n}\n\nclass BaseBrowserTag {\n components: { [string]: Object }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n}\n\nlet BrowserTag\nif (!DISABLE_SPEEDY) {\n BrowserTag = class SpeedyBrowserTag extends BaseBrowserTag implements Tag {\n // Store component ruleSizes in an array per component (in order)\n componentSizes: Array<number>\n components: { [string]: Object }\n\n isLocal: boolean\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: ?string\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.componentSizes = []\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // workaround for an IE/Edge bug: https://twitter.com/probablyup/status/958138927981977600\n newEl.appendChild(document.createTextNode(''))\n\n // $FlowFixMe\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n this.ready = true\n\n // Retrieve the sheet for the new style tag\n const sheet = sheetForTag(newEl)\n\n Object.keys(this.components).forEach(componentId => {\n const comp = this.components[componentId]\n const { cssFromDOM } = comp\n const rules = stringifyRules([cssFromDOM])\n const rulesSize = rules.length\n\n let injectedRules = 0\n for (let j = 0; j < rulesSize; j += 1) {\n if (safeInsertRule(sheet, rules[j], sheet.cssRules.length)) {\n injectedRules += 1\n }\n }\n\n comp.componentIndex = this.componentSizes.length\n comp.css = rules.join(' ')\n this.componentSizes.push(injectedRules)\n })\n }\n\n isSealed() {\n return this.size >= SPEEDY_COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n this.components[componentId] = {\n componentIndex: this.componentSizes.length,\n css: '',\n }\n\n this.componentSizes.push(0)\n this.size += 1\n }\n\n inject(componentId: string, cssRules: Array<string>, name: ?string) {\n if (!this.ready) this.replaceElement()\n\n const comp = this.components[componentId]\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n const cssRulesSize = cssRules.length\n const sheet = sheetForTag(this.el)\n const { componentIndex } = comp\n\n // Determine start index for injection\n const insertIndex = sizeUpToComponentIndex(\n this.componentSizes,\n componentIndex\n )\n\n // Inject each rule shifting index forward for each one (in-order injection)\n let injectedRules = 0\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = cssRules[i]\n if (safeInsertRule(sheet, cssRule, insertIndex + injectedRules)) {\n comp.css += ` ${cssRule}`\n injectedRules += 1\n }\n }\n\n // Update number of rules for component\n this.componentSizes[componentIndex] += injectedRules\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toRawCSS() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n\n toHTML() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n }\n} else {\n BrowserTag = class TextNodeBrowserTag extends BaseBrowserTag implements Tag {\n isLocal: boolean\n components: { [string]: Object }\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: string = ''\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce !== null) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n isSealed() {\n return this.size >= COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n const comp = { componentId, textNode: document.createTextNode('') }\n this.el.appendChild(comp.textNode)\n this.size += 1\n this.components[componentId] = comp\n }\n\n inject(componentId: string, css: Array<string>, name: ?string) {\n if (!this.ready) this.replaceElement()\n const comp = this.components[componentId]\n\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n if (comp.textNode.data === '') {\n comp.textNode.appendData(`\\n/* sc-component-id: ${componentId} */\\n`)\n }\n\n comp.textNode.appendData(css.join(' '))\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toHTML() {\n return this.el.outerHTML\n }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n this.ready = true\n // We have nothing to inject. Use the current el.\n if (this.size === 0) return\n\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n newEl.appendChild(document.createTextNode('\\n'))\n\n Object.keys(this.components).forEach(key => {\n const comp = this.components[key]\n\n // eslint-disable-next-line no-param-reassign\n comp.textNode = document.createTextNode(comp.cssFromDOM)\n newEl.appendChild(comp.textNode)\n })\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // The ol' switcheroo\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n }\n }\n}\n\n/* Factory function to separate DOM operations from logical ones*/\nexport default {\n create() {\n const tags = []\n const names = {}\n\n /* Construct existing state from DOM */\n const nodes = document.querySelectorAll(`[${SC_ATTR}]`)\n const nodesLength = nodes.length\n\n for (let i = 0; i < nodesLength; i += 1) {\n // $FlowFixMe: We can trust that all elements in this query are style elements\n const el = (nodes[i]: HTMLStyleElement)\n const attr = el.getAttribute(SC_ATTR)\n\n if (attr) {\n attr\n .trim()\n .split(/\\s+/)\n .forEach(name => {\n names[name] = true\n })\n }\n\n tags.push(\n new BrowserTag(el, el.getAttribute(LOCAL_ATTR) === 'true', el.innerHTML)\n )\n }\n\n /* Factory for making more tags */\n const tagConstructor = (isLocal: boolean): Tag => {\n const el = document.createElement('style')\n el.type = 'text/css'\n el.setAttribute(SC_ATTR, '')\n el.setAttribute(LOCAL_ATTR, isLocal ? 'true' : 'false')\n if (!document.head) {\n throw new Error(\n process.env.NODE_ENV !== 'production' ? 'Missing document <head>' : ''\n )\n }\n document.head.appendChild(el)\n return new BrowserTag(el, isLocal)\n }\n\n return new StyleSheet(tagConstructor, tags, names)\n },\n}\n","// @flow\nimport React from 'react'\nimport BrowserStyleSheet from './BrowserStyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\nexport const SC_ATTR = 'data-styled-components'\nexport const LOCAL_ATTR = 'data-styled-components-is-local'\nexport const CONTEXT_KEY = '__styled-components-stylesheet__'\n\n/* eslint-disable flowtype/object-type-delimiter */\nexport interface Tag {\n isLocal: boolean;\n\n isSealed(): boolean;\n getComponentIds(): Array<string>;\n addComponent(componentId: string): void;\n inject(componentId: string, css: Array<string>, name: ?string): void;\n toHTML(): string;\n toReactElement(key: string): React.Element<*>;\n clone(): Tag;\n}\n/* eslint-enable flowtype/object-type-delimiter */\n\nlet instance = null\n// eslint-disable-next-line no-use-before-define\nexport const clones: Array<StyleSheet> = []\n\nconst IS_BROWSER = typeof document !== 'undefined'\n\nexport default class StyleSheet {\n tagConstructor: boolean => Tag\n tags: Array<Tag>\n names: { [string]: boolean }\n hashes: { [string]: string } = {}\n deferredInjections: { [string]: Array<string> } = {}\n componentTags: { [string]: Tag }\n\n // helper for `ComponentStyle` to know when it cache static styles.\n // staticly styled-component can not safely cache styles on the server\n // without all `ComponentStyle` instances saving a reference to the\n // the styleSheet instance they last rendered with,\n // or listening to creation / reset events. otherwise you might create\n // a component with one stylesheet and render it another api response\n // with another, losing styles on from your server-side render.\n stylesCacheable = IS_BROWSER\n\n constructor(\n tagConstructor: boolean => Tag,\n tags: Array<Tag> = [],\n names: { [string]: boolean } = {}\n ) {\n this.tagConstructor = tagConstructor\n this.tags = tags\n this.names = names\n this.constructComponentTagMap()\n }\n\n constructComponentTagMap() {\n this.componentTags = {}\n\n this.tags.forEach(tag => {\n tag.getComponentIds().forEach(componentId => {\n this.componentTags[componentId] = tag\n })\n })\n }\n\n /* Best level of caching—get the name from the hash straight away. */\n getName(hash: any) {\n return this.hashes[hash.toString()]\n }\n\n /* Second level of caching—if the name is already in the dom, don't\n * inject anything and record the hash for getName next time. */\n alreadyInjected(hash: any, name: string) {\n if (!this.names[name]) return false\n\n this.hashes[hash.toString()] = name\n return true\n }\n\n /* Third type of caching—don't inject components' componentId twice. */\n hasInjectedComponent(componentId: string) {\n return !!this.componentTags[componentId]\n }\n\n deferredInject(componentId: string, isLocal: boolean, css: Array<string>) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.deferredInject(componentId, isLocal, css)\n })\n }\n\n this.getOrCreateTag(componentId, isLocal)\n this.deferredInjections[componentId] = css\n }\n\n inject(\n componentId: string,\n isLocal: boolean,\n css: Array<string>,\n hash: ?any,\n name: ?string\n ) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.inject(componentId, isLocal, css)\n })\n }\n\n const tag = this.getOrCreateTag(componentId, isLocal)\n\n const deferredInjection = this.deferredInjections[componentId]\n if (deferredInjection) {\n tag.inject(componentId, deferredInjection)\n delete this.deferredInjections[componentId]\n }\n\n tag.inject(componentId, css, name)\n\n if (hash && name) {\n this.hashes[hash.toString()] = name\n }\n }\n\n toHTML() {\n return this.tags.map(tag => tag.toHTML()).join('')\n }\n\n toReactElements() {\n return this.tags.map((tag, i) => tag.toReactElement(`sc-${i}`))\n }\n\n getOrCreateTag(componentId: string, isLocal: boolean) {\n const existingTag = this.componentTags[componentId]\n if (existingTag) {\n return existingTag\n }\n\n const lastTag = this.tags[this.tags.length - 1]\n const componentTag =\n !lastTag || lastTag.isSealed() || lastTag.isLocal !== isLocal\n ? this.createNewTag(isLocal)\n : lastTag\n this.componentTags[componentId] = componentTag\n componentTag.addComponent(componentId)\n return componentTag\n }\n\n createNewTag(isLocal: boolean) {\n const newTag = this.tagConstructor(isLocal)\n this.tags.push(newTag)\n return newTag\n }\n\n static get instance() {\n return instance || (instance = StyleSheet.create())\n }\n\n static reset(isServer: ?boolean) {\n instance = StyleSheet.create(isServer)\n }\n\n /* We can make isServer totally implicit once Jest 20 drops and we\n * can change environment on a per-test basis. */\n static create(isServer: ?boolean = !IS_BROWSER) {\n return (isServer ? ServerStyleSheet : BrowserStyleSheet).create()\n }\n\n static clone(oldSheet: StyleSheet) {\n const newSheet = new StyleSheet(\n oldSheet.tagConstructor,\n oldSheet.tags.map(tag => tag.clone()),\n { ...oldSheet.names }\n )\n\n newSheet.hashes = { ...oldSheet.hashes }\n newSheet.deferredInjections = { ...oldSheet.deferredInjections }\n clones.push(newSheet)\n\n return newSheet\n }\n}\n","// @flow\n/* eslint-disable no-underscore-dangle */\nimport React from 'react'\nimport stream from 'stream'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR, clones } from './StyleSheet'\nimport StyleSheetManager from './StyleSheetManager'\nimport getNonce from '../utils/nonce'\n\ndeclare var __SERVER__: boolean\n\nclass ServerTag implements Tag {\n emitted: boolean\n isLocal: boolean\n isProduction: boolean\n components: { [string]: Object }\n size: number\n names: Array<string>\n\n constructor(isLocal: boolean) {\n this.emitted = false\n this.isLocal = isLocal\n this.isProduction = process.env.NODE_ENV === 'production'\n this.components = {}\n this.size = 0\n this.names = []\n }\n\n isSealed() {\n return this.emitted\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n\n addComponent(componentId: string) {\n if (this.components[componentId]) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? `Trying to add Component '${componentId}' twice!`\n : ''\n )\n }\n this.components[componentId] = { componentId, css: '' }\n this.size += 1\n }\n\n concatenateCSS() {\n return Object.keys(this.components).reduce(\n (styles, k) => styles + this.components[k].css,\n ''\n )\n }\n\n inject(componentId: string, css: Array<string>, name: ?string) {\n const comp = this.components[componentId]\n\n if (!comp) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'Must add a new component before you can inject css into it'\n : ''\n )\n }\n\n if (comp.css === '') {\n comp.css = `/* sc-component-id: ${componentId} */\\n`\n }\n\n const cssRulesSize = css.length\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = css[i]\n comp.css += `${cssRule}\\n`.replace(/\\n*$/, '\\n')\n }\n\n if (name) this.names.push(name)\n }\n\n toHTML() {\n const attrs: Array<string> = [\n 'type=\"text/css\"',\n `${SC_ATTR}=\"${this.names.join(' ')}\"`,\n `${LOCAL_ATTR}=\"${this.isLocal ? 'true' : 'false'}\"`,\n ]\n\n const nonce = getNonce()\n if (nonce) {\n attrs.push(`nonce=\"${nonce}\"`)\n }\n\n this.emitted = true\n return `<style ${attrs.join(' ')}>${this.concatenateCSS()}</style>`\n }\n\n toReactElement(key: string) {\n const attrs: Object = {\n [SC_ATTR]: this.names.join(' '),\n [LOCAL_ATTR]: this.isLocal.toString(),\n }\n\n const nonce = getNonce()\n if (nonce) {\n attrs.nonce = nonce\n }\n\n this.emitted = true\n\n return (\n <style\n key={key}\n type=\"text/css\"\n {...attrs}\n dangerouslySetInnerHTML={{ __html: this.concatenateCSS() }}\n />\n )\n }\n\n clone() {\n const copy = new ServerTag(this.isLocal)\n copy.names = [].concat(this.names)\n copy.size = this.size\n copy.components = Object.keys(this.components).reduce((acc, key) => {\n acc[key] = { ...this.components[key] } // eslint-disable-line no-param-reassign\n return acc\n }, {})\n\n return copy\n }\n}\n\nexport default class ServerStyleSheet {\n closed: boolean\n instance: StyleSheet\n isStreaming: boolean\n lastIndex: number\n\n constructor() {\n this.instance = StyleSheet.clone(StyleSheet.instance)\n this.isStreaming = false\n }\n\n collectStyles(children: any) {\n if (this.closed) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Can't collect styles once you've called getStyleTags!\"\n : ''\n )\n }\n return (\n <StyleSheetManager sheet={this.instance}>{children}</StyleSheetManager>\n )\n }\n\n close() {\n clones.splice(clones.indexOf(this.instance), 1)\n this.closed = true\n }\n\n getStyleTags(): string {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toHTML()\n }\n\n getStyleElement() {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toReactElements()\n }\n\n interleaveWithNodeStream(readableStream: stream.Readable) {\n if (__SERVER__) {\n const ourStream = new stream.Readable()\n\n // $FlowFixMe\n ourStream._read = () => {}\n\n this.isStreaming = true\n this.lastIndex = 0\n\n readableStream.on('data', chunk => {\n ourStream.push(\n this.instance.tags\n .slice(this.lastIndex)\n .map(tag => tag.toHTML())\n .join('') + chunk\n )\n\n this.lastIndex = this.instance.tags.length - 1\n })\n\n readableStream.on('end', () => {\n ourStream.push(null)\n this.close()\n })\n\n readableStream.on('error', err => {\n ourStream.emit('error', err)\n this.close()\n })\n\n return ourStream\n } else {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'streaming only works in Node.js, please do not try to call this method in the browser'\n : ''\n )\n }\n }\n\n static create() {\n return new StyleSheet(isLocal => new ServerTag(isLocal))\n }\n}\n","// @flow\n/* globals React$Element */\nimport React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport isPlainObject from 'is-plain-object'\nimport createBroadcast from '../utils/create-broadcast'\nimport type { Broadcast } from '../utils/create-broadcast'\nimport once from '../utils/once'\n\n// NOTE: DO NOT CHANGE, changing this is a semver major change!\nexport const CHANNEL = '__styled-components__'\nexport const CHANNEL_NEXT = `${CHANNEL}next__`\n\nexport const CONTEXT_CHANNEL_SHAPE = PropTypes.shape({\n getTheme: PropTypes.func,\n subscribe: PropTypes.func,\n unsubscribe: PropTypes.func,\n})\n\nexport type Theme = { [key: string]: mixed }\ntype ThemeProviderProps = {|\n children?: React$Element<any>,\n theme: Theme | ((outerTheme: Theme) => void),\n|}\n\nlet warnChannelDeprecated\nif (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated = once(() => {\n // eslint-disable-next-line no-console\n console.error(\n `Warning: Usage of \\`context.${CHANNEL}\\` as a function is deprecated. It will be replaced with the object on \\`.context.${CHANNEL_NEXT}\\` in a future version.`\n )\n })\n}\n\nconst isFunction = test => typeof test === 'function'\n\n/**\n * Provide a theme to an entire react component tree via context and event listeners (have to do\n * both context and event emitter as pure components block context updates)\n */\nclass ThemeProvider extends Component {\n getTheme: (theme?: Theme | ((outerTheme: Theme) => void)) => Theme\n outerTheme: Theme\n unsubscribeToOuterId: string\n props: ThemeProviderProps\n broadcast: Broadcast\n unsubscribeToOuterId: number = -1\n\n constructor() {\n super()\n this.getTheme = this.getTheme.bind(this)\n }\n\n componentWillMount() {\n // If there is a ThemeProvider wrapper anywhere around this theme provider, merge this theme\n // with the outer theme\n const outerContext = this.context[CHANNEL_NEXT]\n if (outerContext !== undefined) {\n this.unsubscribeToOuterId = outerContext.subscribe(theme => {\n this.outerTheme = theme\n\n if (this.broadcast !== undefined) {\n this.publish(this.props.theme)\n }\n })\n }\n\n this.broadcast = createBroadcast(this.getTheme())\n }\n\n getChildContext() {\n return {\n ...this.context,\n [CHANNEL_NEXT]: {\n getTheme: this.getTheme,\n subscribe: this.broadcast.subscribe,\n unsubscribe: this.broadcast.unsubscribe,\n },\n [CHANNEL]: subscriber => {\n if (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated()\n }\n\n // Patch the old `subscribe` provide via `CHANNEL` for older clients.\n const unsubscribeId = this.broadcast.subscribe(subscriber)\n return () => this.broadcast.unsubscribe(unsubscribeId)\n },\n }\n }\n\n componentWillReceiveProps(nextProps: ThemeProviderProps) {\n if (this.props.theme !== nextProps.theme) {\n this.publish(nextProps.theme)\n }\n }\n\n componentWillUnmount() {\n if (this.unsubscribeToOuterId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeToOuterId)\n }\n }\n\n // Get the theme from the props, supporting both (outerTheme) => {} as well as object notation\n getTheme(passedTheme: (outerTheme: Theme) => void | Theme) {\n const theme = passedTheme || this.props.theme\n if (isFunction(theme)) {\n const mergedTheme = theme(this.outerTheme)\n if (\n process.env.NODE_ENV !== 'production' &&\n !isPlainObject(mergedTheme)\n ) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!'\n : ''\n )\n }\n return mergedTheme\n }\n if (!isPlainObject(theme)) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please make your theme prop a plain object'\n : ''\n )\n }\n return { ...this.outerTheme, ...(theme: Object) }\n }\n\n publish(theme: Theme | ((outerTheme: Theme) => void)) {\n this.broadcast.publish(this.getTheme(theme))\n }\n\n render() {\n if (!this.props.children) {\n return null\n }\n return React.Children.only(this.props.children)\n }\n}\n\nThemeProvider.childContextTypes = {\n [CHANNEL]: PropTypes.func, // legacy\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\nThemeProvider.contextTypes = {\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\n\nexport default ThemeProvider\n","// @flow\n\nimport { Component, createElement } from 'react'\nimport PropTypes from 'prop-types'\n\nimport type { Theme } from './ThemeProvider'\nimport createWarnTooManyClasses from '../utils/createWarnTooManyClasses'\n\nimport validAttr from '../utils/validAttr'\nimport isTag from '../utils/isTag'\nimport isStyledComponent from '../utils/isStyledComponent'\nimport getComponentName from '../utils/getComponentName'\nimport determineTheme from '../utils/determineTheme'\nimport escape from '../utils/escape'\nimport type { RuleSet, Target } from '../types'\n\nimport { CHANNEL, CHANNEL_NEXT, CONTEXT_CHANNEL_SHAPE } from './ThemeProvider'\nimport StyleSheet, { CONTEXT_KEY } from './StyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\n// HACK for generating all static styles without needing to allocate\n// an empty execution context every single time...\nconst STATIC_EXECUTION_CONTEXT = {}\n\nexport default (ComponentStyle: Function, constructWithOptions: Function) => {\n const identifiers = {}\n\n /* We depend on components having unique IDs */\n const generateId = (_displayName: string, parentComponentId: string) => {\n const displayName =\n typeof _displayName !== 'string' ? 'sc' : escape(_displayName)\n\n let componentId\n\n /**\n * only fall back to hashing the component injection order if\n * a proper displayName isn't provided by the babel plugin\n */\n if (!_displayName) {\n const nr = (identifiers[displayName] || 0) + 1\n identifiers[displayName] = nr\n\n componentId = `${displayName}-${ComponentStyle.generateName(\n displayName + nr\n )}`\n } else {\n componentId = `${displayName}-${ComponentStyle.generateName(displayName)}`\n }\n\n return parentComponentId !== undefined\n ? `${parentComponentId}-${componentId}`\n : componentId\n }\n\n class BaseStyledComponent extends Component {\n static target: Target\n static styledComponentId: string\n static attrs: Object\n static componentStyle: Object\n static warnTooManyClasses: Function\n\n attrs = {}\n state = {\n theme: null,\n generatedClassName: '',\n }\n unsubscribeId: number = -1\n\n unsubscribeFromContext() {\n if (this.unsubscribeId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeId)\n }\n }\n\n buildExecutionContext(theme: any, props: any) {\n const { attrs } = this.constructor\n const context = { ...props, theme }\n if (attrs === undefined) {\n return context\n }\n\n this.attrs = Object.keys(attrs).reduce((acc, key) => {\n const attr = attrs[key]\n // eslint-disable-next-line no-param-reassign\n acc[key] = typeof attr === 'function' ? attr(context) : attr\n return acc\n }, {})\n\n return { ...context, ...this.attrs }\n }\n\n generateAndInjectStyles(theme: any, props: any) {\n const { attrs, componentStyle, warnTooManyClasses } = this.constructor\n const styleSheet = this.context[CONTEXT_KEY] || StyleSheet.instance\n\n // staticaly styled-components don't need to build an execution context object,\n // and shouldn't be increasing the number of class names\n if (componentStyle.isStatic && attrs === undefined) {\n return componentStyle.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n styleSheet\n )\n } else {\n const executionContext = this.buildExecutionContext(theme, props)\n const className = componentStyle.generateAndInjectStyles(\n executionContext,\n styleSheet\n )\n\n if (\n process.env.NODE_ENV !== 'production' &&\n warnTooManyClasses !== undefined\n ) {\n warnTooManyClasses(className)\n }\n\n return className\n }\n }\n\n componentWillMount() {\n const { componentStyle } = this.constructor\n const styledContext = this.context[CHANNEL_NEXT]\n\n // If this is a staticaly-styled component, we don't need to the theme\n // to generate or build styles.\n if (componentStyle.isStatic) {\n const generatedClassName = this.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n this.props\n )\n this.setState({ generatedClassName })\n // If there is a theme in the context, subscribe to the event emitter. This\n // is necessary due to pure components blocking context updates, this circumvents\n // that by updating when an event is emitted\n } else if (styledContext !== undefined) {\n const { subscribe } = styledContext\n this.unsubscribeId = subscribe(nextTheme => {\n // This will be called once immediately\n const theme = determineTheme(\n this.props,\n nextTheme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n\n this.setState({ theme, generatedClassName })\n })\n } else {\n // eslint-disable-next-line react/prop-types\n const theme = this.props.theme || {}\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n this.setState({ theme, generatedClassName })\n }\n }\n\n componentWillReceiveProps(nextProps: {\n theme?: Theme,\n [key: string]: any,\n }) {\n // If this is a staticaly-styled component, we don't need to listen to\n // props changes to update styles\n const { componentStyle } = this.constructor\n if (componentStyle.isStatic) {\n return\n }\n\n this.setState(oldState => {\n const theme = determineTheme(\n nextProps,\n oldState.theme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n nextProps\n )\n\n return { theme, generatedClassName }\n })\n }\n\n componentWillUnmount() {\n this.unsubscribeFromContext()\n }\n\n render() {\n // eslint-disable-next-line react/prop-types\n const { innerRef } = this.props\n const { generatedClassName } = this.state\n const { styledComponentId, target } = this.constructor\n\n const isTargetTag = isTag(target)\n\n const className = [\n // eslint-disable-next-line react/prop-types\n this.props.className,\n styledComponentId,\n this.attrs.className,\n generatedClassName,\n ]\n .filter(Boolean)\n .join(' ')\n\n const baseProps = {\n ...this.attrs,\n className,\n }\n\n if (isStyledComponent(target)) {\n baseProps.innerRef = innerRef\n } else {\n baseProps.ref = innerRef\n }\n\n const propsForElement = Object.keys(this.props).reduce(\n (acc, propName) => {\n // Don't pass through non HTML tags through to HTML elements\n // always omit innerRef\n if (\n propName !== 'innerRef' &&\n propName !== 'className' &&\n (!isTargetTag || validAttr(propName))\n ) {\n // eslint-disable-next-line no-param-reassign\n acc[propName] = this.props[propName]\n }\n\n return acc\n },\n baseProps\n )\n\n return createElement(target, propsForElement)\n }\n }\n\n const createStyledComponent = (\n target: Target,\n options: Object,\n rules: RuleSet\n ) => {\n const {\n displayName = isTag(target)\n ? `styled.${target}`\n : `Styled(${getComponentName(target)})`,\n componentId = generateId(options.displayName, options.parentComponentId),\n ParentComponent = BaseStyledComponent,\n rules: extendingRules,\n attrs,\n } = options\n\n const styledComponentId =\n options.displayName && options.componentId\n ? `${escape(options.displayName)}-${options.componentId}`\n : componentId\n\n const componentStyle = new ComponentStyle(\n extendingRules === undefined ? rules : extendingRules.concat(rules),\n attrs,\n styledComponentId\n )\n\n class StyledComponent extends ParentComponent {\n static contextTypes = {\n [CHANNEL]: PropTypes.func,\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n [CONTEXT_KEY]: PropTypes.oneOfType([\n PropTypes.instanceOf(StyleSheet),\n PropTypes.instanceOf(ServerStyleSheet),\n ]),\n }\n\n static displayName = displayName\n static styledComponentId = styledComponentId\n static attrs = attrs\n static componentStyle = componentStyle\n static target = target\n\n static withComponent(tag) {\n const { componentId: previousComponentId, ...optionsToCopy } = options\n\n const newComponentId =\n previousComponentId &&\n `${previousComponentId}-${\n isTag(tag) ? tag : escape(getComponentName(tag))\n }`\n\n const newOptions = {\n ...optionsToCopy,\n componentId: newComponentId,\n ParentComponent: StyledComponent,\n }\n\n return createStyledComponent(tag, newOptions, rules)\n }\n\n static get extend() {\n const {\n rules: rulesFromOptions,\n componentId: parentComponentId,\n ...optionsToCopy\n } = options\n\n const newRules =\n rulesFromOptions === undefined\n ? rules\n : rulesFromOptions.concat(rules)\n\n const newOptions = {\n ...optionsToCopy,\n rules: newRules,\n parentComponentId,\n ParentComponent: StyledComponent,\n }\n\n return constructWithOptions(createStyledComponent, target, newOptions)\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n StyledComponent.warnTooManyClasses = createWarnTooManyClasses(displayName)\n }\n\n return StyledComponent\n }\n\n return createStyledComponent\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\n\nimport type { RuleSet, NameGenerator, Flattener, Stringifier } from '../types'\nimport StyleSheet from './StyleSheet'\nimport isStyledComponent from '../utils/isStyledComponent'\n\nconst isStaticRules = (rules: RuleSet, attrs?: Object): boolean => {\n for (let i = 0; i < rules.length; i += 1) {\n const rule = rules[i]\n\n // recursive case\n if (Array.isArray(rule) && !isStaticRules(rule)) {\n return false\n } else if (typeof rule === 'function' && !isStyledComponent(rule)) {\n // functions are allowed to be static if they're just being\n // used to get the classname of a nested styled copmonent\n return false\n }\n }\n\n if (attrs !== undefined) {\n // eslint-disable-next-line guard-for-in, no-restricted-syntax\n for (const key in attrs) {\n const value = attrs[key]\n if (typeof value === 'function') {\n return false\n }\n }\n }\n\n return true\n}\n\nconst isHRMEnabled =\n typeof module !== 'undefined' &&\n module.hot &&\n process.env.NODE_ENV !== 'production'\n\n/*\n ComponentStyle is all the CSS-specific stuff, not\n the React-specific stuff.\n */\nexport default (\n nameGenerator: NameGenerator,\n flatten: Flattener,\n stringifyRules: Stringifier\n) => {\n class ComponentStyle {\n rules: RuleSet\n componentId: string\n isStatic: boolean\n lastClassName: ?string\n\n constructor(rules: RuleSet, attrs?: Object, componentId: string) {\n this.rules = rules\n this.isStatic = !isHRMEnabled && isStaticRules(rules, attrs)\n this.componentId = componentId\n if (!StyleSheet.instance.hasInjectedComponent(this.componentId)) {\n const placeholder =\n process.env.NODE_ENV !== 'production' ? `.${componentId} {}` : ''\n StyleSheet.instance.deferredInject(componentId, true, [placeholder])\n }\n }\n\n /*\n * Flattens a rule set into valid CSS\n * Hashes it, wraps the whole chunk in a .hash1234 {}\n * Returns the hash to be injected on render()\n * */\n generateAndInjectStyles(executionContext: Object, styleSheet: StyleSheet) {\n const { isStatic, lastClassName } = this\n if (isStatic && lastClassName !== undefined) {\n return lastClassName\n }\n\n const flatCSS = flatten(this.rules, executionContext)\n const hash = hashStr(this.componentId + flatCSS.join(''))\n\n const { stylesCacheable } = styleSheet\n const existingName = styleSheet.getName(hash)\n\n if (existingName !== undefined) {\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n return existingName\n }\n\n const name = nameGenerator(hash)\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n if (styleSheet.alreadyInjected(hash, name)) {\n return name\n }\n\n const css = stringifyRules(flatCSS, `.${name}`)\n // NOTE: this can only be set when we inject the class-name.\n // For some reason, presumably due to how css is stringifyRules behaves in\n // differently between client and server, styles break.\n styleSheet.inject(this.componentId, true, css, hash, name)\n return name\n }\n\n static generateName(str: string) {\n return nameGenerator(hashStr(str))\n }\n }\n\n return ComponentStyle\n}\n","// @flow\nimport type { Target } from '../types'\nimport domElements from '../utils/domElements'\n\nexport default (styledComponent: Function, constructWithOptions: Function) => {\n const styled = (tag: Target) => constructWithOptions(styledComponent, tag)\n\n // Shorthands for all valid HTML Elements\n domElements.forEach(domElement => {\n styled[domElement] = styled(domElement)\n })\n\n return styled\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\nimport type { Interpolation, NameGenerator, Stringifier } from '../types'\nimport StyleSheet from '../models/StyleSheet'\n\nconst replaceWhitespace = (str: string): string => str.replace(/\\s|\\\\n/g, '')\n\nexport default (\n nameGenerator: NameGenerator,\n stringifyRules: Stringifier,\n css: Function\n) => (\n strings: Array<string>,\n ...interpolations: Array<Interpolation>\n): string => {\n const rules = css(strings, ...interpolations)\n const hash = hashStr(replaceWhitespace(JSON.stringify(rules)))\n\n const existingName = StyleSheet.instance.getName(hash)\n if (existingName) return existingName\n\n const name = nameGenerator(hash)\n if (StyleSheet.instance.alreadyInjected(hash, name)) return name\n\n const generatedCSS = stringifyRules(rules, name, '@keyframes')\n StyleSheet.instance.inject(\n `sc-keyframes-${name}`,\n true,\n generatedCSS,\n hash,\n name\n )\n return name\n}\n"],"names":["deferredInjections","constructComponentTagMap","nonce","componentWillMount","state","unsubscribeId","attrs","reduce","length","i"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,iGAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SCMEA;;;;;;SAmBOC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAoDD,YAAA,SAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBCNYC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5EpB,kCAAA;AACA,yCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BA0BEC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+JCSEC;;;eAIAC;;;;;;;;;;;;;;;;;+BAe2BC,OAAYC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BCnEfC,QAA0BC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA0ClD,OAAA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChDJ;;;;;;;;;;;;;;;;;;;SCSK,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"styled-components-no-parser.browser.es.js","sources":["../src/models/BrowserStyleSheet.js","../src/models/StyleSheet.js","../src/models/ServerStyleSheet.js","../src/models/ThemeProvider.js","../src/models/StyledComponent.js","../src/models/ComponentStyle.js","../src/constructors/styled.js","../src/constructors/keyframes.js"],"sourcesContent":["// @flow\n/* eslint-disable no-underscore-dangle */\n/*\n * Browser Style Sheet with Rehydration\n *\n * <style data-styled-components=\"x y z\"\n * data-styled-components-is-local=\"true\">\n * /· sc-component-id: a ·/\n * .sc-a { ... }\n * .x { ... }\n * /· sc-component-id: b ·/\n * .sc-b { ... }\n * .y { ... }\n * .z { ... }\n * </style>\n *\n * Note: replace · with * in the above snippet.\n * */\nimport extractCompsFromCSS from '../utils/extractCompsFromCSS'\nimport stringifyRules from '../utils/stringifyRules'\nimport getNonce from '../utils/nonce'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR } from './StyleSheet'\n\ndeclare var __DEV__: ?string\n\nconst DISABLE_SPEEDY =\n (typeof __DEV__ === 'boolean' && __DEV__) ||\n process.env.NODE_ENV !== 'production'\n\nconst COMPONENTS_PER_TAG = 40\nconst SPEEDY_COMPONENTS_PER_TAG = 1000 // insertRule allows more injections before a perf slowdown\n\n// Source: https://github.com/threepointone/glamor/blob/master/src/sheet.js#L32-L43\nconst sheetForTag = (tag: HTMLStyleElement): CSSStyleSheet => {\n if (tag.sheet) {\n // $FlowFixMe\n return tag.sheet\n }\n\n for (let i = 0; i < document.styleSheets.length; i += 1) {\n if (document.styleSheets[i].ownerNode === tag) {\n // $FlowFixMe\n return document.styleSheets[i]\n }\n }\n\n // NOTE: This should never happen\n throw new Error('')\n}\n\n// Safely (try/catch) injects rule at index and returns whether it was successful\nconst safeInsertRule = (\n sheet: CSSStyleSheet,\n cssRule: string,\n index: number\n): boolean => {\n if (cssRule === undefined || cssRule.length === 0) {\n return false\n }\n\n const maxIndex = sheet.cssRules.length\n const cappedIndex = index <= maxIndex ? index : maxIndex\n\n try {\n sheet.insertRule(cssRule, cappedIndex)\n } catch (err) {\n // NOTE: An invalid rule here means it's not supported by the browser or obviously malformed\n return false\n }\n\n return true\n}\n\n// Counts up the number of rules inside the array until a specific component entry is found\n// This is used to determine the necessary insertRule index\nconst sizeUpToComponentIndex = (\n componentSizes: Array<number>,\n componentIndex: number\n) => {\n let cssRulesSize = 0\n for (let i = 0; i <= componentIndex; i += 1) {\n cssRulesSize += componentSizes[i]\n }\n\n return cssRulesSize\n}\n\nclass BaseBrowserTag {\n components: { [string]: Object }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n}\n\nlet BrowserTag\nif (!DISABLE_SPEEDY) {\n BrowserTag = class SpeedyBrowserTag extends BaseBrowserTag implements Tag {\n // Store component ruleSizes in an array per component (in order)\n componentSizes: Array<number>\n components: { [string]: Object }\n\n isLocal: boolean\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: ?string\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.componentSizes = []\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // workaround for an IE/Edge bug: https://twitter.com/probablyup/status/958138927981977600\n newEl.appendChild(document.createTextNode(''))\n\n // $FlowFixMe\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n this.ready = true\n\n // Retrieve the sheet for the new style tag\n const sheet = sheetForTag(newEl)\n\n Object.keys(this.components).forEach(componentId => {\n const comp = this.components[componentId]\n const { cssFromDOM } = comp\n const rules = stringifyRules([cssFromDOM])\n const rulesSize = rules.length\n\n let injectedRules = 0\n for (let j = 0; j < rulesSize; j += 1) {\n if (safeInsertRule(sheet, rules[j], sheet.cssRules.length)) {\n injectedRules += 1\n }\n }\n\n comp.componentIndex = this.componentSizes.length\n comp.css = rules.join(' ')\n this.componentSizes.push(injectedRules)\n })\n }\n\n isSealed() {\n return this.size >= SPEEDY_COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n this.components[componentId] = {\n componentIndex: this.componentSizes.length,\n css: '',\n }\n\n this.componentSizes.push(0)\n this.size += 1\n }\n\n inject(componentId: string, cssRules: Array<string>, name: ?string) {\n if (!this.ready) this.replaceElement()\n\n const comp = this.components[componentId]\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n const cssRulesSize = cssRules.length\n const sheet = sheetForTag(this.el)\n const { componentIndex } = comp\n\n // Determine start index for injection\n const insertIndex = sizeUpToComponentIndex(\n this.componentSizes,\n componentIndex\n )\n\n // Inject each rule shifting index forward for each one (in-order injection)\n let injectedRules = 0\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = cssRules[i]\n if (safeInsertRule(sheet, cssRule, insertIndex + injectedRules)) {\n comp.css += ` ${cssRule}`\n injectedRules += 1\n }\n }\n\n // Update number of rules for component\n this.componentSizes[componentIndex] += injectedRules\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toRawCSS() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n\n toHTML() {\n return '' // NOTE: Unsupported in production mode (SpeedyBrowserTag)\n }\n }\n} else {\n BrowserTag = class TextNodeBrowserTag extends BaseBrowserTag implements Tag {\n isLocal: boolean\n components: { [string]: Object }\n size: number\n el: HTMLStyleElement\n ready: boolean\n\n constructor(\n el: HTMLStyleElement,\n isLocal: boolean,\n existingSource: string = ''\n ) {\n super()\n\n const nonce = getNonce()\n if (nonce !== null) {\n el.setAttribute('nonce', nonce)\n }\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n this.size = extractedComps.length\n this.components = extractedComps.reduce((acc, obj) => {\n acc[obj.componentId] = obj // eslint-disable-line no-param-reassign\n return acc\n }, {})\n }\n\n isSealed() {\n return this.size >= COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n if (\n process.env.NODE_ENV !== 'production' &&\n this.components[componentId]\n ) {\n throw new Error(`Trying to add Component '${componentId}' twice!`)\n }\n\n const comp = { componentId, textNode: document.createTextNode('') }\n this.el.appendChild(comp.textNode)\n this.size += 1\n this.components[componentId] = comp\n }\n\n inject(componentId: string, css: Array<string>, name: ?string) {\n if (!this.ready) this.replaceElement()\n const comp = this.components[componentId]\n\n if (process.env.NODE_ENV !== 'production' && !comp) {\n throw new Error(\n 'Must add a new component before you can inject css into it'\n )\n }\n\n if (comp.textNode.data === '') {\n comp.textNode.appendData(`\\n/* sc-component-id: ${componentId} */\\n`)\n }\n\n comp.textNode.appendData(css.join(' '))\n\n if (name !== undefined && name !== null) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n }\n\n toHTML() {\n return this.el.outerHTML\n }\n\n toReactElement() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"BrowserTag doesn't implement toReactElement!\"\n : ''\n )\n }\n\n clone() {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'BrowserTag cannot be cloned!'\n : ''\n )\n }\n\n /* Because we care about source order, before we can inject anything we need to\n * create a text node for each component and replace the existing CSS. */\n replaceElement() {\n this.ready = true\n // We have nothing to inject. Use the current el.\n if (this.size === 0) return\n\n // Build up our replacement style tag\n const newEl = this.el.cloneNode(false)\n newEl.appendChild(document.createTextNode('\\n'))\n\n Object.keys(this.components).forEach(key => {\n const comp = this.components[key]\n\n // eslint-disable-next-line no-param-reassign\n comp.textNode = document.createTextNode(comp.cssFromDOM)\n newEl.appendChild(comp.textNode)\n })\n\n if (!this.el.parentNode) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Trying to replace an element that wasn't mounted!\"\n : ''\n )\n }\n\n // The ol' switcheroo\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\n }\n }\n}\n\n/* Factory function to separate DOM operations from logical ones*/\nexport default {\n create() {\n const tags = []\n const names = {}\n\n /* Construct existing state from DOM */\n const nodes = document.querySelectorAll(`[${SC_ATTR}]`)\n const nodesLength = nodes.length\n\n for (let i = 0; i < nodesLength; i += 1) {\n // $FlowFixMe: We can trust that all elements in this query are style elements\n const el = (nodes[i]: HTMLStyleElement)\n const attr = el.getAttribute(SC_ATTR)\n\n if (attr) {\n attr\n .trim()\n .split(/\\s+/)\n .forEach(name => {\n names[name] = true\n })\n }\n\n tags.push(\n new BrowserTag(\n el,\n el.getAttribute(LOCAL_ATTR) === 'true',\n el.textContent\n )\n )\n }\n\n /* Factory for making more tags */\n const tagConstructor = (isLocal: boolean): Tag => {\n const el = document.createElement('style')\n el.type = 'text/css'\n el.setAttribute(SC_ATTR, '')\n el.setAttribute(LOCAL_ATTR, isLocal ? 'true' : 'false')\n if (!document.head) {\n throw new Error(\n process.env.NODE_ENV !== 'production' ? 'Missing document <head>' : ''\n )\n }\n document.head.appendChild(el)\n return new BrowserTag(el, isLocal)\n }\n\n return new StyleSheet(tagConstructor, tags, names)\n },\n}\n","// @flow\nimport React from 'react'\nimport BrowserStyleSheet from './BrowserStyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\nexport const SC_ATTR = 'data-styled-components'\nexport const LOCAL_ATTR = 'data-styled-components-is-local'\nexport const CONTEXT_KEY = '__styled-components-stylesheet__'\n\n/* eslint-disable flowtype/object-type-delimiter */\nexport interface Tag {\n isLocal: boolean;\n\n isSealed(): boolean;\n getComponentIds(): Array<string>;\n addComponent(componentId: string): void;\n inject(componentId: string, css: Array<string>, name: ?string): void;\n toHTML(): string;\n toReactElement(key: string): React.Element<*>;\n clone(): Tag;\n}\n/* eslint-enable flowtype/object-type-delimiter */\n\nlet instance = null\n// eslint-disable-next-line no-use-before-define\nexport const clones: Array<StyleSheet> = []\n\nconst IS_BROWSER = typeof document !== 'undefined'\n\nexport default class StyleSheet {\n tagConstructor: boolean => Tag\n tags: Array<Tag>\n names: { [string]: boolean }\n hashes: { [string]: string } = {}\n deferredInjections: { [string]: Array<string> } = {}\n componentTags: { [string]: Tag }\n isStreaming: boolean\n\n // helper for `ComponentStyle` to know when it cache static styles.\n // staticly styled-component can not safely cache styles on the server\n // without all `ComponentStyle` instances saving a reference to the\n // the styleSheet instance they last rendered with,\n // or listening to creation / reset events. otherwise you might create\n // a component with one stylesheet and render it another api response\n // with another, losing styles on from your server-side render.\n stylesCacheable = IS_BROWSER\n\n constructor(\n tagConstructor: boolean => Tag,\n tags: Array<Tag> = [],\n names: { [string]: boolean } = {}\n ) {\n this.tagConstructor = tagConstructor\n this.tags = tags\n this.names = names\n this.constructComponentTagMap()\n this.isStreaming = false\n }\n\n constructComponentTagMap() {\n this.componentTags = {}\n\n this.tags.forEach(tag => {\n tag.getComponentIds().forEach(componentId => {\n this.componentTags[componentId] = tag\n })\n })\n }\n\n /* Best level of caching—get the name from the hash straight away. */\n getName(hash: any) {\n return this.hashes[hash.toString()]\n }\n\n /* Second level of caching—if the name is already in the dom, don't\n * inject anything and record the hash for getName next time. */\n alreadyInjected(hash: any, name: string) {\n if (!this.names[name]) return false\n\n this.hashes[hash.toString()] = name\n return true\n }\n\n /* Third type of caching—don't inject components' componentId twice. */\n hasInjectedComponent(componentId: string) {\n return !!this.componentTags[componentId]\n }\n\n deferredInject(componentId: string, isLocal: boolean, css: Array<string>) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.deferredInject(componentId, isLocal, css)\n })\n }\n\n this.getOrCreateTag(componentId, isLocal)\n this.deferredInjections[componentId] = css\n }\n\n inject(\n componentId: string,\n isLocal: boolean,\n css: Array<string>,\n hash: ?any,\n name: ?string\n ) {\n if (this === instance) {\n clones.forEach(clone => {\n clone.inject(componentId, isLocal, css)\n })\n }\n\n const tag = this.getOrCreateTag(componentId, isLocal)\n\n const deferredInjection = this.deferredInjections[componentId]\n if (deferredInjection) {\n tag.inject(componentId, deferredInjection)\n delete this.deferredInjections[componentId]\n }\n\n tag.inject(componentId, css, name)\n\n if (hash && name) {\n this.hashes[hash.toString()] = name\n }\n }\n\n toHTML() {\n return this.tags.map(tag => tag.toHTML()).join('')\n }\n\n toReactElements() {\n return this.tags.map((tag, i) => tag.toReactElement(`sc-${i}`))\n }\n\n getOrCreateTag(componentId: string, isLocal: boolean) {\n const existingTag = this.componentTags[componentId]\n\n /**\n * in a streaming context, once a tag is sealed it can never be added to again\n * or those styles will never make it to the client\n */\n if (\n existingTag && this.isStreaming ? !existingTag.isSealed() : existingTag\n ) {\n return existingTag\n }\n\n const lastTag = this.tags[this.tags.length - 1]\n const componentTag =\n !lastTag || lastTag.isSealed() || lastTag.isLocal !== isLocal\n ? this.createNewTag(isLocal)\n : lastTag\n this.componentTags[componentId] = componentTag\n componentTag.addComponent(componentId)\n return componentTag\n }\n\n createNewTag(isLocal: boolean) {\n const newTag = this.tagConstructor(isLocal)\n this.tags.push(newTag)\n return newTag\n }\n\n static get instance() {\n return instance || (instance = StyleSheet.create())\n }\n\n static reset(isServer: ?boolean) {\n instance = StyleSheet.create(isServer)\n }\n\n /* We can make isServer totally implicit once Jest 20 drops and we\n * can change environment on a per-test basis. */\n static create(isServer: ?boolean = !IS_BROWSER) {\n return (isServer ? ServerStyleSheet : BrowserStyleSheet).create()\n }\n\n static clone(oldSheet: StyleSheet) {\n const newSheet = new StyleSheet(\n oldSheet.tagConstructor,\n oldSheet.tags.map(tag => tag.clone()),\n { ...oldSheet.names }\n )\n\n newSheet.hashes = { ...oldSheet.hashes }\n newSheet.deferredInjections = { ...oldSheet.deferredInjections }\n clones.push(newSheet)\n\n return newSheet\n }\n}\n","// @flow\n/* eslint-disable no-underscore-dangle */\nimport React from 'react'\nimport stream from 'stream'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR, clones } from './StyleSheet'\nimport StyleSheetManager from './StyleSheetManager'\nimport getNonce from '../utils/nonce'\n\ndeclare var __SERVER__: boolean\n\nclass ServerTag implements Tag {\n emitted: boolean\n isLocal: boolean\n isProduction: boolean\n components: { [string]: Object }\n size: number\n names: Array<string>\n\n constructor(isLocal: boolean) {\n this.emitted = false\n this.isLocal = isLocal\n this.isProduction = process.env.NODE_ENV === 'production'\n this.components = {}\n this.size = 0\n this.names = []\n }\n\n isSealed() {\n return this.emitted\n }\n\n getComponentIds() {\n return Object.keys(this.components)\n }\n\n addComponent(componentId: string) {\n if (this.components[componentId]) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? `Trying to add Component '${componentId}' twice!`\n : ''\n )\n }\n this.components[componentId] = { componentId, css: '' }\n this.size += 1\n }\n\n concatenateCSS() {\n return Object.keys(this.components).reduce(\n (styles, k) => styles + this.components[k].css,\n ''\n )\n }\n\n inject(componentId: string, css: Array<string>, name: ?string) {\n const comp = this.components[componentId]\n\n if (!comp) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'Must add a new component before you can inject css into it'\n : ''\n )\n }\n\n if (comp.css === '') {\n comp.css = `/* sc-component-id: ${componentId} */\\n`\n }\n\n const cssRulesSize = css.length\n for (let i = 0; i < cssRulesSize; i += 1) {\n const cssRule = css[i]\n comp.css += `${cssRule}\\n`.replace(/\\n*$/, '\\n')\n }\n\n if (name) this.names.push(name)\n }\n\n toHTML() {\n const attrs: Array<string> = [\n 'type=\"text/css\"',\n `${SC_ATTR}=\"${this.names.join(' ')}\"`,\n `${LOCAL_ATTR}=\"${this.isLocal ? 'true' : 'false'}\"`,\n ]\n\n const nonce = getNonce()\n if (nonce) {\n attrs.push(`nonce=\"${nonce}\"`)\n }\n\n this.emitted = true\n return `<style ${attrs.join(' ')}>${this.concatenateCSS()}</style>`\n }\n\n toReactElement(key: string) {\n const attrs: Object = {\n [SC_ATTR]: this.names.join(' '),\n [LOCAL_ATTR]: this.isLocal.toString(),\n }\n\n const nonce = getNonce()\n if (nonce) {\n attrs.nonce = nonce\n }\n\n this.emitted = true\n\n return (\n <style\n key={key}\n type=\"text/css\"\n {...attrs}\n dangerouslySetInnerHTML={{ __html: this.concatenateCSS() }}\n />\n )\n }\n\n clone() {\n const copy = new ServerTag(this.isLocal)\n copy.names = [].concat(this.names)\n copy.size = this.size\n copy.components = Object.keys(this.components).reduce((acc, key) => {\n acc[key] = { ...this.components[key] } // eslint-disable-line no-param-reassign\n return acc\n }, {})\n\n return copy\n }\n}\n\nexport default class ServerStyleSheet {\n closed: boolean\n instance: StyleSheet\n\n constructor() {\n this.instance = StyleSheet.clone(StyleSheet.instance)\n this.instance.isStreaming = false\n }\n\n collectStyles(children: any) {\n if (this.closed) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? \"Can't collect styles once you've called getStyleTags!\"\n : ''\n )\n }\n return (\n <StyleSheetManager sheet={this.instance}>{children}</StyleSheetManager>\n )\n }\n\n close() {\n clones.splice(clones.indexOf(this.instance), 1)\n this.closed = true\n }\n\n getStyleTags(): string {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toHTML()\n }\n\n getStyleElement() {\n if (!this.closed) {\n this.close()\n }\n\n return this.instance.toReactElements()\n }\n\n interleaveWithNodeStream(readableStream: stream.Readable) {\n if (__SERVER__) {\n const ourStream = new stream.Readable()\n\n // $FlowFixMe\n ourStream._read = () => {}\n\n this.instance.isStreaming = true\n\n readableStream.on('data', chunk => {\n ourStream.push(\n this.instance.tags.reduce((html, tag) => {\n if (!tag.isSealed()) {\n html += tag.toHTML() // eslint-disable-line no-param-reassign\n }\n\n return html\n }, '') + chunk\n )\n })\n\n readableStream.on('end', () => {\n ourStream.push(null)\n this.close()\n })\n\n readableStream.on('error', err => {\n ourStream.emit('error', err)\n this.close()\n })\n\n return ourStream\n } else {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? 'streaming only works in Node.js, please do not try to call this method in the browser'\n : ''\n )\n }\n }\n\n static create() {\n return new StyleSheet(isLocal => new ServerTag(isLocal))\n }\n}\n","// @flow\n/* globals React$Element */\nimport React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport isPlainObject from 'is-plain-object'\nimport createBroadcast from '../utils/create-broadcast'\nimport type { Broadcast } from '../utils/create-broadcast'\nimport once from '../utils/once'\n\n// NOTE: DO NOT CHANGE, changing this is a semver major change!\nexport const CHANNEL = '__styled-components__'\nexport const CHANNEL_NEXT = `${CHANNEL}next__`\n\nexport const CONTEXT_CHANNEL_SHAPE = PropTypes.shape({\n getTheme: PropTypes.func,\n subscribe: PropTypes.func,\n unsubscribe: PropTypes.func,\n})\n\nexport type Theme = { [key: string]: mixed }\ntype ThemeProviderProps = {|\n children?: React$Element<any>,\n theme: Theme | ((outerTheme: Theme) => void),\n|}\n\nlet warnChannelDeprecated\nif (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated = once(() => {\n // eslint-disable-next-line no-console\n console.error(\n `Warning: Usage of \\`context.${CHANNEL}\\` as a function is deprecated. It will be replaced with the object on \\`.context.${CHANNEL_NEXT}\\` in a future version.`\n )\n })\n}\n\nconst isFunction = test => typeof test === 'function'\n\n/**\n * Provide a theme to an entire react component tree via context and event listeners (have to do\n * both context and event emitter as pure components block context updates)\n */\nclass ThemeProvider extends Component {\n getTheme: (theme?: Theme | ((outerTheme: Theme) => void)) => Theme\n outerTheme: Theme\n unsubscribeToOuterId: string\n props: ThemeProviderProps\n broadcast: Broadcast\n unsubscribeToOuterId: number = -1\n\n constructor() {\n super()\n this.getTheme = this.getTheme.bind(this)\n }\n\n componentWillMount() {\n // If there is a ThemeProvider wrapper anywhere around this theme provider, merge this theme\n // with the outer theme\n const outerContext = this.context[CHANNEL_NEXT]\n if (outerContext !== undefined) {\n this.unsubscribeToOuterId = outerContext.subscribe(theme => {\n this.outerTheme = theme\n\n if (this.broadcast !== undefined) {\n this.publish(this.props.theme)\n }\n })\n }\n\n this.broadcast = createBroadcast(this.getTheme())\n }\n\n getChildContext() {\n return {\n ...this.context,\n [CHANNEL_NEXT]: {\n getTheme: this.getTheme,\n subscribe: this.broadcast.subscribe,\n unsubscribe: this.broadcast.unsubscribe,\n },\n [CHANNEL]: subscriber => {\n if (process.env.NODE_ENV !== 'production') {\n warnChannelDeprecated()\n }\n\n // Patch the old `subscribe` provide via `CHANNEL` for older clients.\n const unsubscribeId = this.broadcast.subscribe(subscriber)\n return () => this.broadcast.unsubscribe(unsubscribeId)\n },\n }\n }\n\n componentWillReceiveProps(nextProps: ThemeProviderProps) {\n if (this.props.theme !== nextProps.theme) {\n this.publish(nextProps.theme)\n }\n }\n\n componentWillUnmount() {\n if (this.unsubscribeToOuterId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeToOuterId)\n }\n }\n\n // Get the theme from the props, supporting both (outerTheme) => {} as well as object notation\n getTheme(passedTheme: (outerTheme: Theme) => void | Theme) {\n const theme = passedTheme || this.props.theme\n if (isFunction(theme)) {\n const mergedTheme = theme(this.outerTheme)\n if (\n process.env.NODE_ENV !== 'production' &&\n !isPlainObject(mergedTheme)\n ) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please return an object from your theme function, i.e. theme={() => ({})}!'\n : ''\n )\n }\n return mergedTheme\n }\n if (!isPlainObject(theme)) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? '[ThemeProvider] Please make your theme prop a plain object'\n : ''\n )\n }\n return { ...this.outerTheme, ...(theme: Object) }\n }\n\n publish(theme: Theme | ((outerTheme: Theme) => void)) {\n this.broadcast.publish(this.getTheme(theme))\n }\n\n render() {\n if (!this.props.children) {\n return null\n }\n return React.Children.only(this.props.children)\n }\n}\n\nThemeProvider.childContextTypes = {\n [CHANNEL]: PropTypes.func, // legacy\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\nThemeProvider.contextTypes = {\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n}\n\nexport default ThemeProvider\n","// @flow\n\nimport { Component, createElement } from 'react'\nimport PropTypes from 'prop-types'\n\nimport type { Theme } from './ThemeProvider'\nimport createWarnTooManyClasses from '../utils/createWarnTooManyClasses'\n\nimport validAttr from '../utils/validAttr'\nimport isTag from '../utils/isTag'\nimport isStyledComponent from '../utils/isStyledComponent'\nimport getComponentName from '../utils/getComponentName'\nimport determineTheme from '../utils/determineTheme'\nimport escape from '../utils/escape'\nimport type { RuleSet, Target } from '../types'\n\nimport { CHANNEL, CHANNEL_NEXT, CONTEXT_CHANNEL_SHAPE } from './ThemeProvider'\nimport StyleSheet, { CONTEXT_KEY } from './StyleSheet'\nimport ServerStyleSheet from './ServerStyleSheet'\n\n// HACK for generating all static styles without needing to allocate\n// an empty execution context every single time...\nconst STATIC_EXECUTION_CONTEXT = {}\n\nexport default (ComponentStyle: Function, constructWithOptions: Function) => {\n const identifiers = {}\n\n /* We depend on components having unique IDs */\n const generateId = (_displayName: string, parentComponentId: string) => {\n const displayName =\n typeof _displayName !== 'string' ? 'sc' : escape(_displayName)\n\n let componentId\n\n /**\n * only fall back to hashing the component injection order if\n * a proper displayName isn't provided by the babel plugin\n */\n if (!_displayName) {\n const nr = (identifiers[displayName] || 0) + 1\n identifiers[displayName] = nr\n\n componentId = `${displayName}-${ComponentStyle.generateName(\n displayName + nr\n )}`\n } else {\n componentId = `${displayName}-${ComponentStyle.generateName(displayName)}`\n }\n\n return parentComponentId !== undefined\n ? `${parentComponentId}-${componentId}`\n : componentId\n }\n\n class BaseStyledComponent extends Component {\n static target: Target\n static styledComponentId: string\n static attrs: Object\n static componentStyle: Object\n static warnTooManyClasses: Function\n\n attrs = {}\n state = {\n theme: null,\n generatedClassName: '',\n }\n unsubscribeId: number = -1\n\n unsubscribeFromContext() {\n if (this.unsubscribeId !== -1) {\n this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeId)\n }\n }\n\n buildExecutionContext(theme: any, props: any) {\n const { attrs } = this.constructor\n const context = { ...props, theme }\n if (attrs === undefined) {\n return context\n }\n\n this.attrs = Object.keys(attrs).reduce((acc, key) => {\n const attr = attrs[key]\n // eslint-disable-next-line no-param-reassign\n acc[key] = typeof attr === 'function' ? attr(context) : attr\n return acc\n }, {})\n\n return { ...context, ...this.attrs }\n }\n\n generateAndInjectStyles(theme: any, props: any) {\n const { attrs, componentStyle, warnTooManyClasses } = this.constructor\n const styleSheet = this.context[CONTEXT_KEY] || StyleSheet.instance\n\n // staticaly styled-components don't need to build an execution context object,\n // and shouldn't be increasing the number of class names\n if (componentStyle.isStatic && attrs === undefined) {\n return componentStyle.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n styleSheet\n )\n } else {\n const executionContext = this.buildExecutionContext(theme, props)\n const className = componentStyle.generateAndInjectStyles(\n executionContext,\n styleSheet\n )\n\n if (\n process.env.NODE_ENV !== 'production' &&\n warnTooManyClasses !== undefined\n ) {\n warnTooManyClasses(className)\n }\n\n return className\n }\n }\n\n componentWillMount() {\n const { componentStyle } = this.constructor\n const styledContext = this.context[CHANNEL_NEXT]\n\n // If this is a staticaly-styled component, we don't need to the theme\n // to generate or build styles.\n if (componentStyle.isStatic) {\n const generatedClassName = this.generateAndInjectStyles(\n STATIC_EXECUTION_CONTEXT,\n this.props\n )\n this.setState({ generatedClassName })\n // If there is a theme in the context, subscribe to the event emitter. This\n // is necessary due to pure components blocking context updates, this circumvents\n // that by updating when an event is emitted\n } else if (styledContext !== undefined) {\n const { subscribe } = styledContext\n this.unsubscribeId = subscribe(nextTheme => {\n // This will be called once immediately\n const theme = determineTheme(\n this.props,\n nextTheme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n\n this.setState({ theme, generatedClassName })\n })\n } else {\n // eslint-disable-next-line react/prop-types\n const theme = this.props.theme || {}\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n this.props\n )\n this.setState({ theme, generatedClassName })\n }\n }\n\n componentWillReceiveProps(nextProps: {\n theme?: Theme,\n [key: string]: any,\n }) {\n // If this is a staticaly-styled component, we don't need to listen to\n // props changes to update styles\n const { componentStyle } = this.constructor\n if (componentStyle.isStatic) {\n return\n }\n\n this.setState(oldState => {\n const theme = determineTheme(\n nextProps,\n oldState.theme,\n this.constructor.defaultProps\n )\n const generatedClassName = this.generateAndInjectStyles(\n theme,\n nextProps\n )\n\n return { theme, generatedClassName }\n })\n }\n\n componentWillUnmount() {\n this.unsubscribeFromContext()\n }\n\n render() {\n // eslint-disable-next-line react/prop-types\n const { innerRef } = this.props\n const { generatedClassName } = this.state\n const { styledComponentId, target } = this.constructor\n\n const isTargetTag = isTag(target)\n\n const className = [\n // eslint-disable-next-line react/prop-types\n this.props.className,\n styledComponentId,\n this.attrs.className,\n generatedClassName,\n ]\n .filter(Boolean)\n .join(' ')\n\n const baseProps = {\n ...this.attrs,\n className,\n }\n\n if (isStyledComponent(target)) {\n baseProps.innerRef = innerRef\n } else {\n baseProps.ref = innerRef\n }\n\n const propsForElement = Object.keys(this.props).reduce(\n (acc, propName) => {\n // Don't pass through non HTML tags through to HTML elements\n // always omit innerRef\n if (\n propName !== 'innerRef' &&\n propName !== 'className' &&\n (!isTargetTag || validAttr(propName))\n ) {\n // eslint-disable-next-line no-param-reassign\n acc[propName] = this.props[propName]\n }\n\n return acc\n },\n baseProps\n )\n\n return createElement(target, propsForElement)\n }\n }\n\n const createStyledComponent = (\n target: Target,\n options: Object,\n rules: RuleSet\n ) => {\n const {\n displayName = isTag(target)\n ? `styled.${target}`\n : `Styled(${getComponentName(target)})`,\n componentId = generateId(options.displayName, options.parentComponentId),\n ParentComponent = BaseStyledComponent,\n rules: extendingRules,\n attrs,\n } = options\n\n const styledComponentId =\n options.displayName && options.componentId\n ? `${escape(options.displayName)}-${options.componentId}`\n : componentId\n\n const componentStyle = new ComponentStyle(\n extendingRules === undefined ? rules : extendingRules.concat(rules),\n attrs,\n styledComponentId\n )\n\n class StyledComponent extends ParentComponent {\n static contextTypes = {\n [CHANNEL]: PropTypes.func,\n [CHANNEL_NEXT]: CONTEXT_CHANNEL_SHAPE,\n [CONTEXT_KEY]: PropTypes.oneOfType([\n PropTypes.instanceOf(StyleSheet),\n PropTypes.instanceOf(ServerStyleSheet),\n ]),\n }\n\n static displayName = displayName\n static styledComponentId = styledComponentId\n static attrs = attrs\n static componentStyle = componentStyle\n static target = target\n\n static withComponent(tag) {\n const { componentId: previousComponentId, ...optionsToCopy } = options\n\n const newComponentId =\n previousComponentId &&\n `${previousComponentId}-${\n isTag(tag) ? tag : escape(getComponentName(tag))\n }`\n\n const newOptions = {\n ...optionsToCopy,\n componentId: newComponentId,\n ParentComponent: StyledComponent,\n }\n\n return createStyledComponent(tag, newOptions, rules)\n }\n\n static get extend() {\n const {\n rules: rulesFromOptions,\n componentId: parentComponentId,\n ...optionsToCopy\n } = options\n\n const newRules =\n rulesFromOptions === undefined\n ? rules\n : rulesFromOptions.concat(rules)\n\n const newOptions = {\n ...optionsToCopy,\n rules: newRules,\n parentComponentId,\n ParentComponent: StyledComponent,\n }\n\n return constructWithOptions(createStyledComponent, target, newOptions)\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n StyledComponent.warnTooManyClasses = createWarnTooManyClasses(displayName)\n }\n\n return StyledComponent\n }\n\n return createStyledComponent\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\n\nimport type { RuleSet, NameGenerator, Flattener, Stringifier } from '../types'\nimport StyleSheet from './StyleSheet'\nimport isStyledComponent from '../utils/isStyledComponent'\n\nconst isStaticRules = (rules: RuleSet, attrs?: Object): boolean => {\n for (let i = 0; i < rules.length; i += 1) {\n const rule = rules[i]\n\n // recursive case\n if (Array.isArray(rule) && !isStaticRules(rule)) {\n return false\n } else if (typeof rule === 'function' && !isStyledComponent(rule)) {\n // functions are allowed to be static if they're just being\n // used to get the classname of a nested styled copmonent\n return false\n }\n }\n\n if (attrs !== undefined) {\n // eslint-disable-next-line guard-for-in, no-restricted-syntax\n for (const key in attrs) {\n const value = attrs[key]\n if (typeof value === 'function') {\n return false\n }\n }\n }\n\n return true\n}\n\nconst isHRMEnabled =\n typeof module !== 'undefined' &&\n module.hot &&\n process.env.NODE_ENV !== 'production'\n\n/*\n ComponentStyle is all the CSS-specific stuff, not\n the React-specific stuff.\n */\nexport default (\n nameGenerator: NameGenerator,\n flatten: Flattener,\n stringifyRules: Stringifier\n) => {\n class ComponentStyle {\n rules: RuleSet\n componentId: string\n isStatic: boolean\n lastClassName: ?string\n\n constructor(rules: RuleSet, attrs?: Object, componentId: string) {\n this.rules = rules\n this.isStatic = !isHRMEnabled && isStaticRules(rules, attrs)\n this.componentId = componentId\n if (!StyleSheet.instance.hasInjectedComponent(this.componentId)) {\n const placeholder =\n process.env.NODE_ENV !== 'production' ? `.${componentId} {}` : ''\n StyleSheet.instance.deferredInject(componentId, true, [placeholder])\n }\n }\n\n /*\n * Flattens a rule set into valid CSS\n * Hashes it, wraps the whole chunk in a .hash1234 {}\n * Returns the hash to be injected on render()\n * */\n generateAndInjectStyles(executionContext: Object, styleSheet: StyleSheet) {\n const { isStatic, lastClassName } = this\n if (isStatic && lastClassName !== undefined) {\n return lastClassName\n }\n\n const flatCSS = flatten(this.rules, executionContext)\n const hash = hashStr(this.componentId + flatCSS.join(''))\n\n const { stylesCacheable } = styleSheet\n const existingName = styleSheet.getName(hash)\n\n if (existingName !== undefined) {\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n return existingName\n }\n\n const name = nameGenerator(hash)\n if (stylesCacheable) {\n this.lastClassName = existingName\n }\n if (styleSheet.alreadyInjected(hash, name)) {\n return name\n }\n\n const css = stringifyRules(flatCSS, `.${name}`)\n // NOTE: this can only be set when we inject the class-name.\n // For some reason, presumably due to how css is stringifyRules behaves in\n // differently between client and server, styles break.\n styleSheet.inject(this.componentId, true, css, hash, name)\n return name\n }\n\n static generateName(str: string) {\n return nameGenerator(hashStr(str))\n }\n }\n\n return ComponentStyle\n}\n","// @flow\nimport type { Target } from '../types'\nimport domElements from '../utils/domElements'\n\nexport default (styledComponent: Function, constructWithOptions: Function) => {\n const styled = (tag: Target) => constructWithOptions(styledComponent, tag)\n\n // Shorthands for all valid HTML Elements\n domElements.forEach(domElement => {\n styled[domElement] = styled(domElement)\n })\n\n return styled\n}\n","// @flow\nimport hashStr from '../vendor/glamor/hash'\nimport type { Interpolation, NameGenerator, Stringifier } from '../types'\nimport StyleSheet from '../models/StyleSheet'\n\nconst replaceWhitespace = (str: string): string => str.replace(/\\s|\\\\n/g, '')\n\nexport default (\n nameGenerator: NameGenerator,\n stringifyRules: Stringifier,\n css: Function\n) => (\n strings: Array<string>,\n ...interpolations: Array<Interpolation>\n): string => {\n const rules = css(strings, ...interpolations)\n const hash = hashStr(replaceWhitespace(JSON.stringify(rules)))\n\n const existingName = StyleSheet.instance.getName(hash)\n if (existingName) return existingName\n\n const name = nameGenerator(hash)\n if (StyleSheet.instance.alreadyInjected(hash, name)) return name\n\n const generatedCSS = stringifyRules(rules, name, '@keyframes')\n StyleSheet.instance.inject(\n `sc-keyframes-${name}`,\n true,\n generatedCSS,\n hash,\n name\n )\n return name\n}\n"],"names":["deferredInjections","isStreaming","nonce","componentWillMount","state","unsubscribeId","attrs","reduce","length","i"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,iGAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SCMEA;;;;;;;SAoBOC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBC6CWC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5EpB,kCAAA;AACA,yCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BA0BEC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+JCSEC;;;eAIAC;;;;;;;;;;;;;;;;;+BAe2BC,OAAYC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BCnEfC,QAA0BC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA0ClD,OAAA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChDJ;;;;;;;;;;;;;;;;;;;SCSK,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|