The goal of this specification is to allow authors access to the engine's parser. There are two over-arching use cases:
var background = window.cssParse.rule("background: green");
console.log(background.styleMap.get("background").value) // "green"
var styles = window.cssParse.ruleSet(".foo { background: green; margin: 5px; }");
console.log(styles.length) // 5
console.log(styles[0].styleMap.get("margin-top").value) // 5
console.log(styles[0].styleMap.get("margin-top").type) // "px"
const style = fetch("style.css")
.then(response=>CSS.parseStylesheet(response.body));
style.then(console.log);
/* example of the object once we have it more refined */
);
Here is an example of some JS code that is wanting to parse out various CSS types and also seperate out the values from their units.
function parseValues(value,propertyName) {
// Trim value on the edges
value = value.trim();
// Normalize letter-casing
value = value.toLowerCase();
// Map colors to a standard value (eg: white, blue, yellow)
if (isKeywordColor(value)) { return "<color-keyword>"; }
value = value.replace(/[#][0-9a-fA-F]+/g, '#xxyyzz');
// Escapce identifiers containing numbers
var numbers = ['ZERO','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE'];
value = value.replace(
/([_a-z][-_a-z]|[_a-df-z])[0-9]+[-_a-z0-9]*/g,
s=>numbers.reduce(
(m,nstr,nint)=>m.replace(RegExp(nint,'g'),nstr),
s
)
);
// Remove any digits eg: 55px -> px, 1.5 -> 0.0, 1 -> 0
value = value.replace(/(?:[+]|[-]|)(?:(?:[0-9]+)(?:[.][0-9]+|)|(?:[.][0-9]+))(?:[e](?:[+]|[-]|)(?:[0-9]+))?(%|e[a-z]+|[a-df-z][a-z]*)/g, "$1");
value = value.replace(/(?:[+]|[-]|)(?:[0-9]+)(?:[.][0-9]+)(?:[e](?:[+]|[-]|)(?:[0-9]+))?/g, " <float> ");
value = value.replace(/(?:[+]|[-]|)(?:[.][0-9]+)(?:[e](?:[+]|[-]|)(?:[0-9]+))?/g, " <float> ");
value = value.replace(/(?:[+]|[-]|)(?:[0-9]+)(?:[e](?:[+]|[-]|)(?:[0-9]+))/g, " <float> ");
value = value.replace(/(?:[+]|[-]|)(?:[0-9]+)/g, " <int> ");
// Unescapce identifiers containing numbers
value = numbers.reduce(
(m,nstr,nint)=>m.replace(RegExp(nstr,'g'),nint),
value
)
// Remove quotes
value = value.replace(/('|‘|’|")/g, "");
//
switch(propertyName) {
case 'counter-increment':
case 'counter-reset':
// Anonymize the user identifier
value = value.replace(/[-_a-zA-Z0-9]+/g,' <custom-ident> ');
break;
case 'grid':
case 'grid-template':
case 'grid-template-rows':
case 'grid-template-columns':
case 'grid-template-areas':
// Anonymize line names
value = value.replace(/\[[-_a-zA-Z0-9 ]+\]/g,' <line-names> ');
break;
case '--var':
// Replace (...), {...} and [...]
value = value.replace(/[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, " <parentheses-block> ");
value = value.replace(/[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, " <parentheses-block> ");
value = value.replace(/\[(?:[^()]+|\[(?:[^()]+|\[(?:[^()]+|\[(?:[^()]+|\[(?:[^()]*)\])*\])*\])*\])*\]/g, " <curly-brackets-block> ");
value = value.replace(/\[(?:[^()]+|\[(?:[^()]+|\[(?:[^()]+|\[(?:[^()]+|\[(?:[^()]*)\])*\])*\])*\])*\]/g, " <curly-brackets-block> ");
value = value.replace(/\{(?:[^()]+|\{(?:[^()]+|\{(?:[^()]+|\{(?:[^()]+|\{(?:[^()]*)\})*\})*\})*\})*\}/g, " <square-brackets-block> ");
value = value.replace(/\{(?:[^()]+|\{(?:[^()]+|\{(?:[^()]+|\{(?:[^()]+|\{(?:[^()]*)\})*\})*\})*\})*\}/g, " <square-brackets-block> ");
break;
}
return value.trim();
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4