File size: 2,385 Bytes
271613e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
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
}
|