* Parse CSS text into rules * @param {string} cssText CSS text to parse
(cssText)
| 653 | * @param {string} cssText CSS text to parse |
| 654 | */ |
| 655 | _parseCssRules(cssText) { |
| 656 | const { |
| 657 | TT_LEFT_CURLY_BRACKET, |
| 658 | TT_RIGHT_CURLY_BRACKET, |
| 659 | TT_SEMICOLON, |
| 660 | readToken |
| 661 | } = require(class="st">"../../lib/css/syntax"); |
| 662 | |
| 663 | /** @type {CssRule[]} */ |
| 664 | const rules = []; |
| 665 | /** @type {StyleDeclaration} */ |
| 666 | let currentRule = { getPropertyValue }; |
| 667 | /** @type {string | undefined} */ |
| 668 | let selector; |
| 669 | let last = 0; |
| 670 | |
| 671 | const processDeclaration = (/** @type {string} */ str) => { |
| 672 | const colon = str.indexOf(class="st">":"); |
| 673 | if (colon > 0) { |
| 674 | const property = str.slice(0, colon).trim(); |
| 675 | const value = str.slice(colon + 1).trim(); |
| 676 | currentRule[property] = value; |
| 677 | } |
| 678 | }; |
| 679 | |
| 680 | class="cm">// Remove comments |
| 681 | const cleanCss = cssText |
| 682 | class="cm">// @ts-expect-error we use es2018 for such tests |
| 683 | .replace(/\/\*.*?\*\class="cm">//gs, class="st">""); |
| 684 | |
| 685 | let ruleStart = 0; |
| 686 | |
| 687 | for (let pos = 0; ; ) { |
| 688 | const t = readToken(cleanCss, pos, /** @type {MutableToken} */ ({})); |
| 689 | if (t === undefined) break; |
| 690 | pos = t.end; |
| 691 | if (t.type === TT_LEFT_CURLY_BRACKET) { |
| 692 | if (selector === undefined) { |
| 693 | selector = cleanCss.slice(last, t.start).trim(); |
| 694 | ruleStart = last; |
| 695 | last = t.end; |
| 696 | } |
| 697 | } else if (t.type === TT_RIGHT_CURLY_BRACKET) { |
| 698 | processDeclaration(cleanCss.slice(last, t.start)); |
| 699 | last = t.end; |
| 700 | |
| 701 | class="cm">// Generate cssText for the entire rule |
| 702 | const ruleText = cleanCss.slice(ruleStart, t.end).trim(); |
| 703 | const cssText = `${selector} ${ruleText.slice(ruleText.indexOf(class="st">"{"))}`; |
| 704 | |
| 705 | rules.push({ |
| 706 | selectorText: selector, |
| 707 | style: currentRule, |
| 708 | cssText |
| 709 | }); |
| 710 | selector = undefined; |
| 711 | currentRule = { getPropertyValue }; |
| 712 | } else if (t.type === TT_SEMICOLON) { |