(className: string)
| 90 | } |
| 91 | |
| 92 | export function getComputedStyles(className: string) { |
| 93 | const div = document.createElement('div') |
| 94 | div.className = className |
| 95 | |
| 96 | const computed: ComputedStyles = {} |
| 97 | for (const sheet of document.styleSheets) { |
| 98 | // CSSRulesLists assumes every rule is a CSSRule, not a CSSStyleRule |
| 99 | for (const rule of sheet.cssRules) { |
| 100 | if (rule instanceof CSSMediaRule) { |
| 101 | readMedia(rule) |
| 102 | } else if (rule instanceof CSSStyleRule) { |
| 103 | readRule(rule, computed) |
| 104 | } else { |
| 105 | // console.warn('rule.type =', rule.type) |
| 106 | } |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | return computed |
| 111 | |
| 112 | function matchesSafe(node: HTMLDivElement, selector: string) { |
| 113 | if (!selector) { |
| 114 | return false |
| 115 | } |
| 116 | try { |
| 117 | return node.matches(selector) |
| 118 | } catch (error) { |
| 119 | return false |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | function readRule(rule: CSSStyleRule, dest: ComputedStyles) { |
| 124 | if (matchesSafe(div, rule.selectorText)) { |
| 125 | const {style} = rule |
| 126 | for (let i = 0; i < style.length; i++) { |
| 127 | const prop = style[i] |
| 128 | dest[prop] = style.getPropertyValue(prop) |
| 129 | } |
| 130 | } else { |
| 131 | // console.warn('no match:', rule.selectorText) |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | function readMedia(mediaRule: CSSMediaRule) { |
| 136 | const key = `@media ${mediaRule.media[0]}` |
| 137 | // const dest = computed[key] || (computed[key] = {}) |
| 138 | const dest = {} |
| 139 | for (const rule of mediaRule.cssRules) { |
| 140 | if (rule instanceof CSSStyleRule) { |
| 141 | readRule(rule, dest) |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | // Don't add media rule to computed styles |
| 146 | // if no styles were actually applied |
| 147 | if (Object.keys(dest).length > 0) { |
| 148 | computed[key] = dest |
| 149 | } |
no test coverage detected