To extract properties from your uploaded CSS text, one approach is to add the text to the document stylesheets and access all properties using document.styleSheets
and cssRules
.
When adding a new stylesheet, it's crucial not to overwrite the existing app/page styles. Thus, disabling the new stylesheet or style rules becomes necessary.
Demonstration: load content into <style>
element and disable it
/**
* Here's some example CSS content
* obtained through fileReader/input
*/
let cssText = `
/* latin */
@font-face {
font-family: 'Poppins';
font-style: italic;
font-weight: 200;
font-display: swap;
src: url(https://fonts.gstatic.com/s/poppins/v20/pxiDyp8kv8JHgFVrJJLmv1pVF9eOYktMqg.woff2) format('woff2');
}
/* latin */
@font-face {
font-family: 'Poppins';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/poppins/v20/pxiGyp8kv8JHgFVrJJLucHtAOvWDSA.woff2) format('woff2');
}
body {
font-family: Poppins;
font-style: italic;
background: red;
}
`;
/**
* Load disabled
* style element with
* new css rules for parsing
*/
cssTmp.textContent = cssText;
/**
* Retrieve temporary stylesheet by id
* and deactivate it
* to avoid altering the UI style of the application
*/
let stylesheetTmp = [...document.styleSheets].filter((style) => {
return style.ownerNode.id == "cssTmp";
})[0];
// Disable stylesheet
stylesheetTmp.disabled = true;
/**
* Access @font-face rules
*/
let rules = [...stylesheetTmp.cssRules];
let fontProps = [];
rules.forEach((rule) => {
let type = rule.type;
// Type 5 represents @font-face
if (type === 5) {
let fontFamily = rule.style.getPropertyValue("font-family");
let fontStyle = rule.style.getPropertyValue("font-style");
let fontWeight = rule.style.getPropertyValue("font-weight");
fontProps.push({
fontFamily: fontFamily,
fontWeight: fontWeight,
fontStyle: fontStyle
});
}
});
console.log(fontProps);
<style id="cssTmp"></style>
<p>Test</p>
Functionality Breakdown
- Create a
<style>
element with a unique ID like "cssTmp"
- Fill this element with the imported CSS content
cssTmp.textContent = cssText
- Select the stylesheet by filtering all document stylesheets based on the specified ID:
let stylesheetTmp = [...document.styleSheets].filter((style) => {
return style.ownerNode.id == "cssTmp";
})[0];
- Deactivate this stylesheet:
stylesheetTmp.disabled = true;
- Iterate through cssRules
To make the styles rules iterable, employ the spread operator or use Array.from()
method.
let rules = [...stylesheetTmp.cssRules];
By filtering out @font-face
rules based on their type - which is "5", you can explore all data within the rule object by including a console.log(rule)
.
You might require additional property values such as font styles (regular/italic) - these details can be organized in an array of objects created beforehand.
The retrieved data could then populate options within a <select>
element.