eruda3 / src /Elements /CssStore.js
soiz1's picture
Migrated from GitHub
271613e verified
import each from 'licia/each'
import sortKeys from 'licia/sortKeys'
function formatStyle(style) {
const ret = {}
for (let i = 0, len = style.length; i < len; i++) {
const name = style[i]
if (style[name] === 'initial') continue
ret[name] = style[name]
}
return sortStyleKeys(ret)
}
const elProto = Element.prototype
let matchesSel = function () {
return false
}
if (elProto.webkitMatchesSelector) {
matchesSel = (el, selText) => el.webkitMatchesSelector(selText)
} else if (elProto.mozMatchesSelector) {
matchesSel = (el, selText) => el.mozMatchesSelector(selText)
}
export default class CssStore {
constructor(el) {
this._el = el
}
getComputedStyle() {
const computedStyle = window.getComputedStyle(this._el)
return formatStyle(computedStyle)
}
getMatchedCSSRules() {
const ret = []
each(document.styleSheets, (styleSheet) => {
try {
// Started with version 64, Chrome does not allow cross origin script to access this property.
if (!styleSheet.cssRules) return
} catch {
return
}
each(styleSheet.cssRules, (cssRule) => {
let matchesEl = false
// Mobile safari will throw DOM Exception 12 error, need to try catch it.
try {
matchesEl = this._elMatchesSel(cssRule.selectorText)
} catch {
// No op
}
if (!matchesEl) return
ret.push({
selectorText: cssRule.selectorText,
style: formatStyle(cssRule.style),
})
})
})
return ret
}
_elMatchesSel(selText) {
return matchesSel(this._el, selText)
}
}
function sortStyleKeys(style) {
return sortKeys(style, {
comparator: (a, b) => {
const lenA = a.length
const lenB = b.length
const len = lenA > lenB ? lenB : lenA
for (let i = 0; i < len; i++) {
const codeA = a.charCodeAt(i)
const codeB = b.charCodeAt(i)
const cmpResult = cmpCode(codeA, codeB)
if (cmpResult !== 0) return cmpResult
}
if (lenA > lenB) return 1
if (lenA < lenB) return -1
return 0
},
})
}
function cmpCode(a, b) {
a = transCode(a)
b = transCode(b)
if (a > b) return 1
if (a < b) return -1
return 0
}
function transCode(code) {
// - should be placed after lowercase chars.
if (code === 45) return 123
return code
}