--- a/devtools/client/inspector/test/browser_inspector_pseudoclass-lock.js
+++ b/devtools/client/inspector/test/browser_inspector_pseudoclass-lock.js
@@ -26,33 +26,48 @@ add_task(function* () {
inspector.sidebar.select("ruleview");
let view = inspector.ruleview.view;
info("Selecting the test node");
yield selectNode("#div-1", inspector);
yield togglePseudoClass(inspector);
- yield assertPseudoAddedToNode(inspector, testActor, view);
+ yield assertPseudoAddedToNode(inspector, testActor, view, "#div-1");
yield togglePseudoClass(inspector);
- yield assertPseudoRemovedFromNode(testActor);
- yield assertPseudoRemovedFromView(inspector, testActor, view);
+ yield assertPseudoRemovedFromNode(testActor, "#div-1");
+ yield assertPseudoRemovedFromView(inspector, testActor, view, "#div-1");
yield togglePseudoClass(inspector);
yield testNavigate(inspector, testActor, view);
+ info("Toggle pseudo on the parent and ensure everything is toggled off");
+ yield selectNode("#parent-div", inspector);
+ yield togglePseudoClass(inspector);
+ yield assertPseudoRemovedFromNode(testActor, "#div-1");
+ yield assertPseudoRemovedFromView(inspector, testActor, view, "#div-1");
+
+ yield togglePseudoClass(inspector);
+ info("Assert pseudo is dismissed when toggling it on a sibling node");
+ yield selectNode("#div-2", inspector);
+ yield togglePseudoClass(inspector);
+ yield assertPseudoAddedToNode(inspector, testActor, view, "#div-2");
+ let hasLock = yield testActor.hasPseudoClassLock("#div-1", PSEUDO);
+ ok(!hasLock, "pseudo-class lock has been removed for the previous locked node");
+
info("Destroying the toolbox");
let tab = toolbox.target.tab;
yield toolbox.destroy();
// As the toolbox get detroyed, we need to fetch a new test-actor
testActor = yield getTestActorWithoutToolbox(tab);
- yield assertPseudoRemovedFromNode(testActor);
+ yield assertPseudoRemovedFromNode(testActor, "#div-1");
+ yield assertPseudoRemovedFromNode(testActor, "#div-2");
});
function* togglePseudoClass(inspector) {
info("Toggle the pseudoclass, wait for it to be applied");
// Give the inspector panels a chance to update when the pseudoclass changes
let onPseudo = inspector.selection.once("pseudoclass");
let onRefresh = inspector.once("rule-view-refreshed");
@@ -85,61 +100,61 @@ function* testNavigate(inspector, testAc
yield selectNode("#div-1", inspector);
}
function* showPickerOn(selector, inspector) {
let nodeFront = yield getNodeFront(selector, inspector);
yield inspector.highlighter.showBoxModel(nodeFront);
}
-function* assertPseudoAddedToNode(inspector, testActor, ruleview) {
- info("Make sure the pseudoclass lock is applied to #div-1 and its ancestors");
+function* assertPseudoAddedToNode(inspector, testActor, ruleview, selector) {
+ info("Make sure the pseudoclass lock is applied to " + selector + " and its ancestors");
- let hasLock = yield testActor.hasPseudoClassLock("#div-1", PSEUDO);
+ let hasLock = yield testActor.hasPseudoClassLock(selector, PSEUDO);
ok(hasLock, "pseudo-class lock has been applied");
hasLock = yield testActor.hasPseudoClassLock("#parent-div", PSEUDO);
ok(hasLock, "pseudo-class lock has been applied");
hasLock = yield testActor.hasPseudoClassLock("body", PSEUDO);
ok(hasLock, "pseudo-class lock has been applied");
info("Check that the ruleview contains the pseudo-class rule");
let rules = ruleview.element.querySelectorAll(
".ruleview-rule.theme-separator");
is(rules.length, 3,
"rule view is showing 3 rules for pseudo-class locked div");
is(rules[1]._ruleEditor.rule.selectorText, "div:hover",
"rule view is showing " + PSEUDO + " rule");
- info("Show the highlighter on #div-1");
- yield showPickerOn("#div-1", inspector);
+ info("Show the highlighter on " + selector);
+ yield showPickerOn(selector, inspector);
info("Check that the infobar selector contains the pseudo-class");
let value = yield testActor.getHighlighterNodeTextContent(
"box-model-infobar-pseudo-classes");
is(value, PSEUDO, "pseudo-class in infobar selector");
yield inspector.highlighter.hideBoxModel();
}
-function* assertPseudoRemovedFromNode(testActor) {
+function* assertPseudoRemovedFromNode(testActor, selector) {
info("Make sure the pseudoclass lock is removed from #div-1 and its " +
"ancestors");
- let hasLock = yield testActor.hasPseudoClassLock("#div-1", PSEUDO);
+ let hasLock = yield testActor.hasPseudoClassLock(selector, PSEUDO);
ok(!hasLock, "pseudo-class lock has been removed");
hasLock = yield testActor.hasPseudoClassLock("#parent-div", PSEUDO);
ok(!hasLock, "pseudo-class lock has been removed");
hasLock = yield testActor.hasPseudoClassLock("body", PSEUDO);
ok(!hasLock, "pseudo-class lock has been removed");
}
-function* assertPseudoRemovedFromView(inspector, testActor, ruleview) {
+function* assertPseudoRemovedFromView(inspector, testActor, ruleview, selector) {
info("Check that the ruleview no longer contains the pseudo-class rule");
let rules = ruleview.element.querySelectorAll(
".ruleview-rule.theme-separator");
is(rules.length, 2, "rule view is showing 2 rules after removing lock");
- yield showPickerOn("#div-1", inspector);
+ yield showPickerOn(selector, inspector);
let value = yield testActor.getHighlighterNodeTextContent(
"box-model-infobar-pseudo-classes");
is(value, "", "pseudo-class removed from infobar selector");
yield inspector.highlighter.hideBoxModel();
}
--- a/devtools/server/actors/inspector.js
+++ b/devtools/server/actors/inspector.js
@@ -1747,16 +1747,24 @@ var WalkerActor = protocol.ActorClassWit
* @returns An empty packet. A "pseudoClassLock" mutation will
* be queued for any changed nodes.
*/
addPseudoClassLock: function (node, pseudo, options = {}) {
if (isNodeDead(node)) {
return;
}
+ // There can be only one node locked per pseudo, so dismiss all existing
+ // ones
+ for (let locked of this._activePseudoClassLocks) {
+ if (DOMUtils.hasPseudoClassLock(locked.rawNode, pseudo)) {
+ this._removePseudoClassLock(locked, pseudo);
+ }
+ }
+
this._addPseudoClassLock(node, pseudo);
if (!options.parents) {
return;
}
let walker = this.getDocumentWalker(node.rawNode);
let cur;