Last active
July 13, 2019 05:43
-
-
Save ryankuykendall/479200b8f45d5580d82313e68fcf4b07 to your computer and use it in GitHub Desktop.
Condenser for StylePropertyMap (element.computedStyleMap())
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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