forked from Kholid060/inspect-css
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgetAppliedCSS.js
More file actions
129 lines (95 loc) · 3.11 KB
/
getAppliedCSS.js
File metadata and controls
129 lines (95 loc) · 3.11 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* eslint-disable */
function extractCSS(rules) {
const result = { css: '', hover: '' };
rules.forEach(({ selectorText, style }) => {
if (/\:\:before|\:\:after|\*/g.test(selectorText)) return;
if (/\:hover/g.test(selectorText)) {
result.hover += style.cssText;
return;
}
result.css += style.cssText;
});
return result;
}
function removeDuplicateCSS(css) {
const seen = new Set();
const cssArray = css.split(';');
const filteredCssArray = cssArray.filter((property) => {
if (property === '') return;
const [key] = property.split(':');
const duplicate = seen.has(key.trim());
seen.add(key.trim());
return !duplicate;
});
return filteredCssArray.map((cssStr) => cssStr.trim()).join(';\n');
}
function getNumber(text) {
const number = +text.replace(/\D/g, '');
return number;
}
function filterRules(element, rules) {
const filteredRules = rules.filter(({ selectorText }) => element.matches(selectorText));
return filteredRules;
}
class GetAppliedCSS {
constructor(el) {
// el.matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector || el.oMatchesSelector;
this.element = el;
}
get rules() {
const slice = Function.call.bind(Array.prototype.slice);
const rules = Array.from(document.styleSheets).reduce((rulesArr, sheet) => {
try {
if (sheet?.cssRules) {
return rulesArr.concat(slice(sheet.cssRules));
}
} catch {
return rulesArr;
}
}, []);
return rules;
}
all() {
const { css: mediaCSS, hover: mediaHover } = this.mediaQueryCSS();
const { css: styleCSS, hover: styleHover } = this.css();
const inlineCSS = this.inlineCSS();
const css = removeDuplicateCSS(inlineCSS + mediaCSS + styleCSS);
const hover = removeDuplicateCSS(mediaHover + styleHover);
return { css, hover };
}
inlineCSS() {
const styleAttribute = this.element.getAttribute('style');
if (!styleAttribute) return '';
return styleAttribute.endsWith(';') ? styleAttribute : `${styleAttribute};`;
}
mediaQueryCSS() {
const mediaQueries = this.rules.filter(({ conditionText, media }) => media && window.matchMedia(conditionText).matches && getNumber(conditionText));
const mediaQueriesSorted = mediaQueries.sort((a, b) => {
const aMedia = getNumber(a.conditionText);
const bMedia = getNumber(b.conditionText);
if (aMedia > bMedia) return -1;
if (bMedia > aMedia) return 1;
return 0;
});
const cssRules = mediaQueriesSorted.reduce(
(result, media) => {
if (media.cssRules) {
const filteredRules = filterRules(this.element, Array.from(media.cssRules));
const { css, hover } = extractCSS(filteredRules);
result.css += css;
result.hover += hover;
return result;
}
return result;
},
{ css: '', hover: '' },
);
return cssRules;
}
css() {
const filteredRules = filterRules(this.element, this.rules);
const result = extractCSS(filteredRules);
return result;
}
}
export default GetAppliedCSS;