From f4946d1e7774ea7e51916fe73246c3a3c67ce556 Mon Sep 17 00:00:00 2001 From: mitchellhamilton Date: Sun, 30 Jul 2017 14:21:18 +1000 Subject: [PATCH] Fix prefixed selectors in objects Closes #201 --- src/ast-object.js | 25 +++++-- test/__snapshots__/react.test.js.snap | 12 ++++ test/babel/__snapshots__/css.test.js.snap | 80 +++++++++++++++++++++++ test/babel/css.test.js | 40 ++++++++++++ 4 files changed, 152 insertions(+), 5 deletions(-) diff --git a/src/ast-object.js b/src/ast-object.js index 1fbedd9c5..24270c7cf 100644 --- a/src/ast-object.js +++ b/src/ast-object.js @@ -20,13 +20,28 @@ function prefixAst (args, t) { // nested objects if (t.isObjectExpression(property.value)) { const key = property.computed - ? property.key - : t.isStringLiteral(property.key) - ? t.stringLiteral(property.key.value) - : t.identifier(property.key.name) + ? property.key + : t.isStringLiteral(property.key) + ? t.stringLiteral(property.key.value) + : t.identifier(property.key.name) + + const prefixedPseudoSelectors = { + '::placeholder': ['::-webkit-input-placeholder', '::-moz-placeholder', ':-ms-input-placeholder'], + ':fullscreen': [':-webkit-full-screen', ':-moz-full-screen', ':-ms-fullscreen'] + } + + const prefixedValue = prefixAst(property.value, t) + + if (!property.computed) { + if (prefixedPseudoSelectors[key.value]) { + forEach(prefixedPseudoSelectors[key.value], (prefixedKey) => { + properties.push(t.objectProperty(t.stringLiteral(prefixedKey), prefixedValue, false)) + }) + } + } return properties.push( - t.objectProperty(key, prefixAst(property.value, t), property.computed) + t.objectProperty(key, prefixedValue, property.computed) ) // literal value or array of literal values diff --git a/test/__snapshots__/react.test.js.snap b/test/__snapshots__/react.test.js.snap index ccddacbf0..1957916c9 100644 --- a/test/__snapshots__/react.test.js.snap +++ b/test/__snapshots__/react.test.js.snap @@ -356,6 +356,18 @@ exports[`styled input placeholder 1`] = ` `; exports[`styled input placeholder object 1`] = ` +.glamor-1::-webkit-input-placeholder { + background-color: green; +} + +.glamor-1::-moz-placeholder { + background-color: green; +} + +.glamor-1:-ms-input-placeholder { + background-color: green; +} + .glamor-1::placeholder { background-color: green; } diff --git a/test/babel/__snapshots__/css.test.js.snap b/test/babel/__snapshots__/css.test.js.snap index 4eac4257b..038f4e44c 100644 --- a/test/babel/__snapshots__/css.test.js.snap +++ b/test/babel/__snapshots__/css.test.js.snap @@ -129,6 +129,86 @@ css({ });" `; +exports[`babel css inline ::placeholder 1`] = ` +" +const cls1 = css({ + '::-webkit-input-placeholder': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + }, + '::-moz-placeholder': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + }, + ':-ms-input-placeholder': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + }, + '::placeholder': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + } +}); +const cls2 = /*#__PURE__*/css([], [], function createEmotionStyledRules() { + return [{ + '::-webkit-input-placeholder': { + 'color': 'green', + 'display': '-webkit-box; display: flex' + }, + ':-ms-input-placeholder': { + 'color': 'green', + 'display': '-ms-flexbox; display: flex' + }, + '::placeholder': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + } + }]; +});" +`; + +exports[`babel css inline :fullscreen 1`] = ` +" +const cls1 = css({ + ':-webkit-full-screen': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + }, + ':-moz-full-screen': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + }, + ':-ms-fullscreen': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + }, + ':fullscreen': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + } +}); +const cls2 = /*#__PURE__*/css([], [], function createEmotionStyledRules() { + return [{ + ':-webkit-full-screen': { + 'color': 'green', + 'display': '-webkit-box; display: flex' + }, + ':-moz-full-screen': { + 'color': 'green', + 'display': 'flex' + }, + ':-ms-fullscreen': { + 'color': 'green', + 'display': '-ms-flexbox; display: flex' + }, + ':fullscreen': { + 'color': 'green', + 'display': '-webkit-box; display: -ms-flexbox; display: flex' + } + }]; +});" +`; + exports[`babel css inline array of objects 1`] = ` " const cls2 = css([{ diff --git a/test/babel/css.test.js b/test/babel/css.test.js index 1b343a6a6..abc83a4b9 100644 --- a/test/babel/css.test.js +++ b/test/babel/css.test.js @@ -85,6 +85,46 @@ describe('babel css', () => { expect(code).toMatchSnapshot() }) + test('::placeholder', () => { + const basic = ` + const cls1 = css({ + '::placeholder': { + color: 'green', + display: 'flex' + } + }) + const cls2 = css\` + ::placeholder { + color: green; + display: flex; + } + \` + ` + const { code } = babel.transform(basic, { + plugins: [[plugin]] + }) + expect(code).toMatchSnapshot() + }) + test(':fullscreen', () => { + const basic = ` + const cls1 = css({ + ':fullscreen': { + color: 'green', + display: 'flex' + } + }) + const cls2 = css\` + :fullscreen { + color: green; + display: flex; + } + \` + ` + const { code } = babel.transform(basic, { + plugins: [[plugin]] + }) + expect(code).toMatchSnapshot() + }) test('only composes', () => { const basic = ` const cls1 = css\`