Bug 1243736 - Enable browser_rules_content_02.js with e10s and make rule-view wait for updateSourceLink; r=bgrins
--- a/devtools/client/inspector/rules/rules.js
+++ b/devtools/client/inspector/rules/rules.js
@@ -957,22 +957,23 @@ CssRuleView.prototype = {
_populate: function() {
let elementStyle = this._elementStyle;
return this._elementStyle.populate().then(() => {
if (this._elementStyle !== elementStyle || this.isDestroyed) {
return;
}
this._clearRules();
- this._createEditors();
-
+ let onEditorsReady = this._createEditors();
this.refreshPseudoClassPanel();
// Notify anyone that cares that we refreshed.
- this.emit("ruleview-refreshed");
+ return onEditorsReady.then(() => {
+ this.emit("ruleview-refreshed");
+ }, e => console.error(e));
}).then(null, promiseWarn);
},
/**
* Show the user that the rule view has no node selected.
*/
_showEmpty: function() {
if (this.styleDocument.getElementById("noResults") > 0) {
@@ -1142,27 +1143,31 @@ CssRuleView.prototype = {
let lastInheritedSource = "";
let lastKeyframes = null;
let seenPseudoElement = false;
let seenNormalElement = false;
let seenSearchTerm = false;
let container = null;
if (!this._elementStyle.rules) {
- return;
+ return promise.resolve();
}
+ let editorReadyPromises = [];
for (let rule of this._elementStyle.rules) {
if (rule.domRule.system) {
continue;
}
// Initialize rule editor
if (!rule.editor) {
rule.editor = new RuleEditor(this, rule);
+ let onEditorReady = promise.defer();
+ rule.editor.once("source-link-updated", onEditorReady.resolve);
+ editorReadyPromises.push(onEditorReady.promise);
}
// Filter the rules and highlight any matches if there is a search input
if (this.searchValue && this.searchData) {
if (this.highlightRule(rule)) {
seenSearchTerm = true;
} else if (rule.domRule.type !== ELEMENT_STYLE) {
continue;
@@ -1206,16 +1211,18 @@ CssRuleView.prototype = {
}
}
if (this.searchValue && !seenSearchTerm) {
this.searchField.classList.add("devtools-style-searchbox-no-match");
} else {
this.searchField.classList.remove("devtools-style-searchbox-no-match");
}
+
+ return promise.all(editorReadyPromises);
},
/**
* Highlight rules that matches the filter search value and returns a
* boolean indicating whether or not rules were highlighted.
*
* @param {Rule} rule
* The rule object we're highlighting if its rule selectors or
--- a/devtools/client/inspector/rules/test/browser.ini
+++ b/devtools/client/inspector/rules/test/browser.ini
@@ -132,17 +132,16 @@ skip-if = (os == "win" && debug) || e10s
[browser_rules_multiple-properties-priority.js]
[browser_rules_multiple-properties-unfinished_01.js]
[browser_rules_multiple-properties-unfinished_02.js]
[browser_rules_multiple_properties_01.js]
[browser_rules_multiple_properties_02.js]
[browser_rules_original-source-link.js]
[browser_rules_pseudo-element_01.js]
[browser_rules_pseudo-element_02.js]
-skip-if = e10s # Bug 1090340
[browser_rules_pseudo_lock_options.js]
[browser_rules_refresh-no-flicker.js]
[browser_rules_refresh-on-attribute-change_01.js]
[browser_rules_refresh-on-attribute-change_02.js]
[browser_rules_refresh-on-style-change.js]
[browser_rules_search-filter-computed-list_01.js]
[browser_rules_search-filter-computed-list_02.js]
[browser_rules_search-filter-computed-list_03.js]
--- a/devtools/client/inspector/rules/test/browser_rules_pseudo-element_02.js
+++ b/devtools/client/inspector/rules/test/browser_rules_pseudo-element_02.js
@@ -6,28 +6,24 @@
// Test that pseudoelements are displayed correctly in the rule view
const TEST_URI = URL_ROOT + "doc_pseudoelement.html";
add_task(function*() {
yield addTab(TEST_URI);
let {inspector} = yield openRuleView();
- yield testTopLeft(inspector);
-});
-function* testTopLeft(inspector) {
- let node = inspector.markup.walker.frontForRawNode(getNode("#topleft"));
+ let node = yield getNodeFront("#topleft", inspector);
let children = yield inspector.markup.walker.children(node);
is(children.nodes.length, 3, "Element has correct number of children");
let beforeElement = children.nodes[0];
is(beforeElement.tagName, "_moz_generated_content_before",
"tag name is correct");
yield selectNode(beforeElement, inspector);
let afterElement = children.nodes[children.nodes.length - 1];
is(afterElement.tagName, "_moz_generated_content_after",
"tag name is correct");
yield selectNode(afterElement, inspector);
-}
-
+});
--- a/devtools/client/inspector/rules/views/rule-editor.js
+++ b/devtools/client/inspector/rules/views/rule-editor.js
@@ -20,37 +20,49 @@ const {
} = require("devtools/client/inspector/shared/utils");
const {
parseDeclarations,
parsePseudoClassesAndAttributes,
SELECTOR_ATTRIBUTE,
SELECTOR_ELEMENT,
SELECTOR_PSEUDO_CLASS
} = require("devtools/client/shared/css-parsing-utils");
+const promise = require("promise");
+
+loader.lazyRequireGetter(this, "EventEmitter",
+ "devtools/shared/event-emitter");
XPCOMUtils.defineLazyGetter(this, "_strings", function() {
return Services.strings.createBundle(
"chrome://devtools-shared/locale/styleinspector.properties");
});
const HTML_NS = "http://www.w3.org/1999/xhtml";
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
/**
* RuleEditor is responsible for the following:
* Owns a Rule object and creates a list of TextPropertyEditors
* for its TextProperties.
* Manages creation of new text properties.
*
+ * One step of a RuleEditor's instantiation is figuring out what's the original
+ * source link to the parent stylesheet (in case of source maps). This step is
+ * asynchronous and is triggered as soon as the RuleEditor is instantiated (see
+ * updateSourceLink). If you need to know when the RuleEditor is done with this,
+ * you need to listen to the source-link-updated event.
+ *
* @param {CssRuleView} ruleView
* The CssRuleView containg the document holding this rule editor.
* @param {Rule} rule
* The Rule object we're editing.
*/
function RuleEditor(ruleView, rule) {
+ EventEmitter.decorate(this);
+
this.ruleView = ruleView;
this.doc = this.ruleView.styleDocument;
this.rule = rule;
this.isEditable = !rule.isSystem;
// Flag that blocks updates of the selector and properties when it is
// being edited
this.isEditing = false;
@@ -219,20 +231,31 @@ RuleEditor.prototype = {
if (this.rule.ruleLine === -1 && this.rule.domRule.parentStyleSheet) {
sourceLabel.parentNode.setAttribute("unselectable", "true");
}
}
let showOrig = Services.prefs.getBoolPref(PREF_ORIG_SOURCES);
if (showOrig && !this.rule.isSystem &&
this.rule.domRule.type !== ELEMENT_STYLE) {
+ // Only get the original source link if the right pref is set, if the rule
+ // isn't a system rule and if it isn't an inline rule.
this.rule.getOriginalSourceStrings().then((strings) => {
sourceLabel.setAttribute("value", strings.short);
sourceLabel.setAttribute("tooltiptext", strings.full);
- }, console.error);
+ }, e => console.error(e)).then(() => {
+ this.emit("source-link-updated");
+ });
+ } else {
+ // If we're not getting the original source link, then we can emit the
+ // event immediately (but still asynchronously to give consumers a chance
+ // to register it after having instantiated the RuleEditor).
+ promise.resolve().then(() => {
+ this.emit("source-link-updated");
+ });
}
},
/**
* Update the rule editor with the contents of the rule.
*/
populate: function() {
// Clear out existing viewers.