Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

security error the operation is insecure in firefox document.stylesheets

The following code throws an error in the Firefox Console at the line with the continue.

SecurityError: The operation is insecure.
if( !sheet.cssRules ) { continue; }

However does not in Chrome and IE 11... Can someone explain the -why- of this? (And also how to re-work to make it safe.) I assume this is a cross-domain issue, but I'm stuck as how to re-work the code properly.

var bgColor = getStyleRuleValue('background-color', 'bg_selector');

function getStyleRuleValue(style, selector, sheet) {
  var sheets = typeof sheet !== 'undefined' ? [sheet] : document.styleSheets;
  for (var i = 0, l = sheets.length; i < l; i++) {
    var sheet = sheets[i];
    if( !sheet.cssRules ) { continue; }
    for (var j = 0, k = sheet.cssRules.length; j < k; j++) {
      var rule = sheet.cssRules[j];
      if (rule.selectorText && rule.selectorText.split(',').indexOf(selector) !== -1) 
         return rule.style[style];            
     }
   }
  return null;
 }
like image 658
jchwebdev Avatar asked Feb 08 '14 05:02

jchwebdev


1 Answers

To circumvent the SecurityError in Firefox when attempting to access the cssRules attribute, you must use a try/catch statement. The following should work:

// Example call to process_stylesheet() with StyleSheet object.
process_stylesheet(window.document.styleSheets[0]);

function process_stylesheet(ss) {
  // cssRules respects same-origin policy, as per
  // https://code.google.com/p/chromium/issues/detail?id=49001#c10.
  try {
    // In Chrome, if stylesheet originates from a different domain,
    // ss.cssRules simply won't exist. I believe the same is true for IE, but
    // I haven't tested it.
    //
    // In Firefox, if stylesheet originates from a different domain, trying
    // to access ss.cssRules will throw a SecurityError. Hence, we must use
    // try/catch to detect this condition in Firefox.
    if(!ss.cssRules)
      return;
  } catch(e) {
    // Rethrow exception if it's not a SecurityError. Note that SecurityError
    // exception is specific to Firefox.
    if(e.name !== 'SecurityError')
      throw e;
    return;
  }

  // ss.cssRules is available, so proceed with desired operations.
  for(var i = 0; i < ss.cssRules.length; i++) {
    var rule = ss.cssRules[i];
    // Do something with rule
  }
}
like image 189
Jeff W. Avatar answered Nov 11 '22 18:11

Jeff W.