I have written the following Tampermonkey/Greasemonkey script. I am trying to obtain a list of all CSS rules for a page; across all stylesheets. As of now, I am just iterating over everything. Is there a faster way to obtain the rules? Also, I feel that there is a more efficient way of converting the CSS text to an object, but right now, all I can think to do is to tokenize the property-value pairs by spliting.// ==UserScript==// @name         Dump CSS Rules// @namespace    example.css.rules// @version      0.1// @description  Print out all the CSS rules// @author       You// @grant        GM_log// ==/UserScript==(function() {    /*jslint browser: true*/ /*global  $*/    'use strict';    function getRules() {        var rulesList = [];        searchStyleSheets(rulesList);        return rulesList;    }    function searchStyleSheets(rulesList) {        var styleSheets = document.styleSheets || [];        for (var i = 0; i < styleSheets.length; i++) {            // CSSStyleSheet            searchRulesList(styleSheets[i], undefined, undefined, undefined, rulesList);        }    }    function searchRulesList(styleSheet, href, media, rules, rulesList) {        // CSSRuleList        var rules = rules || styleSheet.rules || styleSheet.cssRules || [];        var href = href || styleSheet.href || '';        var media = media || styleSheet.media.mediaText || '';        for (var i = 0; i < rules.length; i++) {            addRule(rules[i], href, media, rulesList);        }    }    function addRule(rule, href, media, rulesList) {        // CSSMediaRule        if (rule.type === 4) {            var rules = rule.rules || rule.cssRules || [];            var href = rule.parentStyleSheet.href || '';            var media = rule.media.mediaText || '';            searchRulesList(rule, href, media, rules, rulesList);        } else {            // CSSStyleRule            rulesList.push({                'selector' : rule.selectorText,                'css'      : cssTextToObject(getCssText(rule), rule),                'href'     : href,                //'self'   : rule,                'media'    : media,                'type'     : rule.type            });        }    }    function getCssText(rule) {        return (function(text) {            return text.substr(text.indexOf('{')) ;        }(rule.cssText ? rule.cssText : rule.style.cssText));    }    function cssTextToObject(cssText, rule) {        var m = cssText.match(/^\{(?:[ ]*)?(.*)(?:[ ]*)?\}$/);        if (m != null) {            var obj = {};            if (m.length === 2) {                var properties = m[1].split(/(?:[ ]*)?[;](?:[ ]*)?/);                for (var i = 0; i < properties.length; i++) {                    var pair = properties[i].split(/(?:[ ]*)?[:](?:[ ]*)?/);                    if (pair.length === 2) {                        obj[pair[0]] = pair[1];                    }                }            }            return obj;        } else {            return cssText;        }    }    GM_log(JSON.stringify(getRules(), undefined, '    '));}())Here are the rules for this page:[    {        selector: .MathJax_Hover_Frame,        css: {            border-radius: 0.25em,            box-shadow: rgb(136, 51, 170) 0px 0px 15px,            -webkit-box-shadow: rgb(136, 51, 170) 0px 0px 15px,            display: inline-block,            position: absolute,            border: 1px solid rgb(170, 102, 221) !important        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_Hover_Arrow,        css: {            position: absolute,            width: 15px,            height: 11px,            cursor: pointer        },        href: ,        media: ,        type: 1    },    {        selector: #MathJax_About,        css: {            position: fixed,            left: 50%,            width: auto,            text-align: center,            border: 3px outset,            padding: 1em 2em,            color: black,            cursor: default,            font-family: message-box,            font-size: 120%,            font-style: normal,            text-indent: 0px,            text-transform: none,            line-height: normal,            letter-spacing: normal,            word-spacing: normal,            word-wrap: normal,            white-space: nowrap,            float: none,            z-index: 201,            border-radius: 15px,            box-shadow: rgb(128, 128, 128) 0px 10px 20px,            -webkit-box-shadow: rgb(128, 128, 128) 0px 10px 20px,            background-color: rgb(221, 221, 221)        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_Menu,        css: {            position: absolute,            color: black,            width: auto,            padding: 2px,            border: 1px solid rgb(204, 204, 204),            margin: 0px,            cursor: default,            font-style: normal,            font-weight: normal,            font-size: 12px,            font-family: 'Segoe UI',            font-variant: normal,            text-align: left,            text-indent: 0px,            text-transform: none,            line-height: normal,            letter-spacing: normal,            word-spacing: normal,            word-wrap: normal,            white-space: nowrap,            float: none,            z-index: 201,            box-shadow: rgb(128, 128, 128) 0px 10px 20px,            -webkit-box-shadow: rgb(128, 128, 128) 0px 10px 20px,            background-color: white        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuItem,        css: {            padding: 2px 2em,            background: transparent        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuArrow,        css: {            position: absolute,            right: 0.5em,            color: rgb(102, 102, 102)        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuActive .MathJax_MenuArrow,        css: {            color: white        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuArrow.RTL,        css: {            left: 0.5em,            right: auto        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuCheck,        css: {            position: absolute,            left: 0.7em        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuCheck.RTL,        css: {            right: 0.7em,            left: auto        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuRadioCheck,        css: {            position: absolute,            left: 1em        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuRadioCheck.RTL,        css: {            right: 1em,            left: auto        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuLabel,        css: {            padding: 2px 2em 4px 1.33em,            font-style: italic        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuRule,        css: {            border-top-width: 1px,            border-top-style: solid,            border-top-color: rgb(204, 204, 204),            margin: 4px 1px 0px        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuDisabled,        css: {            color: graytext        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_MenuActive,        css: {            color: highlighttext,            background-color: highlight        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_Menu_Close,        css: {            position: absolute,            width: 31px,            height: 31px,            top: -15px,            left: -15px        },        href: ,        media: ,        type: 1    },    {        selector: #MathJax_Zoom,        css: {            position: absolute,            overflow: auto,            display: block,            z-index: 301,            padding: 0.5em,            border: 1px solid black,            margin: 0px,            font-weight: normal,            font-style: normal,            text-align: left,            text-indent: 0px,            text-transform: none,            line-height: normal,            letter-spacing: normal,            word-spacing: normal,            word-wrap: normal,            white-space: nowrap,            float: none,            box-shadow: rgb(170, 170, 170) 5px 5px 15px,            -webkit-box-shadow: rgb(170, 170, 170) 5px 5px 15px,            background-color: rgb(240, 240, 240)        },        href: ,        media: ,        type: 1    },    {        selector: #MathJax_ZoomOverlay,        css: {            position: absolute,            left: 0px,            top: 0px,            z-index: 300,            display: inline-block,            width: 100%,            height: 100%,            border: 0px,            padding: 0px,            margin: 0px,            opacity: 0,            background-color: white        },        href: ,        media: ,        type: 1    },    {        selector: #MathJax_ZoomFrame,        css: {            position: relative,            display: inline-block,            height: 0px,            width: 0px        },        href: ,        media: ,        type: 1    },    {        selector: #MathJax_ZoomEventTrap,        css: {            position: absolute,            left: 0px,            top: 0px,            z-index: 302,            display: inline-block,            border: 0px,            padding: 0px,            margin: 0px,            opacity: 0,            background-color: white        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_Preview,        css: {            color: rgb(136, 136, 136)        },        href: ,        media: ,        type: 1    },    {        selector: #MathJax_Message,        css: {            position: fixed,            left: 1em,            bottom: 1.5em,            border: 1px solid rgb(149, 149, 149),            margin: 0px,            padding: 2px 8px,            z-index: 102,            color: black,            font-size: 80%,            width: auto,            white-space: nowrap,            background-color: rgb(230, 230, 230)        },        href: ,        media: ,        type: 1    },    {        selector: #MathJax_MSIE_Frame,        css: {            position: absolute,            top: 0px,            left: 0px,            width: 0px,            z-index: 101,            border: 0px,            margin: 0px,            padding: 0px        },        href: ,        media: ,        type: 1    },    {        selector: .MathJax_Error,        css: {            color: rgb(204, 0, 0),            font-style: italic        },        href: ,        media: ,        type: 1    }]
Optimize CSS Rule Dumper
javascript;performance;recursion;userscript