зеркало из https://github.com/mozilla/gecko-dev.git
Bug 707740 - Ability to lock in a pseudo class in the page inspector. r=dcamp
This commit is contained in:
Родитель
76ff990af2
Коммит
a69a90000f
|
@ -43,7 +43,11 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource:///modules/devtools/LayoutHelpers.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = ["Highlighter"];
|
||||
|
||||
|
@ -59,6 +63,9 @@ const INSPECTOR_INVISIBLE_ELEMENTS = {
|
|||
"title": true,
|
||||
};
|
||||
|
||||
const PSEUDO_CLASSES = [":hover", ":active", ":focus"];
|
||||
// add ":visited" and ":link" after bug 713106 is fixed
|
||||
|
||||
/**
|
||||
* A highlighter mechanism.
|
||||
*
|
||||
|
@ -109,6 +116,8 @@ const INSPECTOR_INVISIBLE_ELEMENTS = {
|
|||
* "highlighting" - Highlighter is highlighting
|
||||
* "locked" - The selected node has been locked
|
||||
* "unlocked" - The selected ndoe has been unlocked
|
||||
* "pseudoclasstoggled" - A pseudo-class lock has changed on the selected node
|
||||
|
||||
*
|
||||
* Structure:
|
||||
*
|
||||
|
@ -238,6 +247,17 @@ Highlighter.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify that a pseudo-class lock was toggled on the highlighted element
|
||||
*
|
||||
* @param aPseudo - The pseudo-class to toggle, e.g. ":hover".
|
||||
*/
|
||||
pseudoClassLockToggled: function Highlighter_pseudoClassLockToggled(aPseudo)
|
||||
{
|
||||
this.emitEvent("pseudoclasstoggled", [aPseudo]);
|
||||
this.updateInfobar();
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the highlighter size and position.
|
||||
*/
|
||||
|
@ -446,29 +466,80 @@ Highlighter.prototype = {
|
|||
|
||||
let classesBox = this.chromeDoc.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||
classesBox.id = "highlighter-nodeinfobar-classes";
|
||||
|
||||
let pseudoClassesBox = this.chromeDoc.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||
pseudoClassesBox.id = "highlighter-nodeinfobar-pseudo-classes";
|
||||
|
||||
// Add some content to force a better boundingClientRect down below.
|
||||
classesBox.textContent = " ";
|
||||
pseudoClassesBox.textContent = " ";
|
||||
|
||||
nodeInfobar.appendChild(tagNameLabel);
|
||||
nodeInfobar.appendChild(idLabel);
|
||||
nodeInfobar.appendChild(classesBox);
|
||||
nodeInfobar.appendChild(pseudoClassesBox);
|
||||
container.appendChild(arrowBoxTop);
|
||||
container.appendChild(nodeInfobar);
|
||||
container.appendChild(arrowBoxBottom);
|
||||
|
||||
aParent.appendChild(container);
|
||||
|
||||
nodeInfobar.onclick = (function _onInfobarRightClick(aEvent) {
|
||||
if (aEvent.button == 2) {
|
||||
this.openPseudoClassMenu();
|
||||
}
|
||||
}).bind(this);
|
||||
|
||||
let barHeight = container.getBoundingClientRect().height;
|
||||
|
||||
this.nodeInfo = {
|
||||
tagNameLabel: tagNameLabel,
|
||||
idLabel: idLabel,
|
||||
classesBox: classesBox,
|
||||
pseudoClassesBox: pseudoClassesBox,
|
||||
container: container,
|
||||
barHeight: barHeight,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the infobar's pseudo-class context menu.
|
||||
*/
|
||||
openPseudoClassMenu: function Highlighter_openPseudoClassMenu()
|
||||
{
|
||||
let menu = this.chromeDoc.createElement("menupopup");
|
||||
menu.id = "infobar-context-menu";
|
||||
|
||||
let popupSet = this.chromeDoc.getElementById("mainPopupSet");
|
||||
popupSet.appendChild(menu);
|
||||
|
||||
let fragment = this.buildPseudoClassMenu();
|
||||
menu.appendChild(fragment);
|
||||
|
||||
menu.openPopup(this.nodeInfo.pseudoClassesBox, "end_before", 0, 0, true, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create the menuitems for toggling the selection's pseudo-class state
|
||||
*
|
||||
* @returns DocumentFragment. The menuitems for toggling pseudo-classes.
|
||||
*/
|
||||
buildPseudoClassMenu: function IUI_buildPseudoClassesMenu()
|
||||
{
|
||||
let fragment = this.chromeDoc.createDocumentFragment();
|
||||
for (let i = 0; i < PSEUDO_CLASSES.length; i++) {
|
||||
let pseudo = PSEUDO_CLASSES[i];
|
||||
let item = this.chromeDoc.createElement("menuitem");
|
||||
item.setAttribute("type", "checkbox");
|
||||
item.setAttribute("label", pseudo);
|
||||
item.addEventListener("command",
|
||||
this.pseudoClassLockToggled.bind(this, pseudo), false);
|
||||
item.setAttribute("checked", DOMUtils.hasPseudoClassLock(this.node,
|
||||
pseudo));
|
||||
fragment.appendChild(item);
|
||||
}
|
||||
return fragment;
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlight a rectangular region.
|
||||
*
|
||||
|
@ -543,6 +614,14 @@ Highlighter.prototype = {
|
|||
|
||||
classes.textContent = this.node.classList.length ?
|
||||
"." + Array.join(this.node.classList, ".") : "";
|
||||
|
||||
// Pseudo-classes
|
||||
let pseudos = PSEUDO_CLASSES.filter(function(pseudo) {
|
||||
return DOMUtils.hasPseudoClassLock(this.node, pseudo);
|
||||
}, this);
|
||||
|
||||
let pseudoBox = this.nodeInfo.pseudoClassesBox;
|
||||
pseudoBox.textContent = pseudos.join("");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -617,8 +696,8 @@ Highlighter.prototype = {
|
|||
*/
|
||||
computeZoomFactor: function Highlighter_computeZoomFactor() {
|
||||
this.zoom =
|
||||
this.win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils)
|
||||
this.win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils)
|
||||
.screenPixelsPerCSSPixel;
|
||||
},
|
||||
|
||||
|
@ -805,3 +884,6 @@ Highlighter.prototype = {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "DOMUtils", function () {
|
||||
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils)
|
||||
});
|
||||
|
|
|
@ -83,6 +83,8 @@ const INSPECTOR_NOTIFICATIONS = {
|
|||
EDITOR_SAVED: "inspector-editor-saved",
|
||||
};
|
||||
|
||||
const PSEUDO_CLASSES = [":hover", ":active", ":focus"];
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// InspectorUI
|
||||
|
||||
|
@ -362,6 +364,7 @@ InspectorUI.prototype = {
|
|||
show: this.openRuleView,
|
||||
hide: this.closeRuleView,
|
||||
onSelect: this.selectInRuleView,
|
||||
onChanged: this.changeInRuleView,
|
||||
panel: null,
|
||||
unregister: this.destroyRuleView,
|
||||
sidebar: true,
|
||||
|
@ -481,6 +484,7 @@ InspectorUI.prototype = {
|
|||
if (!aKeepStore) {
|
||||
this.store.deleteStore(this.winID);
|
||||
this.win.removeEventListener("pagehide", this, true);
|
||||
this.clearPseudoClassLocks();
|
||||
} else {
|
||||
// Update the store before closing.
|
||||
if (this.selection) {
|
||||
|
@ -566,7 +570,7 @@ InspectorUI.prototype = {
|
|||
this.inspecting = false;
|
||||
this.toolsDim(false);
|
||||
if (this.highlighter.getNode()) {
|
||||
this.select(this.highlighter.getNode(), true, true, !aPreventScroll);
|
||||
this.select(this.highlighter.getNode(), true, !aPreventScroll);
|
||||
} else {
|
||||
this.select(null, true, true);
|
||||
}
|
||||
|
@ -574,15 +578,17 @@ InspectorUI.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Select an object in the tree view.
|
||||
* Select an object in the inspector.
|
||||
* @param aNode
|
||||
* node to inspect
|
||||
* @param forceUpdate
|
||||
* force an update?
|
||||
* @param aScroll boolean
|
||||
* scroll the tree panel?
|
||||
* @param aFrom [optional] string
|
||||
* which part of the UI the selection occured from
|
||||
*/
|
||||
select: function IUI_select(aNode, forceUpdate, aScroll)
|
||||
select: function IUI_select(aNode, forceUpdate, aScroll, aFrom)
|
||||
{
|
||||
// if currently editing an attribute value, using the
|
||||
// highlighter dismisses the editor
|
||||
|
@ -593,6 +599,10 @@ InspectorUI.prototype = {
|
|||
aNode = this.defaultSelection;
|
||||
|
||||
if (forceUpdate || aNode != this.selection) {
|
||||
if (aFrom != "breadcrumbs") {
|
||||
this.clearPseudoClassLocks();
|
||||
}
|
||||
|
||||
this.selection = aNode;
|
||||
if (!this.inspecting) {
|
||||
this.highlighter.highlight(this.selection);
|
||||
|
@ -605,6 +615,41 @@ InspectorUI.prototype = {
|
|||
|
||||
this.toolsSelect(aScroll);
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle the pseudo-class lock on the currently inspected element. If the
|
||||
* pseudo-class is :hover or :active, that pseudo-class will also be toggled
|
||||
* on every ancestor of the element, mirroring real :hover and :active
|
||||
* behavior.
|
||||
*
|
||||
* @param aPseudo the pseudo-class lock to toggle, e.g. ":hover"
|
||||
*/
|
||||
togglePseudoClassLock: function IUI_togglePseudoClassLock(aPseudo)
|
||||
{
|
||||
if (DOMUtils.hasPseudoClassLock(this.selection, aPseudo)) {
|
||||
this.breadcrumbs.nodeHierarchy.forEach(function(crumb) {
|
||||
DOMUtils.removePseudoClassLock(crumb.node, aPseudo);
|
||||
});
|
||||
} else {
|
||||
let hierarchical = aPseudo == ":hover" || aPseudo == ":active";
|
||||
let node = this.selection;
|
||||
do {
|
||||
DOMUtils.addPseudoClassLock(node, aPseudo);
|
||||
node = node.parentNode;
|
||||
} while (hierarchical && node.parentNode)
|
||||
}
|
||||
this.nodeChanged();
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all pseudo-class locks applied to elements in the node hierarchy
|
||||
*/
|
||||
clearPseudoClassLocks: function IUI_clearPseudoClassLocks()
|
||||
{
|
||||
this.breadcrumbs.nodeHierarchy.forEach(function(crumb) {
|
||||
DOMUtils.clearPseudoClassLocks(crumb.node);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the highlighted node is changed by a tool.
|
||||
|
@ -616,6 +661,7 @@ InspectorUI.prototype = {
|
|||
nodeChanged: function IUI_nodeChanged(aUpdater)
|
||||
{
|
||||
this.highlighter.invalidateSize();
|
||||
this.breadcrumbs.updateSelectors();
|
||||
this.toolsOnChanged(aUpdater);
|
||||
},
|
||||
|
||||
|
@ -641,6 +687,10 @@ InspectorUI.prototype = {
|
|||
self.select(self.highlighter.getNode(), false, false);
|
||||
});
|
||||
|
||||
this.highlighter.addListener("pseudoclasstoggled", function(aPseudo) {
|
||||
self.togglePseudoClassLock(aPseudo);
|
||||
});
|
||||
|
||||
if (this.store.getValue(this.winID, "inspecting")) {
|
||||
this.startInspecting();
|
||||
this.highlighter.unlock();
|
||||
|
@ -911,6 +961,15 @@ InspectorUI.prototype = {
|
|||
if (this.ruleView)
|
||||
this.ruleView.highlight(aNode);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the rules for the current node in the Css Rule View.
|
||||
*/
|
||||
changeInRuleView: function IUI_selectInRuleView()
|
||||
{
|
||||
if (this.ruleView)
|
||||
this.ruleView.nodeChanged();
|
||||
},
|
||||
|
||||
ruleViewChanged: function IUI_ruleViewChanged()
|
||||
{
|
||||
|
@ -1336,7 +1395,7 @@ InspectorUI.prototype = {
|
|||
toolsOnChanged: function IUI_toolsChanged(aUpdater)
|
||||
{
|
||||
this.toolsDo(function IUI_toolsOnChanged(aTool) {
|
||||
if (aTool.isOpen && ("onChanged" in aTool) && aTool != aUpdater) {
|
||||
if (("onChanged" in aTool) && aTool != aUpdater) {
|
||||
aTool.onChanged.call(aTool.context);
|
||||
}
|
||||
});
|
||||
|
@ -1730,6 +1789,13 @@ HTMLBreadcrumbs.prototype = {
|
|||
for (let i = 0; i < aNode.classList.length; i++) {
|
||||
text += "." + aNode.classList[i];
|
||||
}
|
||||
for (let i = 0; i < PSEUDO_CLASSES.length; i++) {
|
||||
let pseudo = PSEUDO_CLASSES[i];
|
||||
if (DOMUtils.hasPseudoClassLock(aNode, pseudo)) {
|
||||
text += pseudo;
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
|
||||
|
@ -1755,6 +1821,9 @@ HTMLBreadcrumbs.prototype = {
|
|||
|
||||
let classesLabel = this.IUI.chromeDoc.createElement("label");
|
||||
classesLabel.className = "inspector-breadcrumbs-classes plain";
|
||||
|
||||
let pseudosLabel = this.IUI.chromeDoc.createElement("label");
|
||||
pseudosLabel.className = "inspector-breadcrumbs-pseudo-classes plain";
|
||||
|
||||
tagLabel.textContent = aNode.tagName.toLowerCase();
|
||||
idLabel.textContent = aNode.id ? ("#" + aNode.id) : "";
|
||||
|
@ -1765,9 +1834,15 @@ HTMLBreadcrumbs.prototype = {
|
|||
}
|
||||
classesLabel.textContent = classesText;
|
||||
|
||||
let pseudos = PSEUDO_CLASSES.filter(function(pseudo) {
|
||||
return DOMUtils.hasPseudoClassLock(aNode, pseudo);
|
||||
}, this);
|
||||
pseudosLabel.textContent = pseudos.join("");
|
||||
|
||||
fragment.appendChild(tagLabel);
|
||||
fragment.appendChild(idLabel);
|
||||
fragment.appendChild(classesLabel);
|
||||
fragment.appendChild(pseudosLabel);
|
||||
|
||||
return fragment;
|
||||
},
|
||||
|
@ -1807,7 +1882,7 @@ HTMLBreadcrumbs.prototype = {
|
|||
|
||||
item.onmouseup = (function(aNode) {
|
||||
return function() {
|
||||
inspector.select(aNode, true, true);
|
||||
inspector.select(aNode, true, true, "breadcrumbs");
|
||||
}
|
||||
})(nodes[i]);
|
||||
|
||||
|
@ -1961,7 +2036,7 @@ HTMLBreadcrumbs.prototype = {
|
|||
|
||||
button.onBreadcrumbsClick = function onBreadcrumbsClick() {
|
||||
inspector.stopInspecting();
|
||||
inspector.select(aNode, true, true);
|
||||
inspector.select(aNode, true, true, "breadcrumbs");
|
||||
};
|
||||
|
||||
button.onclick = (function _onBreadcrumbsRightClick(aEvent) {
|
||||
|
@ -2076,6 +2151,20 @@ HTMLBreadcrumbs.prototype = {
|
|||
let element = this.nodeHierarchy[this.currentIndex].button;
|
||||
scrollbox.ensureElementIsVisible(element);
|
||||
},
|
||||
|
||||
updateSelectors: function BC_updateSelectors()
|
||||
{
|
||||
for (let i = this.nodeHierarchy.length - 1; i >= 0; i--) {
|
||||
let crumb = this.nodeHierarchy[i];
|
||||
let button = crumb.button;
|
||||
|
||||
while(button.hasChildNodes()) {
|
||||
button.removeChild(button.firstChild);
|
||||
}
|
||||
button.appendChild(this.prettyPrintNodeAsXUL(crumb.node));
|
||||
button.setAttribute("tooltiptext", this.prettyPrintNodeAsText(crumb.node));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the breadcrumbs display when a new node is selected.
|
||||
|
@ -2117,6 +2206,8 @@ HTMLBreadcrumbs.prototype = {
|
|||
|
||||
// Make sure the selected node and its neighbours are visible.
|
||||
this.scroll();
|
||||
|
||||
this.updateSelectors();
|
||||
},
|
||||
|
||||
}
|
||||
|
@ -2136,3 +2227,6 @@ XPCOMUtils.defineLazyGetter(this, "StyleInspector", function () {
|
|||
return obj.StyleInspector;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "DOMUtils", function () {
|
||||
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
});
|
||||
|
|
|
@ -72,6 +72,7 @@ _BROWSER_FILES = \
|
|||
browser_inspector_invalidate.js \
|
||||
browser_inspector_sidebarstate.js \
|
||||
browser_inspector_treePanel_menu.js \
|
||||
browser_inspector_pseudoclass_lock.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
|
||||
let doc;
|
||||
let div;
|
||||
|
||||
let pseudo = ":hover";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
ignoreAllUncaughtExceptions();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,pseudo-class lock tests";
|
||||
}
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
div = doc.createElement("div");
|
||||
div.textContent = "test div";
|
||||
|
||||
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);
|
||||
|
||||
setupTests();
|
||||
}
|
||||
|
||||
function setupTests()
|
||||
{
|
||||
Services.obs.addObserver(selectNode,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
InspectorUI.openInspectorUI();
|
||||
}
|
||||
|
||||
function selectNode()
|
||||
{
|
||||
Services.obs.removeObserver(selectNode,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
|
||||
|
||||
executeSoon(function() {
|
||||
InspectorUI.highlighter.addListener("nodeselected", openRuleView);
|
||||
InspectorUI.inspectNode(div);
|
||||
});
|
||||
}
|
||||
|
||||
function openRuleView()
|
||||
{
|
||||
Services.obs.addObserver(performTests,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
|
||||
|
||||
InspectorUI.showSidebar();
|
||||
InspectorUI.openRuleView();
|
||||
}
|
||||
|
||||
function performTests()
|
||||
{
|
||||
Services.obs.removeObserver(performTests,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY);
|
||||
|
||||
InspectorUI.highlighter.removeListener("nodeselected", performTests);
|
||||
|
||||
// toggle the class
|
||||
InspectorUI.highlighter.pseudoClassLockToggled(pseudo);
|
||||
|
||||
testAdded();
|
||||
|
||||
// toggle the lock off
|
||||
InspectorUI.highlighter.pseudoClassLockToggled(pseudo);
|
||||
|
||||
testRemoved();
|
||||
testRemovedFromUI();
|
||||
|
||||
// toggle it back on
|
||||
InspectorUI.highlighter.pseudoClassLockToggled(pseudo);
|
||||
|
||||
// close the inspector
|
||||
Services.obs.addObserver(testInspectorClosed,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
|
||||
InspectorUI.closeInspectorUI();
|
||||
}
|
||||
|
||||
function testAdded()
|
||||
{
|
||||
// lock is applied to it and ancestors
|
||||
let node = div;
|
||||
do {
|
||||
is(DOMUtils.hasPseudoClassLock(node, pseudo), true,
|
||||
"pseudo-class lock has been applied");
|
||||
node = node.parentNode;
|
||||
} while (node.parentNode)
|
||||
|
||||
// infobar selector contains pseudo-class
|
||||
let pseudoClassesBox = document.getElementById("highlighter-nodeinfobar-pseudo-classes");
|
||||
is(pseudoClassesBox.textContent, pseudo, "pseudo-class in infobar selector");
|
||||
|
||||
// ruleview contains pseudo-class rule
|
||||
is(InspectorUI.ruleView.element.children.length, 3,
|
||||
"rule view is showing 3 rules for pseudo-class locked div");
|
||||
|
||||
is(InspectorUI.ruleView.element.children[1]._ruleEditor.rule.selectorText,
|
||||
"div:hover", "rule view is showing " + pseudo + " rule");
|
||||
}
|
||||
|
||||
function testRemoved()
|
||||
{
|
||||
// lock removed from node and ancestors
|
||||
let node = div;
|
||||
do {
|
||||
is(DOMUtils.hasPseudoClassLock(node, pseudo), false,
|
||||
"pseudo-class lock has been removed");
|
||||
node = node.parentNode;
|
||||
} while (node.parentNode)
|
||||
}
|
||||
|
||||
function testRemovedFromUI()
|
||||
{
|
||||
// infobar selector doesn't contain pseudo-class
|
||||
let pseudoClassesBox = document.getElementById("highlighter-nodeinfobar-pseudo-classes");
|
||||
is(pseudoClassesBox.textContent, "", "pseudo-class removed from infobar selector");
|
||||
|
||||
// ruleview no longer contains pseudo-class rule
|
||||
is(InspectorUI.ruleView.element.children.length, 2,
|
||||
"rule view is showing 2 rules after removing lock");
|
||||
}
|
||||
|
||||
function testInspectorClosed()
|
||||
{
|
||||
Services.obs.removeObserver(testInspectorClosed,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED);
|
||||
|
||||
testRemoved();
|
||||
|
||||
finishUp();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
doc = div = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
|
@ -116,7 +116,7 @@ function ElementStyle(aElement, aStore)
|
|||
// how their .style attribute reflects them as computed values.
|
||||
this.dummyElement = doc.createElementNS(this.element.namespaceURI,
|
||||
this.element.tagName);
|
||||
this._populate();
|
||||
this.populate();
|
||||
}
|
||||
// We're exporting _ElementStyle for unit tests.
|
||||
var _ElementStyle = ElementStyle;
|
||||
|
@ -147,7 +147,7 @@ ElementStyle.prototype = {
|
|||
* Refresh the list of rules to be displayed for the active element.
|
||||
* Upon completion, this.rules[] will hold a list of Rule objects.
|
||||
*/
|
||||
_populate: function ElementStyle_populate()
|
||||
populate: function ElementStyle_populate()
|
||||
{
|
||||
this.rules = [];
|
||||
|
||||
|
@ -713,15 +713,33 @@ CssRuleView.prototype = {
|
|||
|
||||
this._createEditors();
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the rules for the currently highlighted element.
|
||||
*/
|
||||
nodeChanged: function CssRuleView_nodeChanged()
|
||||
{
|
||||
this._clearRules();
|
||||
this._elementStyle.populate();
|
||||
this._createEditors();
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear the rules.
|
||||
*/
|
||||
_clearRules: function CssRuleView_clearRules()
|
||||
{
|
||||
while (this.element.hasChildNodes()) {
|
||||
this.element.removeChild(this.element.lastChild);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear the rule view.
|
||||
*/
|
||||
clear: function CssRuleView_clear()
|
||||
{
|
||||
while (this.element.hasChildNodes()) {
|
||||
this.element.removeChild(this.element.lastChild);
|
||||
}
|
||||
this._clearRules();
|
||||
this._viewedElement = null;
|
||||
this._elementStyle = null;
|
||||
},
|
||||
|
|
|
@ -2014,6 +2014,10 @@ html|*#highlighter-nodeinfobar-id {
|
|||
color: hsl(90, 79%, 52%);
|
||||
}
|
||||
|
||||
html|*#highlighter-nodeinfobar-pseudo-classes {
|
||||
color: hsl(20, 100%, 70%);
|
||||
}
|
||||
|
||||
/* Highlighter - Node Infobar - box & arrow */
|
||||
|
||||
#highlighter-nodeinfobar {
|
||||
|
@ -2118,11 +2122,19 @@ html|*#highlighter-nodeinfobar-id {
|
|||
color: hsl(205,100%,70%);
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[checked] > .inspector-breadcrumbs-pseudo-classes {
|
||||
color: hsl(20, 100%, 70%);
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-id,
|
||||
.inspector-breadcrumbs-classes {
|
||||
color: #8d99a6;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-pseudo-classes {
|
||||
color: hsl(20, 100%, 85%);
|
||||
}
|
||||
|
||||
/* Highlighter toolbar - breadcrumbs - LTR */
|
||||
|
||||
.inspector-breadcrumbs-button:-moz-locale-dir(ltr):first-of-type {
|
||||
|
|
|
@ -2761,6 +2761,10 @@ html|*#highlighter-nodeinfobar-id {
|
|||
color: hsl(90, 79%, 52%);
|
||||
}
|
||||
|
||||
html|*#highlighter-nodeinfobar-pseudo-classes {
|
||||
color: hsl(20, 100%, 70%);
|
||||
}
|
||||
|
||||
/* Highlighter - Node Infobar - box & arrow */
|
||||
|
||||
#highlighter-nodeinfobar {
|
||||
|
@ -2859,11 +2863,19 @@ html|*#highlighter-nodeinfobar-id {
|
|||
color: hsl(205,100%,70%);
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[checked] > .inspector-breadcrumbs-pseudo-classes {
|
||||
color: hsl(20, 100%, 70%);
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-id,
|
||||
.inspector-breadcrumbs-classes {
|
||||
color: #8d99a6;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-pseudo-classes {
|
||||
color: hsl(20, 100%, 85%);
|
||||
}
|
||||
|
||||
/* Highlighter toolbar - breadcrumbs - LTR */
|
||||
|
||||
.inspector-breadcrumbs-button:-moz-locale-dir(ltr):first-of-type {
|
||||
|
|
|
@ -2709,6 +2709,10 @@ html|*#highlighter-nodeinfobar-id {
|
|||
color: hsl(90, 79%, 52%);
|
||||
}
|
||||
|
||||
html|*#highlighter-nodeinfobar-pseudo-classes {
|
||||
color: hsl(20, 100%, 70%);
|
||||
}
|
||||
|
||||
/* Highlighter - Node Infobar - box & arrow */
|
||||
|
||||
#highlighter-nodeinfobar {
|
||||
|
@ -2813,11 +2817,19 @@ html|*#highlighter-nodeinfobar-id {
|
|||
color: hsl(200,100%,70%);
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-button[checked] > .inspector-breadcrumbs-pseudo-classes {
|
||||
color: hsl(20, 100%, 70%);
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-id,
|
||||
.inspector-breadcrumbs-classes {
|
||||
color: #8d99a6;
|
||||
}
|
||||
|
||||
.inspector-breadcrumbs-pseudo-classes {
|
||||
color: hsl(20, 100%, 85%);
|
||||
}
|
||||
|
||||
/* Highlighter toolbar - breadcrumbs - LTR */
|
||||
|
||||
.inspector-breadcrumbs-button:-moz-locale-dir(ltr):first-of-type {
|
||||
|
|
Загрузка…
Ссылка в новой задаче