Is it possible to get css class object?

Why the dash is there?

Which dash? After String.raw inside the template string? (Note: you lost two characters in your quote) That one is escaping the ‘.’ for the RegExp

So what is the final result - one dimentional array?

Yes

Quite strange code. Is the updated version still non-cross browser?

The code worked in Firefox before the “update”, so yes, the whole point of changing it was to make it cross-browser compatible.

I speak about this dash “,”:

({ rules, })
I see only one parameter inside the {} and so I am confused why the dash is not followed by some variable or property…

That’s a comma :D. This is a dash: “-”

Tailing commas in (modern) JavaScript are optional. So you don’t have to set them but you can

Why the rules array is declared as const? I think you save object to it so it should be variable.

(I’m not entirely sure what you mean, but:)

The const doesn’t effect the referenced value, but the reference to it:
declaring an identifier const means you can’t assign to it (const a = { }; a = [ ]; doesn’t work),
but you can still manipulate the values properties (const a = { }; a.b = 42; works).

I tried your code but the rules array is empty when function finishes. Maybe I could send you my addon so you could check how it works?

I would explain you what I am working on and maybe you can improve the code. If it would work it would be great because the code is quite sort. I tried to create complicated solution but I failed here and here.


I wonder that such function like yours is not standard part of browsers. We use functions to remove css classes but we cannot analyse it’s content… Which is neccessary if you need to remove a class dynamically/automatically.

What exactly is it you want to achieve?
Do you want to forcefully apply (user) styles to elements with a certain class?
If so, do you really need anything more than rules that are declared as !important?

I am working on addon which can swap columns (divs). This is archieved by 1) analysing divs positions and 2) analysing styles. Before I can apply new (absolute) position of the divs, I must to remove the classes which give the position:absolute, left: …, right: …, top: … or bottom: … positions and float: being set to “non-none”. So I need to analyse the classes or even div’s id.

The code looks like this:

var selectors = "div.fauxcolumn-right-outer;div.fauxcolumn-center-outer"
var selectors = selectors.split(";");
var searches = [];
var targets = [];
for ( var k in selectors )
  {
  if ( (k % 2) == 0 )
    searches.push(selectors[k]);
  else
    targets.push(selectors[k]);      
  }

