(css, { strict = false } = {})
| 83 | */ |
| 84 | |
| 85 | export function parseCSS(css, { strict = false } = {}) { |
| 86 | let root; |
| 87 | try { |
| 88 | root = parseRoot(css, { strict }); |
| 89 | } catch (e) { |
| 90 | if (strict) throw e; |
| 91 | return []; |
| 92 | } |
| 93 | |
| 94 | const ret = []; |
| 95 | const nodes = root.nodes; |
| 96 | let ignoring = false; |
| 97 | let ignoreEntireFile = false; |
| 98 | |
| 99 | // Check if the first node is a comment that ignores the entire file |
| 100 | if (nodes.length > 0 && nodes[0].type === 'comment' && nodes[0].text) { |
| 101 | if (nodes[0].text.trim() === 'juice ignore') { |
| 102 | ignoreEntireFile = true; |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | if (ignoreEntireFile) { |
| 107 | return ret; |
| 108 | } |
| 109 | |
| 110 | for (let i = 0, l = nodes.length; i < l; i++) { |
| 111 | const node = nodes[i]; |
| 112 | |
| 113 | if (node.type === 'comment') { |
| 114 | if (!node.text) continue; |
| 115 | const comment = node.text.trim(); |
| 116 | |
| 117 | if (comment === 'juice start ignore') { |
| 118 | ignoring = true; |
| 119 | } else if (comment === 'juice end ignore') { |
| 120 | ignoring = false; |
| 121 | } else if (comment === 'juice ignore next') { |
| 122 | // Skip the next node |
| 123 | i++; |
| 124 | } |
| 125 | continue; |
| 126 | } |
| 127 | |
| 128 | if (ignoring) continue; |
| 129 | |
| 130 | if (node.type === 'rule') { |
| 131 | const selectors = node.selectors; |
| 132 | |
| 133 | // Filter declarations: skip those flagged with a preceding "juice ignore next" |
| 134 | const filtered = []; |
| 135 | let skipNext = false; |
| 136 | for (const child of node.nodes) { |
| 137 | if (child.type === 'comment' && child.text && child.text.trim() === 'juice ignore next') { |
| 138 | skipNext = true; |
| 139 | continue; |
| 140 | } |
| 141 | if (skipNext && child.type === 'decl') { |
| 142 | skipNext = false; |
nothing calls this directly
no test coverage detected
searching dependent graphs…