Skip to content

Commit

Permalink
do not merge rules when the selector contains vendor specific pseudo …
Browse files Browse the repository at this point in the history
…selector #35
  • Loading branch information
tbela99 committed May 11, 2024
1 parent 3886cb4 commit 07afe19
Show file tree
Hide file tree
Showing 21 changed files with 710 additions and 292 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Changelog

## V0.5.1

- [x] failed to flatten @import when using url() syntax
-

## V0.5.0

- [x] render node with parents
- [x] fix relative color from xyz
- [x] fix bug when inlineCss is true bug no css variable exists
Expand Down
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -497,30 +497,36 @@ for (const {node, parent, root} of walk(ast)) {

### Comment

- typ: string 'Comment'
- typ: number
- val: string, the comment

### Declaration

- typ: string 'Declaration'
- typ: number
- nam: string, declaration name
- val: array of tokens

### Rule

- typ: string 'Rule'
- typ: number
- sel: string, css selector
- chi: array of children

### AtRule

- typ: string 'AtRule'
- typ: number
- nam: string. AtRule name
- val: rule prelude

### AtRuleStyleSheet

- typ: string 'Stylesheet'
- typ: number
- chi: array of children

### KeyFrameRule

- typ: number
- sel: string, css selector
- chi: array of children

## Sourcemap
Expand Down
113 changes: 94 additions & 19 deletions dist/index-umd-web.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
EnumToken[EnumToken["FractionTokenType"] = 69] = "FractionTokenType";
EnumToken[EnumToken["IdenListTokenType"] = 70] = "IdenListTokenType";
EnumToken[EnumToken["GridTemplateFuncTokenType"] = 71] = "GridTemplateFuncTokenType";
EnumToken[EnumToken["KeyFrameRuleNodeType"] = 72] = "KeyFrameRuleNodeType";
/* aliases */
EnumToken[EnumToken["Time"] = 25] = "Time";
EnumToken[EnumToken["Iden"] = 7] = "Iden";
Expand Down Expand Up @@ -2510,7 +2511,15 @@
* @param tokens
*/
function evaluate(tokens) {
const nodes = inlineExpression(evaluateExpression(buildExpression(tokens)));
let nodes;
try {
nodes = inlineExpression(evaluateExpression(buildExpression(tokens)));
}
catch (e) {
// console.error({tokens});
// console.error(e);
return tokens;
}
if (nodes.length <= 1) {
return nodes;
}
Expand Down Expand Up @@ -3036,7 +3045,7 @@
return result;
}
function updateSourceMap(node, options, cache, sourcemap, position, str) {
if ([exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType].includes(node.typ)) {
if ([exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType, exports.EnumToken.KeyFrameRuleNodeType].includes(node.typ)) {
let src = node.loc?.src ?? '';
let output = options.output ?? '';
if (!(src in cache)) {
Expand Down Expand Up @@ -3096,6 +3105,7 @@
}, '');
case exports.EnumToken.AtRuleNodeType:
case exports.EnumToken.RuleNodeType:
case exports.EnumToken.KeyFrameRuleNodeType:
if (data.typ == exports.EnumToken.AtRuleNodeType && !('chi' in data)) {
return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`;
}
Expand Down Expand Up @@ -6446,6 +6456,9 @@
const position = map.get(tokens[0]);
const uniq = new Map;
parseTokens(tokens, { minify: true }).reduce((acc, curr, index, array) => {
if (curr.typ == exports.EnumToken.CommentTokenType) {
return acc;
}
if (curr.typ == exports.EnumToken.WhitespaceTokenType) {
if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
trimWhiteSpace.includes(array[index + 1]?.typ) ||
Expand All @@ -6467,7 +6480,7 @@
return acc;
}, uniq);
const node = {
typ: exports.EnumToken.RuleNodeType,
typ: context.typ == exports.EnumToken.AtRuleNodeType && context.nam == 'keyframes' ? exports.EnumToken.KeyFrameRuleNodeType : exports.EnumToken.RuleNodeType,
// @ts-ignore
sel: [...uniq.keys()].join(','),
chi: []
Expand Down Expand Up @@ -8405,8 +8418,9 @@
// @ts-ignore
const features = Object.values(allFeatures).sort((a, b) => a.ordering - b.ordering);
function minify(ast, options = {}, recursive = false, errors, nestingContent, context = {}) {
// console.debug(JSON.stringify({ast}, null, 1));
if (!('nodes' in context)) {
context.nodes = new WeakSet;
context.nodes = new Set;
}
if (context.nodes.has(ast)) {
return ast;
Expand Down Expand Up @@ -8637,7 +8651,7 @@
}
if (shouldMerge) {
// @ts-ignore
if ((node.typ == exports.EnumToken.RuleNodeType && node.sel == previous.sel) ||
if (((node.typ == exports.EnumToken.RuleNodeType || node.typ == exports.EnumToken.KeyFrameRuleNodeType) && node.sel == previous.sel) ||
// @ts-ignore
(node.typ == exports.EnumToken.AtRuleNodeType) && node.val != 'font-face' && node.val == previous.val) {
// @ts-ignore
Expand All @@ -8656,32 +8670,33 @@
nodeIndex = i;
continue;
}
else if (node.typ == exports.EnumToken.RuleNodeType && previous?.typ == exports.EnumToken.RuleNodeType) {
else if (node.typ == previous?.typ && [exports.EnumToken.KeyFrameRuleNodeType, exports.EnumToken.RuleNodeType].includes(node.typ)) {
const intersect = diff(previous, node, reducer, options);
if (intersect != null) {
if (intersect.node1.chi.length == 0) {
// @ts-ignore
ast.chi.splice(i--, 1);
// @ts-ignore
node = ast.chi[i];
// node = ast.chi[i];
}
else {
// @ts-ignore
ast.chi.splice(i, 1, intersect.node1);
node = intersect.node1;
// node = ast.chi intersect.node1;
}
if (intersect.node2.chi.length == 0) {
// @ts-ignore
ast.chi.splice(nodeIndex, 1, intersect.result);
previous = intersect.result;
}
else {
// @ts-ignore
ast.chi.splice(nodeIndex, 1, intersect.result, intersect.node2);
previous = intersect.result;
// @ts-ignore
i = nodeIndex;
i = (nodeIndex ?? 0) + 1;
}
reduceRuleSelector(intersect.result);
previous = intersect.result;
nodeIndex = i;
}
}
}
Expand Down Expand Up @@ -8903,6 +8918,18 @@
result.push([]);
continue;
}
if (chr == ':') {
if (str !== '') {
// @ts-ignore
result.at(-1).push(str);
str = '';
}
if (buffer.charAt(i + 1) == ':') {
chr += buffer.charAt(++i);
}
str += chr;
continue;
}
str += chr;
if (chr == '\\') {
str += buffer.charAt(++i);
Expand Down Expand Up @@ -9204,6 +9231,52 @@
const raw1 = node1.raw;
// @ts-ignore
const raw2 = node2.raw;
if (raw1 != null && raw2 != null) {
const prefixes1 = new Set;
const prefixes2 = new Set;
for (const token1 of raw1) {
for (const t of token1) {
if (t[0] == ':') {
const matches = t.match(/::?-([a-z]+)-/);
if (matches == null) {
continue;
}
prefixes1.add(matches[1]);
if (prefixes1.size > 1) {
break;
}
}
}
if (prefixes1.size > 1) {
break;
}
}
for (const token2 of raw2) {
for (const t of token2) {
if (t[0] == ':') {
const matches = t.match(/::?-([a-z]+)-/);
if (matches == null) {
continue;
}
prefixes2.add(matches[1]);
if (prefixes2.size > 1) {
break;
}
}
}
if (prefixes2.size > 1) {
break;
}
}
if (prefixes1.size != prefixes2.size) {
return null;
}
for (const prefix of prefixes1) {
if (!prefixes2.has(prefix)) {
return null;
}
}
}
// @ts-ignore
node1 = { ...node1, chi: node1.chi.slice() };
node2 = { ...node2, chi: node2.chi.slice() };
Expand Down Expand Up @@ -9240,7 +9313,7 @@
const result = (intersect.length == 0 ? null : {
...node1,
// @ts-ignore
sel: [...new Set([...(n1?.raw?.reduce(reducer, []) || splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) || splitRule(n2.sel))])].join(','),
sel: [...new Set([...(n1?.raw?.reduce(reducer, []) ?? splitRule(n1.sel)).concat(n2?.raw?.reduce(reducer, []) ?? splitRule(n2.sel))])].join(','),
chi: intersect.reverse()
});
if (result == null || [n1, n2].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + doRender(curr, options).code.length, 0) <= [node1, node2, result].reduce((acc, curr) => curr.chi.length == 0 ? acc : acc + doRender(curr, options).code.length, 0)) {
Expand Down Expand Up @@ -9391,16 +9464,18 @@
return response.text();
}
async function load(url, currentFile) {
let t;
if (matchUrl.test(url)) {
return fetch(url).then(parseResponse);
t = new URL(url);
}
if (matchUrl.test(currentFile)) {
return fetch(new URL(url, currentFile)).then(parseResponse);
else if (matchUrl.test(currentFile)) {
t = new URL(url, currentFile);
}
else {
const path = resolve(url, currentFile).absolute;
t = new URL(path, self.origin);
}
const path = resolve(url, currentFile).absolute;
const t = new URL(path, self.origin);
// return fetch(new URL(url, new URL(currentFile, self.location.href).href)).then(parseResponse);
return fetch(url, t.origin != self.location.origin ? { mode: 'cors' } : {}).then(parseResponse);
return fetch(t, t.origin != self.origin ? { mode: 'cors' } : {}).then(parseResponse);
}

function render(data, options = {}) {
Expand Down
Loading

0 comments on commit 07afe19

Please sign in to comment.