Skip to content

Instantly share code, notes, and snippets.

@ryankuykendall
Last active July 13, 2019 05:43
Show Gist options
  • Save ryankuykendall/479200b8f45d5580d82313e68fcf4b07 to your computer and use it in GitHub Desktop.
Save ryankuykendall/479200b8f45d5580d82313e68fcf4b07 to your computer and use it in GitHub Desktop.
Condenser for StylePropertyMap (element.computedStyleMap())
// WIP: Work in progress!!!
// TODO (ryan):
// 1. Further classify style attributes (HTML vs. SVG vs. Condensible)
// 2. Create dispatch table/handlers for special cases (e.g., column-*, where if column-count == 'auto',
// drop all column styles. Or for attrs like background-image: url(...), go fetch the image and
// inline it as a Data URL.
condenser = (() => {
const Vendor = {
WebKit: 'webkit'
};
const distributeStyles = (styleMap) => {
// List of properties that cannot be stemmed or condensed.
// Dashed attrs that are never condensed in root attr (keep this alphabetized
// For Nevers, if it is shared, put it in HTML
const neverCondensiblesForHTML = new Set([
'alignment-baseline',
'align-content',
'align-items',
'align-self',
'backface-visibility',
'background-size',
'box-shadow',
'box-sizing',
'caption-side', // Drop if element is not a CAPTION
'caret-color', // Drop if element is not an INPUT or TEXTAREA
'empty-cells',
'letter-spacing',
'line-height',
'object-fit', // Drop if element is not an IMG
'object-position', // Drop if element is not an IMG
'offset-distance', // Requires presense of offset-path
'offset-path',
'offset-rotate', // Requires presense of offset-path
'perspective-origin',
'pointer-events',
'shape-margin',
'shape-outside',
'shape-rendering',
'tab-size',
'text-align',
'text-indent',
'text-overflow',
'text-rendering',
'text-shadow',
'text-transform',
'vertical-align',
'white-space',
'will-change',
'word-spacing',
'word-wrap',
'writing-mode',
'z-index',
]);
const neverCondensiblesForSVG = new Set([
'baseline-shift',
'color-interpolation',
'color-interpolation-filters',
'color-rendering',
'dominant-baseline',
'flood-color',
'flood-opacity',
'r',
'rx',
'ry',
'text-anchor',
'x',
'y',
]);
return [...styleMap.keys()].
filter(attr => (/^--/).test(attr) == false). // filter out CSS Variables for now
map(attr => {
let [root, ...attrItems] = attr.split(/-/);
if (root.length == 0 && attrItems[0] == Vendor.WebKit) {
root = attrItems.shift();
}
let rootStyle;
try {
rootStyle = styleMap.has(root) && styleMap.get(root).toString();
} catch(error) {
console.error(error);
};
return [root, rootStyle, attr, styleMap.get(attr).toString(), attrItems];
}).
reduce((distribution, [root, rootStyle, ...details]) => {
const [attr, attrStyle] = details;
if (neverCondensiblesForHTML.has(attr)) {
distribution.never.html.push(details);
} else if (neverCondensiblesForSVG.has(attr)) {
distribution.never.svg.push(details);
} else if (root == attr) {
// If it is a single word property, it cannot be condensed.
distribution.noncondensible.push(details);
} else if (Vendor.WebKit == root) {
distribution.vendor.webkit.push(details);
} else if (rootStyle) {
if (!distribution.condensible.has(root)) {
distribution.condensible.set(root, {style: rootStyle, attrs: []});
}
distribution.condensible.get(root).attrs.push(details);
} else {
switch(attrStyle) {
case 'auto':
distribution.auto.push(details);
break;
case 'normal':
distribution.normal.push(details);
break;
case 'none':
distribution.none.push(details);
break;
default:
distribution.noncondensible.push(details);
break;
};
}
return distribution;
},
{
auto: [],
normal: [],
none: [],
never: {
html: [],
svg: []
},
condensible: new Map(),
noncondensible: [],
vendor: {
webkit: [],
}
}); /** Should we then recurse on attrItems e.g., root = [root, attrItems.shift()].join('-'); */
};
return (element, handler) => {
const response = {};
const styleMap = element.computedStyleMap();
const distribution = distributeStyles(styleMap);
console.info("Never HTML");
console.table(distribution.never.html);
console.info("Never SVG");
console.table(distribution.never.svg);
console.info("Vendor WebKit");
console.table(distribution.vendor.webkit);
console.info("Auto")
console.table(distribution.auto);
console.info("Normal")
console.table(distribution.normal);
console.info("None")
console.table(distribution.none);
console.info("Noncondensible");
console.table(distribution.noncondensible);
handler.call(null, response);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment