Css Parser Ver2
var _StyleRoot_HtmlIndex = 1;
var _StylePropertyValueBlank = str => str.replace(/(\s)/g, '<span class="blank">$1</span>');
var _StylePropertyValueColor = str => {
    var key = ['transparent', 'aqua', 'black', 'blue', 'fuchsia', 'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'purple', 'red', 'silver', 'teal', 'white', 'yellow', 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'navyblue', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen'];
    var hex = [8, 6, 4, 3].map(n => `[\\da-f]{${n}}`);
 
    var reg = new RegExp(`((?:rgba?|hsla?)\\(.*?\\)|#(?:${hex.join('|')})|${key.join('|')})`, 'g');
 
    return str.replace(reg, '<span style="--tgtcolor: $1" class="inline-color">$1</span>');
};
var StyleRoot = class {
    constructor(string) {
        this.tree = [];
        this.properties = [];
        this.init(string);
        this.name = '__root__';
    }
    init(string) {
        var str = string
            .replace(/\/\*[\s\S]*?\*\//g, '')
            .replace(/@(\S+) ([\S ]+?);/g, (_, identifier, rule) => {
                this.tree.push(new StyleInlineAtRule(identifier, rule));
                return '';
        });
        var begin = 0, end = 0, begin_i = 0, end_i = 0, name;
        for(var b of str.matchAll(/(?<begin>\{)|(?<end>\})/g)) {
            if(b.groups?.begin) {
                if((begin++) == end) {
                    name = str.slice(end_i, b.index).trim();
                    begin_i = b.index;
                }
            }else {
                end++;
                if(begin == end) {
                    var v = str.slice(begin_i + 1, b.index);
                    var m = name.match(/@(\S+)(?: (.+)|)/);
                    var s = m ? new StyleAtRule(v, m[1], m[2] || '') : new StyleBlock(v, name);
                    var prop = v.split(';')
                        .map(v => v.trim().match(/^(\S+?)\:([\s\S]+)/))
                        .filter(v => v)
                        .reduce((p, v) => (p[v[1]] = v[2], p), {});
                    var props = Object.keys(prop).sort().map(k => new StyleProperty(k, prop[k]));
                    s.properties.push(...props);
                    this.tree.push(s);
                    s.tree.length && (s.properties = []);
                    begin = end = 0;
                    end_i = b.index + 1;
                }
            }
        }
    }
    toString(indent=4, lv=0) {
        var ind = ' '.repeat(indent);
        if(this.label) {
            var cont = (this.tree.length ? this.tree : this.properties).map(v => v.toString(indent, lv + 1)).join('\n');
            return `${this.label.toString(indent, lv)} \{\n${cont}\n${ind.repeat(lv)}\}`;
        }
        return this.tree.map(v => `${ind.repeat(lv)}${v.toString(indent, lv)}`).join('\n');
    }
    html(indent=4, lv=0, property_cb) {
        var ind = ' '.repeat(indent);
        var wrap = document.createElement('pre');
        if(this.label) {
            wrap.dataset.lv = lv;
            var title = document.createElement('div');
            title.innerHTML = `<div class="_wrap">${this.label.toString(indent, lv)} <span class="begin-bracket">{</span></div>`;
            title.classList.add('label');
            title.dataset.line = _StyleRoot_HtmlIndex++;
            title.dataset.type = this.name;
            wrap.appendChild(title);
            var box = document.createElement('div');
            box.classList.add('box');
            title.addEventListener('click', e => {
                e.currentTarget.classList.toggle('hidden_mode');
            });
            wrap.appendChild(box);
 
            (this.tree.length ? this.tree : this.properties)
                .forEach(v => {
                    var x = v.html(indent, lv + 1, property_cb);
                    box.appendChild(x);
                });
 
            var endB = document.createElement('span');
            endB.innerText = `${ind.repeat(lv)}}`;
            endB.classList.add('end-bracket');
            endB.dataset.line = _StyleRoot_HtmlIndex++;
            wrap.appendChild(endB);
 
        }else {
            _StyleRoot_HtmlIndex = 1;
            wrap = document.createElement('div');
            var shadow = wrap.shadowRoot || wrap.attachShadow({mode: 'open'});
            var style = document.createElement('style');
            style.innerHTML = `
                :host {-webkit-text-size-adjust: 100%; border: 1px solid #ccc; border-width: 1px 1px 0; color: #333; font-family: sans-serif; font-size: .75em;}
                :host pre {font-family: Courier, monospace; margin: 0; padding: 0; white-space: pre-wrap; word-break: break-all;}
                :host .label, :host .box .property {cursor: pointer; transition: background .25s;}
                :host .label:hover {background: #f8f8f8;}
                :host .box .property:hover {background: #fff8f0;}
 
                :host .box .property .inline-color {align-items: center; display: inline-flex;}
                :host .box .property .inline-color::before {background: var(--tgtcolor); border: 1px solid #aaa; content: ''; display: inline-block; height: 0.6em; width: 0.6em;}
 
                :host .label > ._wrap > .begin-bracket::after {-webkit-mask-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%20id%3D%22Layer_1%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%220%200%20512%20512%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cg%3E%0A%3Cg%3E%0A%3Cpath%20d%3D%22M491.841%2C156.427c-19.471-45.946-51.936-85.013-92.786-112.637C358.217%2C16.166%2C308.893-0.007%2C256%2C0c-35.254-0.002-68.946%2C7.18-99.571%2C20.158C110.484%2C39.63%2C71.416%2C72.093%2C43.791%2C112.943C16.167%2C153.779-0.007%2C203.104%2C0%2C256c-0.002%2C35.255%2C7.181%2C68.948%2C20.159%2C99.573c19.471%2C45.946%2C51.937%2C85.013%2C92.786%2C112.637C153.783%2C495.834%2C203.107%2C512.007%2C256%2C512c35.253%2C0.002%2C68.946-7.18%2C99.571-20.158c45.945-19.471%2C85.013-51.935%2C112.638-92.785C495.834%2C358.22%2C512.007%2C308.894%2C512%2C256C512.002%2C220.744%2C504.819%2C187.052%2C491.841%2C156.427z%20M460.413%2C342.257c-16.851%2C39.781-45.045%2C73.724-80.476%2C97.677c-35.443%2C23.953-78.02%2C37.926-123.936%2C37.933c-30.619-0.002-59.729-6.218-86.255-17.454c-39.781-16.85-73.724-45.044-97.677-80.475C48.114%2C344.495%2C34.14%2C301.917%2C34.133%2C256c0.002-30.62%2C6.219-59.731%2C17.454-86.257c16.851-39.781%2C45.045-73.724%2C80.476-97.677C167.506%2C48.112%2C210.084%2C34.139%2C256%2C34.132c30.619%2C0.002%2C59.729%2C6.218%2C86.255%2C17.454c39.781%2C16.85%2C73.724%2C45.044%2C97.677%2C80.475c23.953%2C35.443%2C37.927%2C78.02%2C37.934%2C123.938C477.864%2C286.62%2C471.648%2C315.731%2C460.413%2C342.257z%22%2F%3E%0A%3C%2Fg%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%3Cg%3E%0A%3Cpath%20d%3D%22M398.826%2C242.084L213.278%2C119.006c-7.686-5.098-18.049-3-23.147%2C4.685c-5.099%2C7.685-3%2C18.049%2C4.685%2C23.147l164.568%2C109.163L194.815%2C365.164c-7.686%2C5.098-9.784%2C15.461-4.685%2C23.147c5.099%2C7.686%2C15.461%2C9.784%2C23.147%2C4.685l185.548-123.08c4.652-3.086%2C7.468-8.333%2C7.468-13.916S403.478%2C245.17%2C398.826%2C242.084z%22%2F%3E%0A%3C%2Fg%3E%0A%3C%2Fg%3E%0A%3C%2Fsvg%3E); -webkit-mask-position: center; -webkit-mask-repeat: no-repeat; align-items: center; background: #aaa; content: ''; display: inline-block; height: 0.8em; transform: rotate(90deg); transition: background .2s, transform .2s; width: 0.8em;}
                :host .label.hidden_mode > ._wrap > .begin-bracket::after {background: #b01; transform: none;}
 
                :host .label.hidden_mode + .box {font-size: 0; height: 0; opacity: 0;}
 
                :host [data-type] {font-weight: bold;}
                :host [data-type="at_rule"] {color: #14743f;}
                :host [data-type="style_block"] {color: #7436c2;}
                :host .begin-bracket, :host .end-bracket {color: #781515; font-weight: bold;}
                :host .property-name {color: #3270bc;}
 
                :host [data-line] {border-bottom: 1px solid #ccc; display: flex;}
                :host [data-line]::before {background: #f8f0ff; color: #333; content: attr(data-line); display: block; font-weight: bold; min-width: 2em; overflow: hidden; margin: 0 .25em 0 0; padding: 0 .25em 0 0; text-align: right; width: 2em;}
            `;
            shadow.appendChild(style);
            this.tree.forEach(v => shadow.appendChild( v.html(indent, lv, property_cb) ));
        }
        return wrap;
    }
};
 
var StyleBlock = class extends StyleRoot {
    constructor(string, label) {
        super(string);
        this.label = new StyleSelector(label);
        this.name = 'style_block';
    }
};
var StyleAtRule = class extends StyleRoot {
    constructor(string, identifier, rule) {
        super(string);
        this.identifier = identifier.trim();
        this.rule = rule.trim();
        this.name = 'at_rule';
    }
    get label() {
        return new StyleSelector(`@${this.identifier} ${this.rule}`);
    }
};
var StyleInlineAtRule = class {
    constructor(identifier, rule) {
        this.identifier = identifier.trim();
        this.rule = rule.trim();
        this.name = 'at_rule';
    }
    toString() {
        return `@${this.identifier} ${this.rule};`;
    }
    html() {
        var wrap = document.createElement('pre');
        wrap.dataset.lv = 0;
        var title = document.createElement('div');
        title.classList.add('label');
        title.innerHTML = this.toString();
        title.dataset.line = _StyleRoot_HtmlIndex++;
        title.dataset.type = this.name;
        wrap.appendChild(title);
        return wrap;
    }
};
var StyleProperty = class {
    constructor(property, value) {
        this.property = property.trim();
        var temp = '';
        var list = value
            .split(/([a-z\-]+\(.+?\)|[a-z\-]+\(\s*?'.+?'\s*?\)|[a-z\-]+\(\s*?".+?"\s*?\)|'.*?'|".*?"|,)/)
            .map(v => v.replace(/\s+/g, ' '))
            .reduce((p, v) => {
                temp = (v.trim() != ',') ? (temp + v) : (p.push(temp.trim()), '');
                return p;
            }, []);
        temp && list.push(temp.trim());
        this.value = list.filter(v => v);
    }
    toString(indent=4, lv=0) {
        var ind = ' '.repeat(indent);
        return `${ind.repeat(lv)}${this.property}: ${
            this.value.length == 1
                ? this.value[0]
                : '\n' + ind.repeat(lv + 1) + this.value.join(',\n' + ind.repeat(lv + 1))
        };`;
    }
    html(indent=4, lv=0, property_cb) {
        var ind = ' '.repeat(indent);
        var prop = document.createElement('div');
        prop.classList.add('property');
        prop.dataset.name = this.property;
        prop.dataset.line = _StyleRoot_HtmlIndex++;
        prop.innerHTML = `<div class="_wrap">${ind.repeat(lv)}<span class="property-name">${this.property}</span>: ${
            this.value.length == 1
                ? _StylePropertyValueColor(this.value[0])
                : '\n' + ind.repeat(lv + 1) + this.value.map(_StylePropertyValueColor).join(',\n' + ind.repeat(lv + 1))
        };</div>`;
        property_cb && prop.addEventListener('click', property_cb);
        return prop;
    }
};
var StyleSelector = class {
    constructor(string) {
        var temp = '', list = string
            .split(/(\:[a-z\-]+\(.+?\)|\[[a-z\-]+(?:(?:\^|\*|\$|)=".+?"(?: [a-zA-Z])|)\]|,)/)
            .map(v => v.trimStart())
            .reduce((p, v) => {
                temp = (v != ',') ? (temp + v) : (p.push(temp.trim()), '');
                return p;
            }, []);
        temp && list.push(temp.trim());
        this.sel = list.map(v => new StyleSelectorKey(v));
    }
    toString(indent=4, lv=0) {
        var ind = ' '.repeat(indent);
        return this.sel.map(v => ind.repeat(lv) + v).join(',\n');
    }
};
var StyleSelectorKey = class {
    constructor(string) {
        this.string = string;
    }
    toString() {
        return this.string;
    }
};
 
/*
var style = new StyleRoot(`
 
@charset "utf-8";
@import url(http://example.com/style.css);
@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"),
       url("/fonts/OpenSans-Regular-webfont.woff") format("woff");
}
@keyframes slide {
  0%, 30% {
    transform: translateX(0%);
  }
  100% {
    transform: translateX(100%);
  }
}
@supports (display: flex) and (position: sticky) {
    @media screen and (min-width: 900px) {
        article, .article {
            display: flex;
            position: sticky;
        }
    }
}
body > .box li.item [href*="article"], body > .box li.item a.article {
    color: #901; color:#000;
    box-shadow: inset -1px -1px 3px rgba(255, 255, 255, .9),
        inset -1px -1px 5px rgba(255, 225, 200, .9),
        1px 1px 3px #aaa;
}
a
{color:red}li a.target{color:#000}
 
`);
*/
// console.log(style + '\n', style);
// document.body.innerHTML = '';
// document.body.appendChild( style.html() );
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License