Skip to content

Commit 228c035

Browse files
authored
Update supports (#45)
1 parent 61df05c commit 228c035

29 files changed

+6197
-190
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ PostCSS JSX Syntax
1313

1414
[PostCSS](https://github.com/postcss/postcss) syntax for parsing [CSS in JS](https://github.com/MicheleBertoli/css-in-js) literals:
1515

16-
- [emotion](https://github.com/emotion-js/emotion)
1716
- [aphrodite](https://github.com/Khan/aphrodite)
17+
- [astroturf](https://github.com/4Catalyzer/astroturf)
18+
- [emotion](https://github.com/emotion-js/emotion)
1819
- [glamor](https://github.com/threepointone/glamor)
1920
- [glamorous](https://github.com/paypal/glamorous)
21+
- [lit-css](https://github.com/bashmish/lit-css)
2022
- [react-native](https://github.com/necolas/react-native-web)
2123
- [react-style](https://github.com/js-next/react-style)
2224
- [reactcss](https://github.com/casesandberg/reactcss)
2325
- [styled-components](https://github.com/styled-components/styled-components)
2426
- [styletron-react](https://github.com/rtsao/styletron)
2527
- [typestyle](https://github.com/typestyle/typestyle)
26-
- [lit-css](https://github.com/bashmish/lit-css)
2728

2829
## Getting Started
2930

extract.js

+46-72
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,40 @@ const {
88
const getTemplate = require("./get-template");
99
const loadSyntax = require("postcss-syntax/load-syntax");
1010

11-
const partSport = {
11+
const supports = {
1212
// https://github.com/Khan/aphrodite
13-
aphrodite: [
14-
"StyleSheet",
15-
"create",
16-
],
17-
1813
// https://github.com/necolas/react-native-web
19-
"react-native": [
20-
"StyleSheet",
21-
"create",
22-
],
23-
};
14+
StyleSheet: true,
15+
16+
// https://github.com/emotion-js/emotion
17+
// import styled from '@emotion/styled'
18+
// https://github.com/threepointone/glamor
19+
// import { styled } from 'glamor/styled'
20+
// https://github.com/rtsao/styletron
21+
// import { styled } from "styletron-react";
22+
styled: true,
23+
24+
// https://github.com/typestyle/typestyle
25+
// import { style } from "typestyle";
26+
style: true,
2427

25-
const supports = {
2628
// https://github.com/4Catalyzer/astroturf
27-
astroturf: true,
29+
// import { css } from 'astroturf';
30+
// https://github.com/bashmish/lit-css
31+
// import { css } from 'lit-css';
32+
// https://github.com/threepointone/glamor
33+
// import { css } from 'glamor'
34+
css: true,
2835

2936
// https://github.com/emotion-js/emotion
37+
// import styled from "react-emotion";
3038
emotion: true,
31-
"@emotion/core": true,
32-
"@emotion/styled": true,
3339
"react-emotion": true,
3440
"preact-emotion": true,
3541

36-
// https://github.com/threepointone/glamor
37-
glamor: true,
38-
3942
// https://github.com/paypal/glamorous
4043
glamorous: true,
4144

42-
// https://github.com/bashmish/lit-css
43-
"lit-css": true,
44-
4545
// https://github.com/js-next/react-style
4646
"react-style": true,
4747

@@ -52,14 +52,9 @@ const supports = {
5252
"styled-components": true,
5353

5454
// https://github.com/rtsao/styletron
55+
// import {styled} from "styletron-react";
56+
// import {withStyle} from "styletron-react";
5557
"styletron-react": true,
56-
57-
// https://github.com/typestyle/typestyle
58-
typestyle: true,
59-
};
60-
61-
const cssPropImpliesStyle = {
62-
"@emotion/core": true
6358
};
6459

6560
const plugins = [
@@ -119,7 +114,6 @@ function literalParser (source, opts, styles) {
119114
let objLiteral = new Set();
120115
let tplLiteral = new Set();
121116
const jobs = [];
122-
let cssPropIsStyle = false;
123117

124118
function addObjectJob (path) {
125119
jobs.push(() => {
@@ -155,6 +149,11 @@ function literalParser (source, opts, styles) {
155149
}
156150

157151
function setSpecifier (id, nameSpace) {
152+
nameSpace.unshift.apply(
153+
nameSpace,
154+
nameSpace.shift().replace(/^\W+/, "").split(/[/\\]+/g)
155+
);
156+
158157
if (types.isIdentifier(id)) {
159158
specifiers.set(id.name, nameSpace);
160159
specifiers.set(id, nameSpace);
@@ -187,36 +186,21 @@ function literalParser (source, opts, styles) {
187186
nameSpace.unshift(node.name);
188187
}
189188
} else {
190-
if (node.name) {
191-
getNameSpace(path.get("name"), nameSpace);
192-
} else if (node.property) {
193-
getNameSpace(path.get("property"), nameSpace);
194-
}
195-
if (node.object) {
196-
getNameSpace(path.get("object"), nameSpace);
197-
} else if (node.callee) {
198-
getNameSpace(path.get("callee"), nameSpace);
199-
}
189+
[
190+
"name",
191+
"property",
192+
"object",
193+
"callee",
194+
].forEach(prop => {
195+
node[prop] && getNameSpace(path.get(prop), nameSpace);
196+
});
200197
}
201198

202199
return nameSpace;
203200
}
204201

205202
function isStylePath (path) {
206-
const nameSpace = getNameSpace(path, []).filter(Boolean);
207-
if (nameSpace.length) {
208-
if (/^(?:css|Styled?)(?:Sheets?)?$/i.test(nameSpace[0]) || supports[nameSpace[0]]) {
209-
return nameSpace;
210-
}
211-
212-
const prefix = partSport[nameSpace.shift()];
213-
214-
if (prefix && nameSpace.length >= prefix.length && prefix.every((name, i) => name === nameSpace[i])) {
215-
return nameSpace;
216-
}
217-
}
218-
219-
return false;
203+
return getNameSpace(path, []).some(name => name && supports[name]);
220204
}
221205

222206
const visitor = {
@@ -228,23 +212,12 @@ function literalParser (source, opts, styles) {
228212
nameSpace.push(specifier.imported.name);
229213
}
230214
setSpecifier(specifier.local, nameSpace);
231-
if (cssPropImpliesStyle[moduleId]) {
232-
cssPropIsStyle = true;
233-
}
234215
});
235216
},
236217
JSXAttribute: (path) => {
237-
const attrName = path.node.name.name;
238-
if (attrName === "css") {
239-
const elePath = path.findParent(p => p.isJSXOpeningElement());
240-
if (!cssPropIsStyle && !isStylePath(elePath)) {
241-
return;
242-
}
243-
} else if (attrName !== "style") {
244-
return;
218+
if (supports[path.node.name.name]) {
219+
addObjectJob(path.get("value.expression"));
245220
}
246-
247-
addObjectJob(path.get("value.expression"));
248221
},
249222
VariableDeclarator: (path) => {
250223
variableDeclarator.set(path.node.id, path.node.init ? [path.get("init")] : []);
@@ -331,25 +304,26 @@ function literalParser (source, opts, styles) {
331304
node.start > style.endIndex || node.end < style.startIndex
332305
))
333306
)).map(node => {
334-
const quasis = node.quasis;
335-
const value = getTemplate(node, source);
336-
307+
const quasis = node.quasis.map(node => ({
308+
start: node.start,
309+
end: node.end,
310+
}));
337311
const style = {
338312
startIndex: quasis[0].start,
339313
endIndex: quasis[quasis.length - 1].end,
340-
content: value,
314+
content: getTemplate(node, source),
341315
};
342316
if (node.expressions.length) {
343317
style.syntax = loadSyntax(opts, __dirname);
344318
style.lang = "template-literal";
345319
style.opts = {
346-
node: node,
320+
quasis: quasis,
347321
};
348322
} else {
349323
style.lang = "css";
350324
}
351325
return style;
352-
}).filter(Boolean);
326+
});
353327

354328
return (styles || []).concat(objLiteral).concat(tplLiteral);
355329
};

object-parser.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ class objectParser {
249249

250250
const value = this.getNodeValue(node.value, rawValue);
251251

252-
if (key.value.startsWith("@")) {
252+
if (key.value[0] === "@") {
253253
const atRule = postcss.atRule({
254254
name: unCamelCase(key.value),
255255
params: value.value,

template-parse.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const Input = require("postcss/lib/input");
55

66
function templateParse (css, opts) {
77
const input = new Input(css, opts);
8-
input.node = opts.node;
8+
input.quasis = opts.quasis;
99
const parser = new TemplateParser(input);
1010
parser.parse();
1111

template-safe-parse.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const Input = require("postcss/lib/input");
55

66
function templateSafeParse (css, opts) {
77
const input = new Input(css, opts);
8-
input.node = opts.node;
8+
input.quasis = opts.quasis;
99
const parser = new TemplateSafeParser(input);
1010
parser.parse();
1111

template-tokenize.js

+18-26
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
const tokenize = require("postcss/lib/tokenize");
33

44
function templateTokenize (input) {
5-
const quasis = input.node.quasis.map((node) => ({
6-
start: node.start,
7-
end: node.end,
8-
})).filter(quasi => quasi.start !== quasi.end);
9-
10-
let pos = input.node.start + 1;
11-
5+
let pos = input.quasis[0].start;
6+
const quasis = input.quasis.filter(quasi => quasi.start !== quasi.end);
127
const tokenizer = tokenize.apply(this, arguments);
138

14-
function tokenInQuasis (start, end) {
15-
return quasis.some(quasi => (start >= quasi.start && end < quasi.end));
9+
function tokenInExpressions (token, returned) {
10+
const start = pos;
11+
pos += token[1].length;
12+
if (!quasis.some(quasi => start >= quasi.start && pos <= quasi.end) || (returned.length && token[0] === returned[0][0])) {
13+
return true;
14+
} else if (returned.length) {
15+
back(token);
16+
}
1617
}
1718

1819
function back (token) {
@@ -24,34 +25,25 @@ function templateTokenize (input) {
2425
const args = arguments;
2526
const returned = [];
2627
let token;
28+
let line;
29+
let column;
30+
2731
while (
2832
(token = tokenizer.nextToken.apply(tokenizer, args)) &&
29-
!tokenInQuasis(pos, (pos += token[1].length)) &&
30-
(returned.length || /\$(?=\{|$)/.test(token[1]))
33+
tokenInExpressions(token, returned)
3134
) {
35+
line = token[4] || token[2] || line;
36+
column = token[5] || token[3] || column;
3237
returned.push(token);
3338
}
3439
if (returned.length) {
35-
let lastToken = returned[returned.length - 1];
36-
if (token && token !== lastToken) {
37-
if (token[0] === returned[0][0]) {
38-
returned.push(token);
39-
lastToken = token;
40-
} else {
41-
back(token);
42-
}
43-
}
44-
while (lastToken[0] === "space") {
45-
back(returned.pop());
46-
lastToken = returned[returned.length - 1];
47-
}
4840
token = [
4941
returned[0][0],
5042
returned.map(token => token[1]).join(""),
5143
returned[0][2],
5244
returned[0][3],
53-
lastToken[4] || lastToken[2],
54-
lastToken[5] || lastToken[3],
45+
line,
46+
column,
5547
];
5648
}
5749
return token;

test/fixtures/CssProp.jsx

-28
This file was deleted.

test/fixtures/emotion-10.jsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
/* global render */
22
/** @jsx jsx */
3-
4-
import { jsx, css } from '@emotion/core';
5-
import styled from '@emotion/styled';
3+
import { css } from "@emotion/core";
4+
import styled from "@emotion/styled";
65

76
const SomeComponent = styled.div`
87
display: flex;
@@ -25,7 +24,7 @@ render(
2524
Some text.
2625
</span>
2726
<span css={{
28-
color: 'sarahgreen'
27+
color: "sarahgreen",
2928
}}>
3029
Some other text.
3130
</span>

0 commit comments

Comments
 (0)