Skip to content

Commit

Permalink
Fix prefixed selectors in objects (#205)
Browse files Browse the repository at this point in the history
Closes #201
  • Loading branch information
emmatown authored Jul 30, 2017
1 parent 5173549 commit 678cd1d
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 9 deletions.
31 changes: 30 additions & 1 deletion src/ast-object.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,37 @@ function prefixAst (args, t) {
? 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
Expand Down
23 changes: 16 additions & 7 deletions src/babel.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// @flow weak
import fs from 'fs'
import { basename, dirname, join as pathJoin, sep as pathSep, relative } from 'path'
import {
basename,
dirname,
join as pathJoin,
sep as pathSep,
relative
} from 'path'
import { touchSync } from 'touch'
import { inline } from './inline'
import { parseCSS } from './parser'
Expand Down Expand Up @@ -83,7 +89,7 @@ export function replaceCssWithCallExpression (
// babel-plugin-styled-components
// https://github.com/styled-components/babel-plugin-styled-components/blob/37a13e9c21c52148ce6e403100df54c0b1561a88/src/visitors/displayNameAndId.js#L49-L93

const findModuleRoot = (filename) => {
const findModuleRoot = filename => {
if (!filename || filename === 'unknown') {
return null
}
Expand All @@ -100,7 +106,7 @@ const findModuleRoot = (filename) => {
const FILE_HASH = 'emotion-file-hash'
const COMPONENT_POSITION = 'emotion-component-position'

const getFileHash = (state) => {
const getFileHash = state => {
const { file } = state
// hash calculation is costly due to fs operations, so we'll cache it per file.
if (file.get(FILE_HASH)) {
Expand All @@ -109,10 +115,13 @@ const getFileHash = (state) => {
const filename = file.opts.filename
// find module root directory
const moduleRoot = findModuleRoot(filename)
const filePath = moduleRoot && relative(moduleRoot, filename).replace(pathSep, '/')
const filePath =
moduleRoot && relative(moduleRoot, filename).replace(pathSep, '/')
let moduleName = ''
if (moduleRoot) {
const packageJsonString = fs.readFileSync(pathJoin(moduleRoot, 'package.json'))
const packageJsonString = fs.readFileSync(
pathJoin(moduleRoot, 'package.json')
)
if (packageJsonString) {
try {
moduleName = JSON.parse(packageJsonString).name
Expand All @@ -126,13 +135,13 @@ const getFileHash = (state) => {
return fileHash
}

const getNextId = (state) => {
const getNextId = state => {
const id = state.file.get(COMPONENT_POSITION) || 0
state.file.set(COMPONENT_POSITION, id + 1)
return id
}

const getComponentId = (state) => {
const getComponentId = state => {
// Prefix the identifier with css- because CSS classes cannot start with a number
// Also in snapshots with jest-glamor-react the hash will be replaced with an index
return `css-${getFileHash(state)}${getNextId(state)}`
Expand Down
4 changes: 3 additions & 1 deletion src/macro-styled.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ module.exports = function macro (options) {
(t.isCallExpression(path.node.callee) ||
t.isIdentifier(path.node.callee.object))
) {
path.replaceWith(buildStyledObjectCallExpression(path, state, runtimeNode, t))
path.replaceWith(
buildStyledObjectCallExpression(path, state, runtimeNode, t)
)
}
})
}
Expand Down
12 changes: 12 additions & 0 deletions test/__snapshots__/react.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
80 changes: 80 additions & 0 deletions test/babel/__snapshots__/css.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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([{
Expand Down
40 changes: 40 additions & 0 deletions test/babel/css.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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\`
Expand Down

0 comments on commit 678cd1d

Please sign in to comment.