for ( var k in searches )
  {
  var search, target; 
  search = $(searches[k]);
  if ( search.length )
   target = $(targets[k]);
  if ( !search.length || !target.length )
    continue;
    
  var s_css_arr = search.prop("className").split(" ");
  var t_css_arr = target.prop("className").split(" ");
  
  var className = s_css_arr[0];
  const hasClass = new RegExp(String.raw`\.${ className }(?:[^\w-]|$)`);
  const rules = [ ];
  
  Array.prototype.forEach.call(document.styleSheets,
      ({ rules, }) => rules && Array.prototype.forEach.call(rules,
          rule => hasClass.test(rule.selectorText) && rules.push(rule)
      )
  );

I see the problem. There is div.classname so I will need to modify it

Doing that may have unexpected consequences. Instead you should div.style.setProperty('left', '42px', 'important')

This will overrule all other styles defined in stylesheets

I guess you misunderstand me. div.classname is the JQuery selector.

Maybe I did …

I started to debug your code and now I see that it does not enter the second function.

In my case there are 1st stylesheets which have no the cssRules, but the 3rd one does. But the rules varibale is undefined. This is similar problem which I had in my code previously. I was stucked with SOP, there was exception Security error. In your case there is not security exception but it seems like the browser refuses to access the object this way. Why it is undefined? It should not be. I can view the object in debugger but I cannot access it. It would be simpler if you would download my addon version for Firefox and try it on the same blog as I am doing the test.

Well, I guess it should be cssRules instead of rules. It seems that rules is not supported by Firefox

But this is cross-browser problem. Is it possible to use this? ({cssRules, rules}) ? Because you don’t know which browser will be used.

I see you are using Chrome. Happy man.

As (almost) always, MDN knows the answer:

Using only cssRules should do.

Unfortunatly, with the cssRules I hit the error I have spoken about :frowning: You should try in Firefox.

SecurityError

Maybe is it problem with permissions to access the css file?

"permissions": ["storage", "tabs", "activeTab", "notifications"],

Hey, someone answers my question and post solution!

var rules;
for (var i = 0; i< document.styleSheets.length ;i++) {
  try {
    rules = sheets[i].cssRules;
  } catch(err) {
    console.log("error");
    alert("error");
    }

Great. Now I know that I can make it working.

Here is my program what I done. There maybe bugs still. It shows the idea of the project I am working on.

mynamespace.removeClass = function(node, selectorText, classNames){
for (var k in classNames)
  {
  var hasClass = new RegExp( "/" + classNames[k] + "/");
  if ( hasClass.test(selectorText) )
    node.removeClass(classNames[k]);
  }
}
mynamespace.filterStyles = function(node, searchStyles ) {
  var classNames = node.prop("className").split(" ");
  var sheets = document.styleSheets, o = {};
  var rules;
  for (var i in sheets) {
    // Firefox - Security fix:
    try { rules = sheets[i].cssRules; } catch(err) {}

  if(rules)
     for (var r = 0; r < rules.length; r++) {
        if (node.is(rules[r].selectorText)) 
          {            
          var selector;
          selector = mynamespace.searchRule(rules[r].style, searchStyles);
          if (!selector)
            selector = mynamespace.searchRule(node.attr('style'), searchStyles);
          if (selector)            
            mynamespace.removeClass(node, selector, classNames);
          }
      }  

  }
  return false;
}

/* searchRule searches rules, 
   compares with ss searchStyles, 
   returns selectorText if condition is true,
   returns false if condition is false.
*/
mynamespace.searchRule = function(css, ss ) {
  if (typeof css == "undefined" ) 
    return false;
  var selector = css.parentRule.selectorText;
  if (css instanceof CSSStyleDeclaration) {
    for (var i = 0; i<css.length; i++) 
    {
    /*            
    var ss = {
      position: { val: "relative", op: "=" },
      left: { val: null , op: "" },
      right: { val: null , op: "" },
      top: { val: null , op: "" },
      bottom: { val: null , op: "" },
      float: { val: "none" , op: "!" , andop: "-"  }
      } */
      for (var a in ss)
        {
        if ( a == css[i] )
          {
          if ( ss[a].val === null && css[a] )
            return selector;
          else
          if ( ss[a].op == "=" && ss[a].val === css[a] )
            return selector;
          else
          if ( ss[a].op == "!" )  
            {   
             if ( ss[a].hasOwnProperty("andop") )
              {
              if ( ss[a].andop == "-" ) 
                {
                if ( css[a] != "" )
                  return selector;
                }
              }
              else
              {
              if( ss[a].val != css[a] )
                  return selector;
              }
            return selector;
            }
          }
        } // end inner for
    } // end outer for
  } // if css instance of
  else if (typeof css == "string") {
      css = css.split("; ");
      // not implemented
      }
return false;
}

/* Implementation */
var searchStyles = {
  position: { val: "absolute", op: "=" },
  left: { val: null , op: "" },
  right: { val: null , op: "" },
  top: { val: null , op: "" },
  bottom: { val: null , op: "" },
  float: { val: "none" , op: "!" , andop: "-"  }
  }

var selectors = "div.fauxcolumn-right-outer;div.fauxcolumn-center-outer"
selectors = selectors.split(";");
var searches = [];
var targets = [];
for ( var k in selectors )
  {
  if ( (k % 2) == 0 )
    searches.push(selectors[k]);
  else
    targets.push(selectors[k]);      
  }

for ( var k in searches )
  {
  search = $(searches[k]);
  mynamespace.filterStyles(search, searchStyles);
  target = $(targets[k]);
  mynamespace.filterStyles(search, searchStyles);
   }

If you see any bugs please let me know.

Is there a way to find out the stylesheets / style rules which were inserted into document?

Edit:
Yes it is. First answer here.

Modified and simplified version posted by me.