(style: Dict, selectors: Array<string>, conditions: String[])
| 72 | } |
| 73 | |
| 74 | const parse = (style: Dict, selectors: Array<string>, conditions: String[]) => { |
| 75 | let cssText = '' |
| 76 | |
| 77 | for (const name in style) { |
| 78 | const isAtRuleLike = name[0] === '@' |
| 79 | const isVariableLike = !isAtRuleLike && name.startsWith('--') |
| 80 | const rules = (isAtRuleLike && Array.isArray(style[name]) ? style[name] : [style[name]]) as Array<string | Dict> |
| 81 | |
| 82 | for (const data of rules) { |
| 83 | const isObjectLike = typeof data === 'object' && data && data.toString === toString |
| 84 | |
| 85 | // Declaration rule (no nested rules), just property and value |
| 86 | if (!isObjectLike) { |
| 87 | cssText = write(cssText, selectors, conditions, name, data as string | number, isAtRuleLike, isVariableLike) |
| 88 | continue |
| 89 | } |
| 90 | |
| 91 | // Closing selector block |
| 92 | if (used.has(selectors)) { |
| 93 | used.delete(selectors) |
| 94 | |
| 95 | cssText += '}' |
| 96 | } |
| 97 | |
| 98 | // This ensures a unique reference with `String("xxx")` even if the same string "xxx" is used multiple times |
| 99 | let usedName = Object(name) |
| 100 | |
| 101 | let nextSelectors: typeof selectors |
| 102 | |
| 103 | // Nested condition |
| 104 | if (isAtRuleLike) { |
| 105 | if (selectors.length && name.includes('@scope') && name.includes('&')) { |
| 106 | const resolvedSelectors = getResolvedSelectors(selectors, parseSelectors(name)) |
| 107 | usedName = Object(resolvedSelectors[0]) |
| 108 | } |
| 109 | nextSelectors = selectors |
| 110 | cssText += parse(data, nextSelectors, conditions.concat(usedName)) |
| 111 | } else { |
| 112 | // Nested selector rule |
| 113 | const nestedSelectors = parseSelectors(name) |
| 114 | nextSelectors = selectors.length |
| 115 | ? getResolvedSelectors(selectors as string[], nestedSelectors) |
| 116 | : nestedSelectors |
| 117 | cssText += parse(data, nextSelectors, conditions) |
| 118 | } |
| 119 | |
| 120 | // Closing nested condition block |
| 121 | if (used.has(usedName)) { |
| 122 | used.delete(usedName) |
| 123 | cssText += '}\n' |
| 124 | } |
| 125 | |
| 126 | // Closing nested selector block |
| 127 | if (used.has(nextSelectors)) { |
| 128 | used.delete(nextSelectors) |
| 129 | cssText += '}\n' |
| 130 | } |
| 131 | } |
no test coverage detected