diff --git a/src/stylesheet-registry.js b/src/stylesheet-registry.js index 7c8dc969..63cf0fd2 100644 --- a/src/stylesheet-registry.js +++ b/src/stylesheet-registry.js @@ -1,6 +1,7 @@ import hashString from 'string-hash' import DefaultStyleSheet from './lib/stylesheet' +const sanitize = rule => rule.replace(/\/style/g, '\\/style') export default class StyleSheetRegistry { constructor({ styleSheet = null, @@ -13,7 +14,13 @@ export default class StyleSheetRegistry { name: 'styled-jsx', optimizeForSpeed }) + this._sheet.inject() + if (styleSheet && typeof optimizeForSpeed === 'boolean') { + this._sheet.setOptimizeForSpeed(optimizeForSpeed) + this._optimizeForSpeed = this._sheet.isOptimizeForSpeed() + } + this._isBrowser = isBrowser this._fromServer = undefined @@ -146,6 +153,12 @@ export default class StyleSheetRegistry { ) { const cache = {} return function(id, css) { + // Sanitize SSR-ed CSS. + // Client side code doesn't need to be sanitized since we use + // document.createTextNode (dev) and the CSSOM api sheet.insertRule (prod). + if (!this._isBrowser) { + css = sanitize(css) + } const idcss = id + css if (!cache[idcss]) { cache[idcss] = css.replace(selectoPlaceholderRegexp, id) diff --git a/test/stylesheet-registry.js b/test/stylesheet-registry.js index 1de2c3be..874ece75 100644 --- a/test/stylesheet-registry.js +++ b/test/stylesheet-registry.js @@ -5,7 +5,7 @@ import test from 'ava' import StyleSheetRegistry from '../src/stylesheet-registry' import makeSheet, { invalidRules } from './stylesheet' -function makeRegistry(options) { +function makeRegistry(options = { optimizeForSpeed: true, isBrowser: true }) { const registry = new StyleSheetRegistry({ styleSheet: makeSheet(options), ...options @@ -85,6 +85,25 @@ test('add - filters out invalid rules (index `-1`)', t => { ]) }) +test('add - sanitizes dynamic CSS on the server', t => { + const registry = makeRegistry({ optimizeForSpeed: false, isBrowser: false }) + + registry.add({ + styleId: '123', + css: [ + 'div.__jsx-style-dynamic-selector { color: red }' + ], + dynamic: ['red'] + }) + + t.deepEqual(registry.cssRules(), [ + [ + 'jsx-1871671996', + 'div.jsx-1871671996 { color: red<\\/style> }' + ] + ]) +}) + // registry.remove test('remove', t => { @@ -196,7 +215,9 @@ test('createComputeId', t => { // createComputeSelector test('createComputeSelector', t => { - const computeSelector = utilRegistry.createComputeSelector() + const computeSelector = utilRegistry + .createComputeSelector() + .bind(utilRegistry) t.is( computeSelector(