|
93 | 93 | if (name.charAt(0) != '#') { |
94 | 94 | return false; |
95 | 95 | } |
96 | | - if (isIdent(name.charAt(1))) { |
97 | | - return true; |
98 | | - } |
99 | | - return true; |
| 96 | + return isIdent(name.charAt(1)); |
100 | 97 | } |
101 | 98 | function isNumber(name) { |
102 | 99 | if (name.length == 0) { |
|
1566 | 1563 | } |
1567 | 1564 |
|
1568 | 1565 | function render(data, opt = {}) { |
| 1566 | + const startTime = performance.now(); |
1569 | 1567 | const options = Object.assign(opt.minify ?? true ? { |
1570 | 1568 | indent: '', |
1571 | 1569 | newLine: '', |
|
1584 | 1582 | } |
1585 | 1583 | return acc + renderToken(curr, options); |
1586 | 1584 | } |
1587 | | - return { code: doRender(data, options, reducer, 0) }; |
| 1585 | + return { code: doRender(data, options, reducer, 0), stats: { |
| 1586 | + total: `${(performance.now() - startTime).toFixed(2)}ms` |
| 1587 | + } }; |
1588 | 1588 | } |
1589 | 1589 | // @ts-ignore |
1590 | 1590 | function doRender(data, options, reducer, level = 0, indents = []) { |
|
1613 | 1613 | case 'AtRule': |
1614 | 1614 | case 'Rule': |
1615 | 1615 | if (data.typ == 'AtRule' && !('chi' in data)) { |
1616 | | - return `${indent}@${data.nam} ${data.val};`; |
| 1616 | + return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`; |
1617 | 1617 | } |
1618 | 1618 | // @ts-ignore |
1619 | 1619 | let children = data.chi.reduce((css, node) => { |
|
1625 | 1625 | str = `${node.nam}:${options.indent}${node.val.reduce(reducer, '').trimEnd()};`; |
1626 | 1626 | } |
1627 | 1627 | else if (node.typ == 'AtRule' && !('chi' in node)) { |
1628 | | - str = `@${node.nam} ${node.val};`; |
| 1628 | + str = `${data.val === '' ? '' : options.indent || ' '}${data.val};`; |
1629 | 1629 | } |
1630 | 1630 | else { |
1631 | 1631 | str = doRender(node, options, reducer, level + 1, indents); |
|
1642 | 1642 | children = children.slice(0, -1); |
1643 | 1643 | } |
1644 | 1644 | if (data.typ == 'AtRule') { |
1645 | | - return `@${data.nam}${data.val ? ' ' + data.val + options.indent : ''}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`; |
| 1645 | + return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`; |
1646 | 1646 | } |
1647 | 1647 | return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`; |
1648 | 1648 | } |
|
1792 | 1792 | case 'Delim': |
1793 | 1793 | return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val; |
1794 | 1794 | } |
1795 | | - throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`); |
| 1795 | + console.error(`unexpected token ${JSON.stringify(token, null, 1)}`); |
| 1796 | + // throw new Error(`unexpected token ${JSON.stringify(token, null, 1)}`); |
| 1797 | + return ''; |
1796 | 1798 | } |
1797 | 1799 |
|
1798 | 1800 | function eq(a, b) { |
|
2581 | 2583 | // @ts-ignore |
2582 | 2584 | return null; |
2583 | 2585 | } |
2584 | | - return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node2 : node2 }; |
| 2586 | + return { result, node1: exchanged ? node2 : node1, node2: exchanged ? node1 : node2 }; |
2585 | 2587 | } |
2586 | 2588 | function matchSelectors(selector1, selector2, parentType) { |
2587 | 2589 | let match = [[]]; |
|
2769 | 2771 | if (node.typ == 'AtRule' && node.nam == 'font-face') { |
2770 | 2772 | continue; |
2771 | 2773 | } |
2772 | | - if (node.typ == 'AtRule' && node.val == 'all') { |
| 2774 | + if (node.typ == 'AtRule') { |
| 2775 | + if (node.nam == 'media' && node.val == 'all') { |
| 2776 | + // @ts-ignore |
| 2777 | + ast.chi?.splice(i, 1, ...node.chi); |
| 2778 | + i--; |
| 2779 | + continue; |
| 2780 | + } |
| 2781 | + // console.debug({previous, node}); |
2773 | 2782 | // @ts-ignore |
2774 | | - ast.chi?.splice(i, 1, ...node.chi); |
2775 | | - i--; |
2776 | | - continue; |
| 2783 | + if (previous?.typ == 'AtRule' && |
| 2784 | + previous.nam == node.nam && |
| 2785 | + previous.val == node.val) { |
| 2786 | + if ('chi' in node) { |
| 2787 | + // @ts-ignore |
| 2788 | + previous.chi.push(...node.chi); |
| 2789 | + } |
| 2790 | + // else { |
| 2791 | + ast?.chi?.splice(i--, 1); |
| 2792 | + continue; |
| 2793 | + // } |
| 2794 | + } |
2777 | 2795 | } |
2778 | 2796 | // @ts-ignore |
2779 | 2797 | if (node.typ == 'Rule') { |
|
3288 | 3306 | } |
3289 | 3307 | buffer += quoteStr; |
3290 | 3308 | while (value = peek()) { |
3291 | | - if (ind >= iterator.length) { |
3292 | | - yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string'); |
3293 | | - break; |
3294 | | - } |
| 3309 | + // if (ind >= iterator.length) { |
| 3310 | + // |
| 3311 | + // yield pushToken(buffer, hasNewLine ? 'Bad-string' : 'Unclosed-string'); |
| 3312 | + // break; |
| 3313 | + // } |
3295 | 3314 | if (value == '\\') { |
3296 | 3315 | const sequence = peek(6); |
3297 | 3316 | let escapeSequence = ''; |
|
3314 | 3333 | // not hex or new line |
3315 | 3334 | // @ts-ignore |
3316 | 3335 | if (i == 1 && !isNewLine(codepoint)) { |
3317 | | - buffer += sequence[i]; |
| 3336 | + buffer += value + sequence[i]; |
3318 | 3337 | next(2); |
3319 | 3338 | continue; |
3320 | 3339 | } |
|
3334 | 3353 | continue; |
3335 | 3354 | } |
3336 | 3355 | // buffer += value; |
3337 | | - if (ind >= iterator.length) { |
3338 | | - // drop '\\' at the end |
3339 | | - yield pushToken(buffer); |
3340 | | - break; |
3341 | | - } |
| 3356 | + // if (ind >= iterator.length) { |
| 3357 | + // |
| 3358 | + // // drop '\\' at the end |
| 3359 | + // yield pushToken(buffer); |
| 3360 | + // break; |
| 3361 | + // } |
3342 | 3362 | buffer += next(2); |
3343 | 3363 | continue; |
3344 | 3364 | } |
|
3507 | 3527 | buffer = ''; |
3508 | 3528 | break; |
3509 | 3529 | } |
3510 | | - buffer += value; |
| 3530 | + buffer += prev() + value; |
3511 | 3531 | break; |
3512 | 3532 | case '"': |
3513 | 3533 | case "'": |
|
3709 | 3729 | * @param opt |
3710 | 3730 | */ |
3711 | 3731 | async function parse$1(iterator, opt = {}) { |
| 3732 | + const startTime = performance.now(); |
3712 | 3733 | const errors = []; |
3713 | 3734 | const options = { |
3714 | 3735 | src: '', |
|
3847 | 3868 | src: options.resolve(url, options.src).absolute |
3848 | 3869 | })); |
3849 | 3870 | }); |
3850 | | - bytesIn += root.bytesIn; |
| 3871 | + bytesIn += root.stats.bytesIn; |
3851 | 3872 | if (root.ast.chi.length > 0) { |
3852 | 3873 | context.chi.push(...root.ast.chi); |
3853 | 3874 | } |
|
3893 | 3914 | // rule |
3894 | 3915 | if (delim.typ == 'Block-start') { |
3895 | 3916 | const position = map.get(tokens[0]); |
3896 | | - // if (context.typ == 'Rule') { |
3897 | | - // |
3898 | | - // if (tokens[0]?.typ == 'Iden') { |
3899 | | - // errors.push({action: 'drop', message: 'invalid nesting rule', location: {src, ...position}}); |
3900 | | - // return null; |
3901 | | - // } |
3902 | | - // } |
3903 | 3917 | const uniq = new Map; |
3904 | 3918 | parseTokens(tokens, { minify: options.minify }).reduce((acc, curr, index, array) => { |
3905 | 3919 | if (curr.typ == 'Whitespace') { |
|
4075 | 4089 | if (tokens.length > 0) { |
4076 | 4090 | await parseNode(tokens); |
4077 | 4091 | } |
| 4092 | + const endParseTime = performance.now(); |
4078 | 4093 | if (options.minify) { |
4079 | 4094 | if (ast.chi.length > 0) { |
4080 | 4095 | minify(ast, options, true); |
4081 | 4096 | } |
4082 | 4097 | } |
4083 | | - return { ast, errors, bytesIn }; |
| 4098 | + const endTime = performance.now(); |
| 4099 | + return { |
| 4100 | + ast, errors, stats: { |
| 4101 | + bytesIn, |
| 4102 | + parse: `${(endParseTime - startTime).toFixed(2)}ms`, |
| 4103 | + minify: `${(endTime - endParseTime).toFixed(2)}ms`, |
| 4104 | + total: `${(endTime - startTime).toFixed(2)}ms` |
| 4105 | + } |
| 4106 | + }; |
4084 | 4107 | } |
4085 | 4108 | function parseString(src, options = { location: false }) { |
4086 | 4109 | return [...tokenize(src)].map(t => { |
|
4431 | 4454 | async function transform$1(css, options = {}) { |
4432 | 4455 | options = { minify: true, removeEmpty: true, ...options }; |
4433 | 4456 | const startTime = performance.now(); |
4434 | | - const parseResult = await parse$1(css, options); |
4435 | | - const renderTime = performance.now(); |
4436 | | - const rendered = render(parseResult.ast, options); |
4437 | | - const endTime = performance.now(); |
4438 | | - return { |
4439 | | - ...parseResult, ...rendered, stats: { |
4440 | | - bytesIn: parseResult.bytesIn, |
4441 | | - bytesOut: rendered.code.length, |
4442 | | - parse: `${(renderTime - startTime).toFixed(2)}ms`, |
4443 | | - render: `${(endTime - renderTime).toFixed(2)}ms`, |
4444 | | - total: `${(endTime - startTime).toFixed(2)}ms` |
4445 | | - } |
4446 | | - }; |
| 4457 | + return parse$1(css, options).then((parseResult) => { |
| 4458 | + const rendered = render(parseResult.ast, options); |
| 4459 | + return { |
| 4460 | + ...parseResult, ...rendered, stats: { |
| 4461 | + bytesOut: rendered.code.length, |
| 4462 | + ...parseResult.stats, |
| 4463 | + render: rendered.stats.total, |
| 4464 | + total: `${(performance.now() - startTime).toFixed(2)}ms` |
| 4465 | + } |
| 4466 | + }; |
| 4467 | + }); |
4447 | 4468 | } |
4448 | 4469 |
|
4449 | 4470 | const matchUrl = /^(https?:)?\/\//; |
|
0 commit comments