Bug 1384789 - Check ancestor URLs to avoid sheet cycles. r=bgrins
With Stylo, an import rule from a cycle _will_ have a `styleSheet` object, so we
need to also check the sheet's ancestors to see if the URL is unique.
MozReview-Commit-ID: B33REaSGGYU
--- a/devtools/server/actors/stylesheets.js
+++ b/devtools/server/actors/stylesheets.js
@@ -926,19 +926,24 @@ var StyleSheetsActor = protocol.ActorCla
_getImported: function (doc, styleSheet) {
return Task.spawn(function* () {
let rules = yield styleSheet.getCSSRules();
let imported = [];
for (let i = 0; i < rules.length; i++) {
let rule = rules[i];
if (rule.type == Ci.nsIDOMCSSRule.IMPORT_RULE) {
- // Associated styleSheet may be null if it has already been seen due
- // to duplicate @imports for the same URL.
- if (!rule.styleSheet || !this._shouldListSheet(doc, rule.styleSheet)) {
+ // With the Gecko style system, the associated styleSheet may be null
+ // if it has already been seen because an import cycle for the same
+ // URL. With Stylo, the styleSheet will exist (which is correct per
+ // the latest CSSOM spec), so we also need to check ancestors for the
+ // same URL to avoid cycles.
+ let sheet = rule.styleSheet;
+ if (!sheet || this._haveAncestorWithSameURL(sheet) ||
+ !this._shouldListSheet(doc, sheet)) {
continue;
}
let actor = this.parentActor.createStyleSheetActor(rule.styleSheet);
imported.push(actor);
// recurse imports in this stylesheet as well
let children = yield this._getImported(doc, actor);
imported = imported.concat(children);
@@ -948,16 +953,33 @@ var StyleSheetsActor = protocol.ActorCla
}
}
return imported;
}.bind(this));
},
/**
+ * Check all ancestors to see if this sheet's URL matches theirs as a way to
+ * detect an import cycle.
+ *
+ * @param {DOMStyleSheet} sheet
+ */
+ _haveAncestorWithSameURL(sheet) {
+ let sheetHref = sheet.href;
+ while (sheet.parentStyleSheet) {
+ if (sheet.parentStyleSheet.href == sheetHref) {
+ return true;
+ }
+ sheet = sheet.parentStyleSheet;
+ }
+ return false;
+ },
+
+ /**
* Create a new style sheet in the document with the given text.
* Return an actor for it.
*
* @param {object} request
* Debugging protocol request object, with 'text property'
* @return {object}
* Object with 'styelSheet' property for form on new actor.
*/