{"version":3,"file":"styled-components.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 * \n *\n * Note: replace · with * in the above snippet.\n * */\nimport extractCompsFromCSS from '../utils/extractCompsFromCSS'\nimport getNonce from '../utils/nonce'\nimport type { Tag } from './StyleSheet'\nimport StyleSheet, { SC_ATTR, LOCAL_ATTR } from './StyleSheet'\n\nexport const COMPONENTS_PER_TAG = 40\n\nclass BrowserTag implements Tag {\n isLocal: boolean\n components: { [string]: Object }\n size: number\n el: HTMLElement\n ready: boolean\n\n constructor(el: HTMLElement, isLocal: boolean, existingSource: string = '') {\n this.el = el\n this.isLocal = isLocal\n this.ready = false\n\n const extractedComps = extractCompsFromCSS(existingSource)\n\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 isFull() {\n return this.size >= COMPONENTS_PER_TAG\n }\n\n addComponent(componentId: string) {\n if (!this.ready) this.replaceElement()\n if (process.env.NODE_ENV !== 'production' && this.components[componentId]) {\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\n this.size += 1\n this.components[componentId] = comp\n }\n\n inject(componentId: string, css: 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 if (comp.textNode.data === '') {\n comp.textNode.appendData(`\\n/* sc-component-id: ${componentId} */\\n`)\n }\n\n comp.textNode.appendData(css)\n if (name) {\n const existingNames = this.el.getAttribute(SC_ATTR)\n this.el.setAttribute(\n SC_ATTR,\n existingNames ? `${existingNames} ${name}` : name\n )\n }\n\n const nonce = getNonce()\n\n if (nonce) {\n this.el.setAttribute('nonce', nonce)\n }\n }\n\n toHTML() {\n return this.el.outerHTML\n }\n\n toReactElement() {\n throw new Error(\"BrowserTag doesn't implement toReactElement!\")\n }\n\n clone() {\n throw new Error('BrowserTag cannot be cloned!')\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()\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(\"Trying to replace an element that wasn't mounted!\")\n }\n\n // The ol' switcheroo\n this.el.parentNode.replaceChild(newEl, this.el)\n this.el = newEl\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 const el = nodes[i]\n\n tags.push(\n new BrowserTag(el, el.getAttribute(LOCAL_ATTR) === 'true', el.innerHTML)\n )\n\n const attr = el.getAttribute(SC_ATTR)\n if (attr) {\n attr\n .trim()\n .split(/\\s+/)\n .forEach(name => {\n names[name] = true\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) throw new Error('Missing document
')\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 components: { [string]: Object };\n\n isFull(): boolean;\n addComponent(componentId: string): void;\n inject(componentId: string, css: 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