Skip to content

Instantly share code, notes, and snippets.

@ryankuykendall
Last active November 18, 2020 03:42
Show Gist options
  • Save ryankuykendall/38f9b8e34d219196b24dcc79121b2d8f to your computer and use it in GitHub Desktop.
Save ryankuykendall/38f9b8e34d219196b24dcc79121b2d8f to your computer and use it in GitHub Desktop.
Helper snippets for working with Element attributes and CSSOM
// Assumes selected node in Chrome Developer tools
[...$0.getAttributeNames()].map((name) => [name, $0.getAttribute(name)]);
// Make sure to look through all of these (especially the ones related to form field validation)
// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
const PSEUDO_SELECTOR_REGEXP = /:(link|visited|hover|active|before|focus|focus-within|enabled|disabled)\b/gm;
[...document.styleSheets].map(({rules}) => {
return [...rules];
})
.flatMap(rule => rule)
.filter(rule => rule instanceof CSSStyleRule)
.filter(rule => PSEUDO_SELECTOR_REGEXP.test(rule.selectorText))
.reduce((distribution, rule) => {
const selector = rule.selectorText;
const matches = selector.match(PSEUDO_SELECTOR_REGEXP);
matches.forEach((pseudo) => {
if (!distribution.has(pseudo)) {
distribution.set(pseudo, []);
}
distribution.get(pseudo).push(rule);
});
return distribution;
}, new Map());
[...document.styleSheets].map(({rules}) => {
return [...rules];
})
.flatMap(rule => rule)
.filter(rule => rule instanceof CSSFontFaceRule);
// TODO (ryan)
[...document.styleSheets].map(({rules}) => {
return [...rules];
})
.flatMap(rule => rule)
.filter(rule => rule instanceof CSSKeyframesRule);
// Make sure to look through all of these (especially the ones related to form field validation)
// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
const PSEUDO_SELECTOR_REGEXP = /:(link|visited|hover|active|before|focus|focus-within|enabled|disabled)\b/;
[...document.styleSheets].map(({rules}) => {
return [...rules];
})
.flatMap(rule => rule)
.filter(rule => rule instanceof CSSStyleRule)
.filter(rule => PSEUDO_SELECTOR_REGEXP.test(rule.selectorText));
// Iterate through all of the style sheets and collect all of the CSS Style Rules
[...document.styleSheets].map(({rules}) => {
return [...rules];
}).flatMap(rule => rule);
const getComputedStylesSimple = (element) => {
const properties = Object.entries(window.getComputedStyle(element))
.map(([prop, value]) => [prop, value, parseInt(prop, 10)])
.filter(([prop, value, index]) => isNaN(index))
.map((property) => property.slice(0, 2));
return new Map(properties);
};
const diffStyles = (element, master = document.documentElement) => {
const elementStyles = getComputedStylesSimple(element);
const masterStyles = getComputedStylesSimple(element);
return [...elementStyles.keys()].reduce((diff, name) => {
const masterValue = masterStyles.get(name);
const elementValue = elementStyles.get(name);
if (elementValue != masterValue) {
diff[name] = elementValue;
}
return diff;
}, {});
};
// This is not quite right.
const dummy = document.createElement(`dummy-${Date.now()}`);
document.body.appendChild(dummy);
const diff = diffStyles(document.body, dummy);
console.log("diff", JSON.stringify(diff, null, 2));
dummy.remove();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment