0

I have a list of CSS classes defined in app.css as

.eventcolor-1{background:rgba(249, 115, 0);}
.eventcolor-2{background:rgba(14, 48, 71, 0.99);}
.eventcolor-3{background:rgba(16, 130, 140, 0.99);}
.eventcolor-4{background:rgba(41, 91, 167, 0.99);}
.eventcolor-5{background:rgba(148, 172, 60, 0.99)}
.eventcolor-6{background:rgba(252, 195, 20, 0.99);} 

In jQuery I need a method that will pull up all the .eventcolor-* currently available, and add them to an array.

The problem is, here's an accepted solution for this task: https://stackoverflow.com/a/18378434/1005607

function getClassNamesByPattern(pattern) {
    var pattern = "eventcolor-*";
    var selectors = {};

    for (var i = 0; i < document.styleSheets.length; i++) {
        var classes = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
        for (var x = 0; x < classes.length; x++) {
            if (undefined !== classes[x].selectorText && null !== classes[x].selectorText.match(new RegExp('\\.' + pattern.replace(/([^\s])\*/, '$1[^ ]+'), 'g'))) {
                selectors[classes[x].selectorText] = classes[x].selectorText;
            }
        }
    }

    return Object.keys(selectors);
}

But this throws a Security Error in Firefox, because I'm going through CSS's I don't need. I don't need to include everything in my app, just the custom file app.css.

SecurityError: The operation is insecure.

Is there a safe way to restrict the search to just a given CSS?

2
  • Your question doesn't have any relation with jquery, consider replacing jquery tag with dom Commented Oct 29, 2017 at 16:00
  • Done, removed the jQuery tag Commented Oct 29, 2017 at 16:01

2 Answers 2

1

You can filter out stylesheet into loop by using StyleSheet.ownerNode property of the CSSStyleSheet objects, you're iterating by.

Considering that you're including your stylesheet as a <link> it may look like:

function getClassNamesByPattern(pattern) {
    var pattern = "eventcolor-*";
    var selectors = {};

    for (var i = 0; i < document.styleSheets.length; i++) {
        var stylesheet = document.styleSheets[i];
        if (typeof stylesheet.ownerNode !== 'undefined') {
            // This is stylesheet linked from external source
            var ownerNode = stylesheet.ownerNode;
            if (typeof ownerNode.tagName === 'string' && ownerNode.tagName.toLowerCase() === 'link' && ownerNode.rel === 'stylesheet') {
                // This is stylesheet linked through <link rel="stylesheet">
                var href = ownerNode.href;
                // Testing for filename match, you can update it to match your needs
                if (!href.match(/\/app\.css$/)) {
                    // Not inside our stylesheet - skip it
                    continue;
                }
            }
        }
        var classes = stylesheet.rules || stylesheet.cssRules;
        for (var x = 0; x < classes.length; x++) {
            if (undefined !== classes[x].selectorText && null !== classes[x].selectorText.match(new RegExp('\\.' + pattern.replace(/([^\s])\*/, '$1[^ ]+'), 'g'))) {
                selectors[classes[x].selectorText] = classes[x].selectorText;
            }
        }
    }

    return Object.keys(selectors);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I also found that "document.styleSheets[i].href" holds the name of the current CSS, so I can check that directly.
0

I also found this easy way:

document.styleSheets[i].href contains the name of the CSS currently being examined.

Thus, we can check document.styleSheets[i].href.indexOf("app.css") != -1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.