PNG  IHDR;IDATxܻn0K )(pA 7LeG{ §㻢|ذaÆ 6lذaÆ 6lذaÆ 6lom$^yذag5bÆ 6lذaÆ 6lذa{ 6lذaÆ `}HFkm,mӪôô! x|'ܢ˟;E:9&ᶒ}{v]n&6 h_tڠ͵-ҫZ;Z$.Pkž)!o>}leQfJTu іچ\X=8Rن4`Vwl>nG^is"ms$ui?wbs[m6K4O.4%/bC%t Mז -lG6mrz2s%9s@-k9=)kB5\+͂Zsٲ Rn~GRC wIcIn7jJhۛNCS|j08yiHKֶۛkɈ+;SzL/F*\Ԕ#"5m2[S=gnaPeғL lذaÆ 6l^ḵaÆ 6lذaÆ 6lذa; _ذaÆ 6lذaÆ 6lذaÆ RIENDB` 'use strict'; const stable = require('stable'); const csstree = require('css-tree'); const specificity = require('csso/lib/restructure/prepare/specificity'); const { selectAll, is } = require('css-select'); const svgoCssSelectAdapter = require('./svgo/css-select-adapter.js'); const { compareSpecificity } = require('./css-tools.js'); const { attrsGroups, inheritableAttrs, presentationNonInheritableGroupAttrs, } = require('../plugins/_collections.js'); const cssSelectOptions = { xmlMode: true, adapter: svgoCssSelectAdapter, }; const parseRule = (ruleNode, dynamic) => { let selectors; let selectorsSpecificity; const declarations = []; csstree.walk(ruleNode, (cssNode) => { if (cssNode.type === 'SelectorList') { // compute specificity from original node to consider pseudo classes selectorsSpecificity = specificity(cssNode); const newSelectorsNode = csstree.clone(cssNode); csstree.walk(newSelectorsNode, (pseudoClassNode, item, list) => { if (pseudoClassNode.type === 'PseudoClassSelector') { dynamic = true; list.remove(item); } }); selectors = csstree.generate(newSelectorsNode); return csstree.walk.skip; } if (cssNode.type === 'Declaration') { declarations.push({ name: cssNode.property, value: csstree.generate(cssNode.value), important: cssNode.important, }); return csstree.walk.skip; } }); return { dynamic, selectors, specificity: selectorsSpecificity, declarations, }; }; const parseStylesheet = (css, dynamic) => { const rules = []; const ast = csstree.parse(css); csstree.walk(ast, (cssNode) => { if (cssNode.type === 'Rule') { rules.push(parseRule(cssNode, dynamic || false)); return csstree.walk.skip; } if (cssNode.type === 'Atrule') { if (cssNode.name === 'keyframes') { return csstree.walk.skip; } csstree.walk(cssNode, (ruleNode) => { if (ruleNode.type === 'Rule') { rules.push(parseRule(ruleNode, dynamic || true)); return csstree.walk.skip; } }); return csstree.walk.skip; } }); return rules; }; const computeOwnStyle = (node, stylesheet) => { const computedStyle = {}; const importantStyles = new Map(); // collect attributes for (const [name, value] of Object.entries(node.attributes)) { if (attrsGroups.presentation.includes(name)) { computedStyle[name] = { type: 'static', inherited: false, value }; importantStyles.set(name, false); } } // collect matching rules for (const { selectors, declarations, dynamic } of stylesheet) { if (is(node, selectors, cssSelectOptions)) { for (const { name, value, important } of declarations) { const computed = computedStyle[name]; if (computed && computed.type === 'dynamic') { continue; } if (dynamic) { computedStyle[name] = { type: 'dynamic', inherited: false }; continue; } if ( computed == null || important === true || importantStyles.get(name) === false ) { computedStyle[name] = { type: 'static', inherited: false, value }; importantStyles.set(name, important); } } } } // collect inline styles for (const [name, { value, priority }] of node.style.properties) { const computed = computedStyle[name]; const important = priority === 'important'; if (computed && computed.type === 'dynamic') { continue; } if ( computed == null || important === true || importantStyles.get(name) === false ) { computedStyle[name] = { type: 'static', inherited: false, value }; importantStyles.set(name, important); } } return computedStyle; }; const computeStyle = (node) => { // find root let root = node; while (root.parentNode) { root = root.parentNode; } // find all styles const styleNodes = selectAll('style', root, cssSelectOptions); // parse all styles const stylesheet = []; for (const styleNode of styleNodes) { const dynamic = styleNode.attributes.media != null && styleNode.attributes.media !== 'all'; if ( styleNode.attributes.type == null || styleNode.attributes.type === '' || styleNode.attributes.type === 'text/css' ) { const children = styleNode.children; for (const child of children) { if (child.type === 'text' || child.type === 'cdata') { stylesheet.push(...parseStylesheet(child.value, dynamic)); } } } } // sort by selectors specificity stable.inplace(stylesheet, (a, b) => compareSpecificity(a.specificity, b.specificity) ); // collect inherited styles const computedStyles = computeOwnStyle(node, stylesheet); let parent = node; while (parent.parentNode && parent.parentNode.type !== 'root') { const inheritedStyles = computeOwnStyle(parent.parentNode, stylesheet); for (const [name, computed] of Object.entries(inheritedStyles)) { if ( computedStyles[name] == null && // ignore not inheritable styles inheritableAttrs.includes(name) === true && presentationNonInheritableGroupAttrs.includes(name) === false ) { computedStyles[name] = { ...computed, inherited: true }; } } parent = parent.parentNode; } return computedStyles; }; exports.computeStyle = computeStyle;