From 08a6f60f02572a059e336fcba0c4d4f4f0e2c7dc Mon Sep 17 00:00:00 2001 From: Heather Arthur Date: Fri, 18 Jan 2013 14:03:22 -0800 Subject: [PATCH] Bug 827604 - Pseudoclass lock isn't clearing; r=dcamp --- browser/devtools/inspector/InspectorPanel.jsm | 23 +++++++++++ browser/devtools/inspector/Selection.jsm | 2 + .../browser_inspector_pseudoclass_lock.js | 39 ++++++++++++++++--- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/browser/devtools/inspector/InspectorPanel.jsm b/browser/devtools/inspector/InspectorPanel.jsm index 9068d6db49a..366f0a3a8cf 100644 --- a/browser/devtools/inspector/InspectorPanel.jsm +++ b/browser/devtools/inspector/InspectorPanel.jsm @@ -65,6 +65,8 @@ InspectorPanel.prototype = { this._selection = new Selection(); this.onNewSelection = this.onNewSelection.bind(this); this.selection.on("new-node", this.onNewSelection); + this.onBeforeNewSelection = this.onBeforeNewSelection.bind(this); + this.selection.on("before-new-node", this.onBeforeNewSelection); this.onDetached = this.onDetached.bind(this); this.selection.on("detached", this.onDetached); @@ -319,6 +321,17 @@ InspectorPanel.prototype = { this.cancelLayoutChange(); }, + /** + * When a new node is selected, before the selection has changed. + */ + onBeforeNewSelection: function InspectorPanel_onBeforeNewSelection(event, + node) { + if (this.breadcrumbs.indexOf(node) == -1) { + // only clear locks if we'd have to update breadcrumbs + this.clearPseudoClasses(); + } + }, + /** * When a node is deleted, select its parent node. */ @@ -367,6 +380,7 @@ InspectorPanel.prototype = { this.nodemenu.removeEventListener("popuphiding", this._resetNodeMenu, true); this.breadcrumbs.destroy(); this.selection.off("new-node", this.onNewSelection); + this.selection.off("before-new-node", this.onBeforeNewSelection); this.selection.off("detached", this.onDetached); this._destroyMarkup(); this._selection.destroy(); @@ -500,6 +514,15 @@ InspectorPanel.prototype = { this.selection.emit("pseudoclass"); }, + /** + * Clear any pseudo-class locks applied to the current hierarchy. + */ + clearPseudoClasses: function InspectorPanel_clearPseudoClasses() { + this.breadcrumbs.nodeHierarchy.forEach(function(crumb) { + DOMUtils.clearPseudoClassLocks(crumb.node); + }); + }, + /** * Toggle the highlighter when ruleview is hovered. */ diff --git a/browser/devtools/inspector/Selection.jsm b/browser/devtools/inspector/Selection.jsm index 9c16c552d90..4e73d38a3a6 100644 --- a/browser/devtools/inspector/Selection.jsm +++ b/browser/devtools/inspector/Selection.jsm @@ -42,6 +42,7 @@ this.EXPORTED_SYMBOLS = ["Selection"]; * * Events: * "new-node" when the inner node changed + * "before-new-node" when the inner node is set to change * "attribute-changed" when an attribute is changed (only if tracked) * "detached" when the node (or one of its parents) is removed from the document (only if tracked) * "reparented" when the node (or one of its parents) is moved under a different node (only if tracked) @@ -126,6 +127,7 @@ Selection.prototype = { setNode: function SN_setNode(value, reason="unknown") { this.reason = reason; if (value !== this._node) { + this.emit("before-new-node", value, reason); let previousNode = this._node; this._detachEvents(); this._node = value; diff --git a/browser/devtools/inspector/test/browser_inspector_pseudoclass_lock.js b/browser/devtools/inspector/test/browser_inspector_pseudoclass_lock.js index 082e2a06a6e..88547284777 100644 --- a/browser/devtools/inspector/test/browser_inspector_pseudoclass_lock.js +++ b/browser/devtools/inspector/test/browser_inspector_pseudoclass_lock.js @@ -8,7 +8,7 @@ let TargetFactory = tempScope.TargetFactory; let DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils); let doc; -let div; +let parentDiv, div, div2; let inspector; let ruleview; @@ -30,16 +30,24 @@ function test() function createDocument() { + parentDiv = doc.createElement("div"); + parentDiv.textContent = "parent div"; + div = doc.createElement("div"); div.textContent = "test div"; + div2 = doc.createElement("div"); + div2.textContent = "test div2"; + let head = doc.getElementsByTagName('head')[0]; let style = doc.createElement('style'); let rules = doc.createTextNode('div { color: red; } div:hover { color: blue; }'); style.appendChild(rules); head.appendChild(style); - doc.body.appendChild(div); + parentDiv.appendChild(div); + parentDiv.appendChild(div2); + doc.body.appendChild(parentDiv); openInspector(selectNode); } @@ -71,10 +79,31 @@ function performTests() // toggle it back on inspector.togglePseudoClass(pseudo); + testNavigate(); + // close the inspector finishUp(); } +function testNavigate() +{ + inspector.selection.setNode(parentDiv); + + // make sure it's still on after naving to parent + is(DOMUtils.hasPseudoClassLock(div, pseudo), true, + "pseudo-class lock is still applied after inspecting ancestor"); + + inspector.selection.setNode(div2); + + // make sure it's removed after naving to a non-hierarchy node + is(DOMUtils.hasPseudoClassLock(div, pseudo), false, + "pseudo-class lock is removed after inspecting sibling node"); + + // toggle it back on + inspector.selection.setNode(div); + inspector.togglePseudoClass(pseudo); +} + function testAdded() { // lock is applied to it and ancestors @@ -99,7 +128,7 @@ function testAdded() function testRemoved() { - // lock removed from node and ancestors + // lock removed from node and ancestors let node = div; do { is(DOMUtils.hasPseudoClassLock(node, pseudo), false, @@ -112,11 +141,11 @@ function testRemovedFromUI() { // infobar selector doesn't contain pseudo-class let pseudoClassesBox = getActiveInspector().highlighter.nodeInfo.pseudoClassesBox; - is(pseudoClassesBox.textContent, "", "pseudo-class removed from infobar selector"); + is(pseudoClassesBox.textContent, "", "pseudo-class removed from infobar selector"); // ruleview no longer contains pseudo-class rule is(ruleview.element.children.length, 2, - "rule view is showing 2 rules after removing lock"); + "rule view is showing 2 rules after removing lock"); } function finishUp()