diff --git a/src/babel.js b/src/babel.js index ebf021c..213a7cd 100644 --- a/src/babel.js +++ b/src/babel.js @@ -11,6 +11,7 @@ const STYLE_ATTRIBUTE = 'jsx' const GLOBAL_ATTRIBUTE = 'global' const MARKUP_ATTRIBUTE = 'data-jsx' const STYLE_COMPONENT = '_JSXStyle' +const STYLE_COMPONENT_ID = 'styleId' const STYLE_COMPONENT_CSS = 'css' export default function ({types: t}) { @@ -31,14 +32,20 @@ export default function ({types: t}) { expr.value ) - const makeStyledJsxTag = transformedCss => ( + const makeStyledJsxTag = (id, transformedCss) => ( t.JSXElement( t.JSXOpeningElement( t.JSXIdentifier(STYLE_COMPONENT), - [t.JSXAttribute( - t.JSXIdentifier(STYLE_COMPONENT_CSS), - t.JSXExpressionContainer(t.stringLiteral(transformedCss)) - )], + [ + t.JSXAttribute( + t.JSXIdentifier(STYLE_COMPONENT_ID), + t.JSXExpressionContainer(t.numericLiteral(id)) + ), + t.JSXAttribute( + t.JSXIdentifier(STYLE_COMPONENT_CSS), + t.JSXExpressionContainer(t.stringLiteral(transformedCss)) + ) + ], true ), null, @@ -65,7 +72,8 @@ export default function ({types: t}) { const el = path.node - if (el.name && el.name.name !== 'style') { + if (el.name && + (el.name.name !== 'style' && el.name.name !== STYLE_COMPONENT)) { for (const attr of el.attributes) { if (attr.name === MARKUP_ATTRIBUTE) { // avoid double attributes @@ -131,14 +139,16 @@ export default function ({types: t}) { } const styleText = getExpressionText(expression) + const styleId = hash(styleText) state.styles.push([ + styleId, styleText, expression.loc ]) } - state.jsxId = hash(state.styles.map(s => s[0]).join('')) + state.jsxId = hash(state.styles.map(s => s[1]).join('')) state.hasJSXStyle = true state.file.hasJSXStyle = true // next visit will be: JSXOpeningElement @@ -159,14 +169,14 @@ export default function ({types: t}) { } // we replace styles with the function call - const [css, loc] = state.styles.shift() + const [id, css, loc] = state.styles.shift() const isGlobal = el.attributes.some(attr => ( attr.name.name === GLOBAL_ATTRIBUTE )) if (isGlobal) { - path.replaceWith(makeStyledJsxTag(css)) + path.replaceWith(makeStyledJsxTag(id, css)) return } @@ -191,7 +201,7 @@ export default function ({types: t}) { transformedCss = transform(state.jsxId, css) } - path.replaceWith(makeStyledJsxTag(transformedCss)) + path.replaceWith(makeStyledJsxTag(id, transformedCss)) } }, Program: { diff --git a/src/render.js b/src/render.js index 3e94304..a4f9581 100644 --- a/src/render.js +++ b/src/render.js @@ -9,14 +9,14 @@ export default typeof window === 'undefined' ? renderOnServer : renderOnClient function renderOnServer(components) { for (const {props} of components) { - memory[props['data-jsx']] = props.css + memory[props.styleId] = props.css } } function renderOnClient(components) { const styles = {} for (const c of components) { - styles[c.props['data-jsx']] = c + styles[c.props.styleId] = c } patch(diff(prevStyles, styles)) diff --git a/test/fixtures/class.out.js b/test/fixtures/class.out.js index 6a6817b..0b18361 100644 --- a/test/fixtures/class.out.js +++ b/test/fixtures/class.out.js @@ -4,8 +4,8 @@ export default class { render() { return

test

- <_JSXStyle css={"p[data-jsx=\"1891769468\"] {color: red;}"} data-jsx={1891769468} /> + <_JSXStyle styleId={1891769468} css={"p[data-jsx=\"1891769468\"] {color: red;}"} />
; } -} \ No newline at end of file +} diff --git a/test/fixtures/global.out.js b/test/fixtures/global.out.js index 132c917..095bca0 100644 --- a/test/fixtures/global.out.js +++ b/test/fixtures/global.out.js @@ -1,4 +1,4 @@ import _JSXStyle from "styled-jsx/style";
- <_JSXStyle css={"\n body {\n color: red\n }\n "} data-jsx={3367785191} /> -
; \ No newline at end of file + <_JSXStyle styleId={3367785191} css={"\n body {\n color: red\n }\n "} /> +; diff --git a/test/fixtures/mixed-global-scoped.out.js b/test/fixtures/mixed-global-scoped.out.js index f40234a..314d636 100644 --- a/test/fixtures/mixed-global-scoped.out.js +++ b/test/fixtures/mixed-global-scoped.out.js @@ -1,6 +1,6 @@ import _JSXStyle from 'styled-jsx/style'; export default (() =>

test

- <_JSXStyle css={"body { background: red }"} data-jsx={793889750} /> - <_JSXStyle css={"p[data-jsx=\"793889750\"] {color: red }"} data-jsx={793889750} /> -
); \ No newline at end of file + <_JSXStyle styleId={3149549172} css={"body { background: red }"} /> + <_JSXStyle styleId={188072295} css={"p[data-jsx=\"793889750\"] {color: red }"} /> + ); diff --git a/test/fixtures/source-maps.out.js b/test/fixtures/source-maps.out.js index 3f52e8c..3f0f7e4 100644 --- a/test/fixtures/source-maps.out.js +++ b/test/fixtures/source-maps.out.js @@ -2,5 +2,5 @@ import _JSXStyle from 'styled-jsx/style'; export default (() =>

test

woot

- <_JSXStyle css={"p[data-jsx=\"188072295\"] {color: red }\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNvdXJjZS1tYXBzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlnQixBQUFFLHlCQUFhIiwiZmlsZSI6InNvdXJjZS1tYXBzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgKCkgPT4gKFxuICA8ZGl2PlxuICAgIDxwPnRlc3Q8L3A+XG4gICAgPHA+d29vdDwvcD5cbiAgICA8c3R5bGUganN4PnsncCB7IGNvbG9yOiByZWQgfSd9PC9zdHlsZT5cbiAgPC9kaXY+XG4pXG4iXX0= */\n/*@ sourceURL=source-maps.js */"} data-jsx={188072295} /> -
); \ No newline at end of file + <_JSXStyle styleId={188072295} css={"p[data-jsx=\"188072295\"] {color: red }\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNvdXJjZS1tYXBzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlnQixBQUFFLHlCQUFhIiwiZmlsZSI6InNvdXJjZS1tYXBzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgKCkgPT4gKFxuICA8ZGl2PlxuICAgIDxwPnRlc3Q8L3A+XG4gICAgPHA+d29vdDwvcD5cbiAgICA8c3R5bGUganN4PnsncCB7IGNvbG9yOiByZWQgfSd9PC9zdHlsZT5cbiAgPC9kaXY+XG4pXG4iXX0= */\n/*@ sourceURL=source-maps.js */"} /> + ); diff --git a/test/fixtures/stateless.out.js b/test/fixtures/stateless.out.js index 0e9200e..5bad68d 100644 --- a/test/fixtures/stateless.out.js +++ b/test/fixtures/stateless.out.js @@ -3,5 +3,5 @@ export default (() =>

test

woot

woot

- <_JSXStyle css={"p[data-jsx=\"188072295\"] {color: red }"} data-jsx={188072295} /> -
); \ No newline at end of file + <_JSXStyle styleId={188072295} css={"p[data-jsx=\"188072295\"] {color: red }"} /> + ); diff --git a/test/fixtures/whitespace.out.js b/test/fixtures/whitespace.out.js index 0e9200e..5bad68d 100644 --- a/test/fixtures/whitespace.out.js +++ b/test/fixtures/whitespace.out.js @@ -3,5 +3,5 @@ export default (() =>

test

woot

woot

- <_JSXStyle css={"p[data-jsx=\"188072295\"] {color: red }"} data-jsx={188072295} /> -
); \ No newline at end of file + <_JSXStyle styleId={188072295} css={"p[data-jsx=\"188072295\"] {color: red }"} /> + );