Bug 707809 - Refactor creation of registered sidebar tools iframes in InspectorUI. r=robcee

This commit is contained in:
Dave Camp 2012-04-19 11:04:46 -07:00
parent e6d45d09f4
commit 7885fece64
33 changed files with 1089 additions and 1612 deletions

View File

@ -26,6 +26,7 @@
* Julian Viereck <jviereck@mozilla.com> * Julian Viereck <jviereck@mozilla.com>
* Paul Rouget <paul@mozilla.com> * Paul Rouget <paul@mozilla.com>
* Kyle Simpson <getify@mozilla.com> * Kyle Simpson <getify@mozilla.com>
* Dave Camp <dcamp@mozilla.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -46,6 +47,7 @@ const Cu = Components.utils;
Cu.import("resource:///modules/domplate.jsm"); Cu.import("resource:///modules/domplate.jsm");
Cu.import("resource:///modules/InsideOutBox.jsm"); Cu.import("resource:///modules/InsideOutBox.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/inspector.jsm");
var EXPORTED_SYMBOLS = ["TreePanel", "DOMHelpers"]; var EXPORTED_SYMBOLS = ["TreePanel", "DOMHelpers"];
@ -122,8 +124,10 @@ TreePanel.prototype = {
delete this.initializingTreePanel; delete this.initializingTreePanel;
Services.obs.notifyObservers(null, Services.obs.notifyObservers(null,
this.IUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY, null); this.IUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY, null);
if (this.IUI.selection) if (this.pendingSelection) {
this.select(this.IUI.selection, true); this.select(this.pendingSelection.node, this.pendingSelection.scroll);
delete this.pendingSelection;
}
}, },
/** /**
@ -219,6 +223,11 @@ TreePanel.prototype = {
delete this.treeBrowserDocument; delete this.treeBrowserDocument;
} }
if (this.ioBox) {
this.ioBox.destroy();
delete this.ioBox;
}
this.treeLoaded = false; this.treeLoaded = false;
}, },
@ -572,8 +581,11 @@ TreePanel.prototype = {
*/ */
select: function TP_select(aNode, aScroll) select: function TP_select(aNode, aScroll)
{ {
if (this.ioBox) if (this.ioBox) {
this.ioBox.select(aNode, true, true, aScroll); this.ioBox.select(aNode, true, true, aScroll);
} else {
this.pendingSelection = { node: aNode, scroll: aScroll };
}
}, },
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -691,11 +703,6 @@ TreePanel.prototype = {
parent.removeChild(this.treeIFrame); parent.removeChild(this.treeIFrame);
delete this.treeIFrame; delete this.treeIFrame;
} }
if (this.ioBox) {
this.ioBox.destroy();
delete this.ioBox;
}
} }
}; };

File diff suppressed because it is too large Load Diff

View File

@ -54,7 +54,6 @@ _BROWSER_FILES = \
browser_inspector_treePanel_output.js \ browser_inspector_treePanel_output.js \
browser_inspector_treePanel_input.html \ browser_inspector_treePanel_input.html \
browser_inspector_treePanel_result.html \ browser_inspector_treePanel_result.html \
browser_inspector_registertools.js \
browser_inspector_bug_665880.js \ browser_inspector_bug_665880.js \
browser_inspector_bug_674871.js \ browser_inspector_bug_674871.js \
browser_inspector_editor.js \ browser_inspector_editor.js \
@ -69,7 +68,6 @@ _BROWSER_FILES = \
browser_inspector_bug_699308_iframe_navigation.js \ browser_inspector_bug_699308_iframe_navigation.js \
browser_inspector_changes.js \ browser_inspector_changes.js \
browser_inspector_ruleviewstore.js \ browser_inspector_ruleviewstore.js \
browser_inspector_duplicate_ruleview.js \
browser_inspector_invalidate.js \ browser_inspector_invalidate.js \
browser_inspector_sidebarstate.js \ browser_inspector_sidebarstate.js \
browser_inspector_treePanel_menu.js \ browser_inspector_treePanel_menu.js \

View File

@ -50,7 +50,7 @@ function createDocument()
function getInspectorProp(aName) function getInspectorProp(aName)
{ {
for each (let view in InspectorUI.stylePanel.cssHtmlTree.propertyViews) { for each (let view in computedViewTree().propertyViews) {
if (view.name == aName) { if (view.name == aName) {
return view; return view;
} }
@ -79,18 +79,16 @@ function runInspectorTests()
// Start up the style inspector panel... // Start up the style inspector panel...
Services.obs.addObserver(stylePanelTests, "StyleInspector-populated", false); Services.obs.addObserver(stylePanelTests, "StyleInspector-populated", false);
executeSoon(function() { InspectorUI.sidebar.show();
InspectorUI.showSidebar(); InspectorUI.sidebar.activatePanel("computedview");
document.getElementById(InspectorUI.getToolbarButtonId("styleinspector")).click();
});
} }
function stylePanelTests() function stylePanelTests()
{ {
Services.obs.removeObserver(stylePanelTests, "StyleInspector-populated"); Services.obs.removeObserver(stylePanelTests, "StyleInspector-populated");
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open"); ok(InspectorUI.sidebar.visible, "Inspector Sidebar is open");
ok(InspectorUI.stylePanel.cssHtmlTree, "Style Panel has a cssHtmlTree"); ok(computedViewTree(), "Style Panel has a cssHtmlTree");
let propView = getInspectorProp("font-size"); let propView = getInspectorProp("font-size");
is(propView.value, "10px", "Style inspector should be showing the correct font size."); is(propView.value, "10px", "Style inspector should be showing the correct font size.");
@ -114,11 +112,13 @@ function stylePanelAfterChange()
function stylePanelNotActive() function stylePanelNotActive()
{ {
// Tests changes made while the style panel is not active. // Tests changes made while the style panel is not active.
InspectorUI.ruleButton.click(); InspectorUI.sidebar.activatePanel("ruleview");
executeSoon(function() { executeSoon(function() {
testDiv.style.fontSize = "20px";
Services.obs.addObserver(stylePanelAfterSwitch, "StyleInspector-populated", false); Services.obs.addObserver(stylePanelAfterSwitch, "StyleInspector-populated", false);
document.getElementById(InspectorUI.getToolbarButtonId("styleinspector")).click(); testDiv.style.fontSize = "20px";
InspectorUI.nodeChanged();
InspectorUI.sidebar.activatePanel("computedview");
}); });
} }

View File

@ -1,128 +0,0 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let div;
let tab1;
let tab2;
let tab1window;
function inspectorTabOpen1()
{
ok(window.InspectorUI, "InspectorUI variable exists");
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(InspectorUI.store.isEmpty(), "Inspector.store is empty");
Services.obs.addObserver(inspectorUIOpen1,
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
InspectorUI.openInspectorUI();
}
function inspectorUIOpen1()
{
Services.obs.removeObserver(inspectorUIOpen1,
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
// Make sure the inspector is open.
ok(InspectorUI.inspecting, "Inspector is highlighting");
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
ok(!InspectorUI.store.isEmpty(), "InspectorUI.store is not empty");
is(InspectorUI.store.length, 1, "Inspector.store.length = 1");
// Highlight a node.
div = content.document.getElementsByTagName("div")[0];
InspectorUI.inspectNode(div);
is(InspectorUI.selection, div, "selection matches the div element");
Services.obs.addObserver(inspectorRuleViewOpened,
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
InspectorUI.showSidebar();
InspectorUI.openRuleView();
}
function inspectorRuleViewOpened() {
Services.obs.removeObserver(inspectorRuleViewOpened,
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY);
// Open the second tab.
tab2 = gBrowser.addTab();
gBrowser.selectedTab = tab2;
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
true);
waitForFocus(inspectorTabOpen2, content);
}, true);
content.location = "data:text/html,<p>tab 2: the inspector should close now";
}
function inspectorTabOpen2()
{
// Make sure the inspector is closed.
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(!InspectorUI.treePanel, "Inspector Tree Panel is closed");
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
is(InspectorUI.store.length, 1, "Inspector.store.length = 1");
Services.obs.addObserver(inspectorFocusTab1,
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
// Switch back to tab 1.
executeSoon(function() {
gBrowser.selectedTab = tab1;
});
}
function inspectorFocusTab1()
{
Services.obs.removeObserver(inspectorFocusTab1,
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
Services.obs.addObserver(inspectorRuleTrap,
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
// Make sure the inspector is open.
ok(InspectorUI.inspecting, "Inspector is highlighting");
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
is(InspectorUI.store.length, 1, "Inspector.store.length = 1");
is(InspectorUI.selection, div, "selection matches the div element");
ok(InspectorUI.isSidebarOpen, "sidebar is open");
ok(InspectorUI.isRuleViewOpen(), "rule view is open");
// The rule view element plus its popupSet
is(InspectorUI.ruleView.doc.documentElement.children.length, 2, "RuleView elements.length == 2");
requestLongerTimeout(4);
executeSoon(function() {
InspectorUI.closeInspectorUI();
gBrowser.removeCurrentTab(); // tab 1
gBrowser.removeCurrentTab(); // tab 2
finish();
});
}
function inspectorRuleTrap()
{
Services.obs.removeObserver(inspectorRuleTrap,
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
is(InspectorUI.ruleView.doc.documentElement.children.length, 1, "RuleView elements.length == 1");
}
function test()
{
waitForExplicitFinish();
tab1 = gBrowser.addTab();
gBrowser.selectedTab = tab1;
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
true);
waitForFocus(inspectorTabOpen1, content);
}, true);
content.location = "data:text/html,<p>tab switching tests for inspector" +
"<div>tab 1</div>";
}

View File

@ -77,8 +77,8 @@ function doEditorTestSteps()
EventUtils.synthesizeMouse(attrValNode_id, 2, 2, {clickCount: 2}, attrValNode_id.ownerDocument.defaultView); EventUtils.synthesizeMouse(attrValNode_id, 2, 2, {clickCount: 2}, attrValNode_id.ownerDocument.defaultView);
}); });
yield; // End of Step 1
yield; // End of Step 1
// Step 2: validate editing session, enter new attribute value into editor, and save input // Step 2: validate editing session, enter new attribute value into editor, and save input
ok(InspectorUI.treePanel.editingContext, "Step 2: editor session started"); ok(InspectorUI.treePanel.editingContext, "Step 2: editor session started");

View File

@ -89,25 +89,21 @@ function treePanelTests()
{ {
Services.obs.removeObserver(treePanelTests, Services.obs.removeObserver(treePanelTests,
InspectorUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY); InspectorUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY);
Services.obs.addObserver(stylePanelTests,
"StyleInspector-opened", false);
ok(InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is open"); ok(InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is open");
executeSoon(function() { InspectorUI.sidebar.show();
InspectorUI.showSidebar(); InspectorUI.currentInspector.once("sidebaractivated-computedview",
document.getElementById(InspectorUI.getToolbarButtonId("styleinspector")).click(); stylePanelTests)
}); InspectorUI.sidebar.activatePanel("computedview");
} }
function stylePanelTests() function stylePanelTests()
{ {
Services.obs.removeObserver(stylePanelTests, "StyleInspector-opened"); ok(InspectorUI.sidebar.visible, "Inspector Sidebar is open");
is(InspectorUI.sidebar.activePanel, "computedview", "Computed View is open");
ok(computedViewTree(), "Computed view has a cssHtmlTree");
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open"); InspectorUI.sidebar.activatePanel("ruleview");
ok(InspectorUI.stylePanel.cssHtmlTree, "Style Panel has a cssHtmlTree");
InspectorUI.ruleButton.click();
executeSoon(function() { executeSoon(function() {
ruleViewTests(); ruleViewTests();
}); });
@ -118,8 +114,8 @@ function ruleViewTests()
Services.obs.addObserver(runContextMenuTest, Services.obs.addObserver(runContextMenuTest,
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false); InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
ok(InspectorUI.isRuleViewOpen(), "Rule View is open"); is(InspectorUI.sidebar.activePanel, "ruleview", "Rule View is open");
ok(InspectorUI.ruleView, "InspectorUI has a cssRuleView"); ok(ruleView(), "InspectorUI has a cssRuleView");
executeSoon(function() { executeSoon(function() {
InspectorUI.closeInspectorUI(); InspectorUI.closeInspectorUI();
@ -152,8 +148,6 @@ function inspectNodesFromContextTest()
Services.obs.addObserver(openInspectorForContextTest, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false); Services.obs.addObserver(openInspectorForContextTest, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
ok(!InspectorUI.inspecting, "Inspector is not actively highlighting"); ok(!InspectorUI.inspecting, "Inspector is not actively highlighting");
is(InspectorUI.selection, salutation, "Inspector is highlighting salutation"); is(InspectorUI.selection, salutation, "Inspector is highlighting salutation");
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is closed");
ok(!InspectorUI.stylePanel.isOpen(), "Inspector Style Panel is closed");
executeSoon(function() { executeSoon(function() {
InspectorUI.closeInspectorUI(true); InspectorUI.closeInspectorUI(true);
}); });
@ -207,11 +201,7 @@ function finishInspectorTests(subject, topic, aWinIdString)
ok(!InspectorUI.highlighter, "Highlighter is gone"); ok(!InspectorUI.highlighter, "Highlighter is gone");
ok(!InspectorUI.treePanel, "Inspector Tree Panel is closed"); ok(!InspectorUI.treePanel, "Inspector Tree Panel is closed");
ok(!InspectorUI.inspecting, "Inspector is not inspecting"); ok(!InspectorUI.inspecting, "Inspector is not inspecting");
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is closed"); ok(!InspectorUI._sidebar, "Inspector Sidebar is closed");
ok(!InspectorUI.stylePanel, "Inspector Style Panel is gone");
ok(!InspectorUI.ruleView, "Inspector Rule View is gone");
is(InspectorUI.sidebarToolbar.children.length, 0, "No items in the Sidebar toolbar");
is(InspectorUI.sidebarDeck.children.length, 0, "No items in the Sidebar deck");
ok(!InspectorUI.toolbar, "toolbar is hidden"); ok(!InspectorUI.toolbar, "toolbar is hidden");
Services.obs.removeObserver(inspectNodesFromContextTestTrap, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED); Services.obs.removeObserver(inspectNodesFromContextTestTrap, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);

View File

@ -51,26 +51,22 @@ function selectNode()
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED); InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
executeSoon(function() { executeSoon(function() {
InspectorUI.highlighter.addListener("nodeselected", openRuleView); InspectorUI.highlighter.addListener("locked", openRuleView);
InspectorUI.inspectNode(div); InspectorUI.inspectNode(div);
InspectorUI.stopInspecting();
}); });
} }
function openRuleView() function openRuleView()
{ {
Services.obs.addObserver(performTests, InspectorUI.sidebar.show();
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false); InspectorUI.currentInspector.once("sidebaractivated-ruleview", performTests);
InspectorUI.sidebar.activatePanel("ruleview");
InspectorUI.showSidebar();
InspectorUI.openRuleView();
} }
function performTests() function performTests()
{ {
Services.obs.removeObserver(performTests, InspectorUI.highlighter.removeListener("locked", performTests);
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY);
InspectorUI.highlighter.removeListener("nodeselected", performTests);
// toggle the class // toggle the class
InspectorUI.highlighter.pseudoClassLockToggled(pseudo); InspectorUI.highlighter.pseudoClassLockToggled(pseudo);
@ -107,10 +103,10 @@ function testAdded()
is(pseudoClassesBox.textContent, pseudo, "pseudo-class in infobar selector"); is(pseudoClassesBox.textContent, pseudo, "pseudo-class in infobar selector");
// ruleview contains pseudo-class rule // ruleview contains pseudo-class rule
is(InspectorUI.ruleView.element.children.length, 3, is(ruleView().element.children.length, 3,
"rule view is showing 3 rules for pseudo-class locked div"); "rule view is showing 3 rules for pseudo-class locked div");
is(InspectorUI.ruleView.element.children[1]._ruleEditor.rule.selectorText, is(ruleView().element.children[1]._ruleEditor.rule.selectorText,
"div:hover", "rule view is showing " + pseudo + " rule"); "div:hover", "rule view is showing " + pseudo + " rule");
} }
@ -132,7 +128,7 @@ function testRemovedFromUI()
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 // ruleview no longer contains pseudo-class rule
is(InspectorUI.ruleView.element.children.length, 2, is(ruleView().element.children.length, 2,
"rule view is showing 2 rules after removing lock"); "rule view is showing 2 rules after removing lock");
} }

View File

@ -1,254 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Inspector Highlighter Tests.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Ratcliffe <mratcliffe@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
let doc;
let h1;
let p2;
let toolsLength = 0;
let toolEvents = 0;
let tool1;
let tool2;
let tool3;
let initToolsMethod = InspectorUI.initTools;
function createDocument()
{
let div = doc.createElement("div");
h1 = doc.createElement("h1");
let p1 = doc.createElement("p");
p2 = doc.createElement("p");
let div2 = doc.createElement("div");
let p3 = doc.createElement("p");
doc.title = "Inspector Tree Selection Test";
h1.textContent = "Inspector Tree Selection Test";
p1.textContent = "This is some example text";
p2.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
"dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
"fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
p3.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
"dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
"fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
div.appendChild(h1);
div.appendChild(p1);
div.appendChild(p2);
div2.appendChild(p3);
doc.body.appendChild(div);
doc.body.appendChild(div2);
setupHighlighterTests();
}
function setupHighlighterTests()
{
ok(h1, "we have the header node");
Services.obs.addObserver(inspectorOpen, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
registerTools();
InspectorUI.toggleInspectorUI();
}
function inspectorOpen()
{
info("we received the inspector-opened notification");
Services.obs.removeObserver(inspectorOpen, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
toolsLength = InspectorUI.tools.length;
toolEvents = InspectorUI.toolEvents.length;
info("tools registered");
InspectorUI.highlighter.addListener("nodeselected", startToolTests);
InspectorUI.inspectNode(h1);
}
function startToolTests(evt)
{
InspectorUI.highlighter.removeListener("nodeselected", startToolTests);
InspectorUI.stopInspecting();
info("Getting InspectorUI.tools");
let tools = InspectorUI.tools;
tool1 = InspectorUI.tools["tool_1"];
tool2 = InspectorUI.tools["tool_2"];
tool3 = InspectorUI.tools["tool_3"];
info("Checking panel states 1");
ok(!tool1.isOpen, "Panel 1 is closed");
ok(!tool2.isOpen, "Panel 2 is closed");
ok(!tool3.isOpen, "Panel 3 is closed");
info("Calling show method for all tools");
InspectorUI.toolShow(tool1);
InspectorUI.toolShow(tool2);
InspectorUI.toolShow(tool3);
info("Checking panel states 2");
ok(tool1.isOpen, "Panel 1 is open");
ok(tool2.isOpen, "Panel 2 is open");
ok(tool3.isOpen, "Panel 3 is open");
info("Calling selectNode method for all tools, should see 3 selects");
InspectorUI.inspectNode(p2);
info("Calling hide method for all tools");
InspectorUI.toolHide(tool1);
InspectorUI.toolHide(tool2);
InspectorUI.toolHide(tool3);
info("Checking panel states 3");
ok(!tool1.isOpen, "Panel 1 is closed");
ok(!tool2.isOpen, "Panel 2 is closed");
ok(!tool3.isOpen, "Panel 3 is closed");
info("Showing tools 1 & 3");
InspectorUI.toolShow(tool1);
InspectorUI.toolShow(tool3);
info("Checking panel states 4");
ok(tool1.isOpen, "Panel 1 is open");
ok(!tool2.isOpen, "Panel 2 is closed");
ok(tool3.isOpen, "Panel 3 is open");
Services.obs.addObserver(unregisterTools, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
InspectorUI.closeInspectorUI(true);
}
function unregisterTools()
{
Services.obs.removeObserver(unregisterTools, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED);
let tools = InspectorUI.tools;
ok(!(tool1 in tools), "Tool 1 removed");
ok(!(tool2 in tools), "Tool 2 removed");
ok(!(tool3 in tools), "Tool 3 removed");
is(tools.length, toolsLength, "Number of Registered Tools matches original");
is(InspectorUI.toolEvents.length, toolEvents, "Number of tool events matches original");
finishUp();
}
function finishUp() {
gBrowser.removeCurrentTab();
InspectorUI.initTools = initToolsMethod;
finish();
}
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,registertool tests for inspector";
}
function registerTools()
{
InspectorUI.initTools = function() {
info("(re)registering tools");
registerTool(new testTool("tool_1", "Tool 1", "Tool 1 tooltip", "I"));
registerTool(new testTool("tool_2", "Tool 2", "Tool 2 tooltip", "J"));
registerTool(new testTool("tool_3", "Tool 3", "Tool 3 tooltip", "K"));
}
}
function registerTool(aTool)
{
InspectorUI.registerTool({
id: aTool.id,
label: aTool.label,
tooltiptext: aTool.tooltip,
accesskey: aTool.accesskey,
context: aTool,
get isOpen() aTool.isOpen(),
onSelect: aTool.selectNode,
show: aTool.show,
hide: aTool.hide,
unregister: aTool.destroy,
});
}
// Tool Object
function testTool(aToolId, aLabel, aTooltip, aAccesskey)
{
this.id = aToolId;
this.label = aLabel;
this.tooltip = aTooltip;
this.accesskey = aAccesskey;
this._isOpen = false;
}
testTool.prototype = {
isOpen: function BIR_isOpen() {
return this._isOpen;
},
selectNode: function BIR_selectNode(aNode) {
is(InspectorUI.selection, aNode,
"selectNode: currently selected node was passed: " + this.id);
},
show: function BIR_show(aNode) {
this._isOpen = true;
is(InspectorUI.selection, aNode,
"show: currently selected node was passed: " + this.id);
},
hide: function BIR_hide() {
info(this.id + " hide");
this._isOpen = false;
},
destroy: function BIR_destroy() {
info("tool destroyed " + this.id);
if (this.isOpen())
this.hide();
delete this.id;
delete this.label;
delete this.tooltip;
delete this.accesskey;
},
};

View File

@ -48,18 +48,7 @@ let tab1;
function waitForRuleView(aCallback) function waitForRuleView(aCallback)
{ {
if (InspectorUI.ruleView) { InspectorUI.currentInspector.once("sidebaractivated-ruleview", aCallback);
aCallback();
return;
}
let ruleViewFrame = InspectorUI.getToolIframe(InspectorUI.ruleViewObject);
ruleViewFrame.addEventListener("load", function(evt) {
ruleViewFrame.removeEventListener(evt.type, arguments.callee, true);
executeSoon(function() {
aCallback();
});
}, true);
} }
function inspectorTabOpen1() function inspectorTabOpen1()
@ -77,17 +66,17 @@ function inspectorUIOpen1()
// Highlight a node. // Highlight a node.
div = content.document.getElementsByTagName("div")[0]; div = content.document.getElementsByTagName("div")[0];
InspectorUI.inspectNode(div); InspectorUI.inspectNode(div);
InspectorUI.stopInspecting();
// Open the rule view sidebar. // Open the rule view sidebar.
waitForRuleView(ruleViewOpened1); waitForRuleView(ruleViewOpened1);
InspectorUI.sidebar.show();
InspectorUI.showSidebar(); InspectorUI.sidebar.activatePanel("ruleview");
InspectorUI.ruleButton.click();
} }
function ruleViewOpened1() function ruleViewOpened1()
{ {
let prop = InspectorUI.ruleView._elementStyle.rules[0].textProps[0]; let prop = ruleView()._elementStyle.rules[0].textProps[0];
is(prop.name, "background-color", "First prop is the background color prop."); is(prop.name, "background-color", "First prop is the background color prop.");
prop.setEnabled(false); prop.setEnabled(false);
@ -124,7 +113,7 @@ function inspectorFocusTab1()
function ruleViewOpened2() function ruleViewOpened2()
{ {
let prop = InspectorUI.ruleView._elementStyle.rules[0].textProps[0]; let prop = ruleView()._elementStyle.rules[0].textProps[0];
is(prop.name, "background-color", "First prop is the background color prop."); is(prop.name, "background-color", "First prop is the background color prop.");
ok(!prop.enabled, "First prop should be disabled."); ok(!prop.enabled, "First prop should be disabled.");

View File

@ -8,22 +8,21 @@ function createDocument()
doc.body.innerHTML = '<h1>Sidebar state test</h1>'; doc.body.innerHTML = '<h1>Sidebar state test</h1>';
doc.title = "Sidebar State Test"; doc.title = "Sidebar State Test";
// Open the sidebar and wait for the default view (the rule view) to show.
Services.obs.addObserver(inspectorRuleViewOpened,
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
InspectorUI.openInspectorUI(); InspectorUI.openInspectorUI();
InspectorUI.showSidebar();
// Open the sidebar and wait for the default view (the rule view) to show.
InspectorUI.currentInspector.once("sidebaractivated-ruleview", inspectorRuleViewOpened);
InspectorUI.sidebar.show();
InspectorUI.sidebar.activatePanel("ruleview");
} }
function inspectorRuleViewOpened() function inspectorRuleViewOpened()
{ {
Services.obs.removeObserver(inspectorRuleViewOpened, is(InspectorUI.sidebar.activePanel, "ruleview", "Rule View is selected by default");
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY);
is(InspectorUI.activeSidebarPanel, "ruleview", "Rule View is selected by default");
// Select the computed view and turn off the inspector. // Select the computed view and turn off the inspector.
InspectorUI.activateSidebarPanel("styleinspector"); InspectorUI.sidebar.activatePanel("computedview");
Services.obs.addObserver(inspectorClosed, Services.obs.addObserver(inspectorClosed,
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false); InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
@ -46,7 +45,7 @@ function computedViewPopulated()
{ {
Services.obs.removeObserver(computedViewPopulated, Services.obs.removeObserver(computedViewPopulated,
"StyleInspector-populated"); "StyleInspector-populated");
is(InspectorUI.activeSidebarPanel, "styleinspector", "Computed view is selected by default."); is(InspectorUI.sidebar.activePanel, "computedview", "Computed view is selected by default.");
finishTest(); finishTest();
} }

View File

@ -62,7 +62,7 @@ function inspectorUIOpen1()
// Make sure the inspector is open. // Make sure the inspector is open.
ok(InspectorUI.inspecting, "Inspector is highlighting"); ok(InspectorUI.inspecting, "Inspector is highlighting");
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open"); ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open"); ok(!InspectorUI.sidebar.visible, "Inspector Sidebar is not open");
ok(!InspectorUI.store.isEmpty(), "InspectorUI.store is not empty"); ok(!InspectorUI.store.isEmpty(), "InspectorUI.store is not empty");
is(InspectorUI.store.length, 1, "Inspector.store.length = 1"); is(InspectorUI.store.length, 1, "Inspector.store.length = 1");
@ -89,7 +89,6 @@ function inspectorTabOpen2()
// Make sure the inspector is closed. // Make sure the inspector is closed.
ok(!InspectorUI.inspecting, "Inspector is not highlighting"); ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(!InspectorUI.treePanel, "Inspector Tree Panel is closed"); ok(!InspectorUI.treePanel, "Inspector Tree Panel is closed");
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
is(InspectorUI.store.length, 1, "Inspector.store.length = 1"); is(InspectorUI.store.length, 1, "Inspector.store.length = 1");
// Activate the inspector again. // Activate the inspector again.
@ -151,24 +150,25 @@ function inspectorOpenTreePanelTab1()
is(InspectorUI.store.length, 2, "Inspector.store.length = 2"); is(InspectorUI.store.length, 2, "Inspector.store.length = 2");
is(InspectorUI.selection, div, "selection matches the div element"); is(InspectorUI.selection, div, "selection matches the div element");
Services.obs.addObserver(inspectorSidebarStyleView1, "StyleInspector-opened", false); InspectorUI.currentInspector.once("sidebaractivated-computedview",
inspectorSidebarStyleView1);
executeSoon(function() { executeSoon(function() {
InspectorUI.showSidebar(); InspectorUI.sidebar.show();
InspectorUI.activateSidebarPanel("styleinspector"); InspectorUI.sidebar.activatePanel("computedview");
}); });
} }
function inspectorSidebarStyleView1() function inspectorSidebarStyleView1()
{ {
Services.obs.removeObserver(inspectorSidebarStyleView1, "StyleInspector-opened"); ok(InspectorUI.sidebar.visible, "Inspector Sidebar is open");
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open"); ok(computedView(), "Inspector Has a computed view Instance");
ok(InspectorUI.stylePanel, "Inspector Has a Style Panel Instance");
InspectorUI.sidebarTools.forEach(function(aTool) { InspectorUI.sidebar._toolObjects().forEach(function (aTool) {
let btn = document.getElementById(InspectorUI.getToolbarButtonId(aTool.id)); let btn = aTool.button;
is(btn.hasAttribute("checked"), is(btn.hasAttribute("checked"),
(aTool == InspectorUI.stylePanel.registrationObject), (aTool.id == "computedview"),
"Button " + btn.id + " has correct checked attribute"); "Button " + btn.label + " has correct checked attribute");
}); });
// Switch back to tab 2. // Switch back to tab 2.
@ -185,7 +185,7 @@ function inspectorFocusTab2()
// Make sure the inspector is still open. // Make sure the inspector is still open.
ok(!InspectorUI.inspecting, "Inspector is not highlighting"); ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open"); ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open"); ok(!InspectorUI.sidebar.visible, "Inspector Sidebar is not open");
is(InspectorUI.store.length, 2, "Inspector.store.length is 2"); is(InspectorUI.store.length, 2, "Inspector.store.length is 2");
isnot(InspectorUI.selection, div, "selection does not match the div element"); isnot(InspectorUI.selection, div, "selection does not match the div element");
@ -214,13 +214,13 @@ function inspectorSecondFocusTab1()
is(InspectorUI.store.length, 2, "Inspector.store.length = 2"); is(InspectorUI.store.length, 2, "Inspector.store.length = 2");
is(InspectorUI.selection, div, "selection matches the div element"); is(InspectorUI.selection, div, "selection matches the div element");
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open"); ok(InspectorUI.sidebar.visible, "Inspector Sidebar is open");
ok(InspectorUI.stylePanel, "Inspector Has a Style Panel Instance"); ok(computedView(), "Inspector Has a Style Panel Instance");
InspectorUI.sidebarTools.forEach(function(aTool) { InspectorUI.sidebar._toolObjects().forEach(function(aTool) {
let btn = document.getElementById(InspectorUI.getToolbarButtonId(aTool.id)); let btn = aTool.button;
is(btn.hasAttribute("checked"), is(btn.hasAttribute("checked"),
(aTool == InspectorUI.stylePanel.registrationObject), (aTool.id == "computedview"),
"Button " + btn.id + " has correct checked attribute"); "Button " + btn.label + " has correct checked attribute");
}); });
// Switch back to tab 2. // Switch back to tab 2.

View File

@ -89,6 +89,20 @@ function midPoint(aPointA, aPointB)
return pointC; return pointC;
} }
function computedView()
{
return InspectorUI.sidebar._toolContext("computedview");
}
function computedViewTree()
{
return computedView().view;
}
function ruleView()
{
return InspectorUI.sidebar._toolContext("ruleview").view;
}
function synthesizeKeyFromKeyTag(aKeyId) { function synthesizeKeyFromKeyTag(aKeyId) {
let key = document.getElementById(aKeyId); let key = document.getElementById(aKeyId);
isnot(key, null, "Successfully retrieved the <key> node"); isnot(key, null, "Successfully retrieved the <key> node");

View File

@ -306,12 +306,10 @@ CssHtmlTree.prototype = {
this._refreshProcess = new UpdateProcess(this.win, CssHtmlTree.propertyNames, { this._refreshProcess = new UpdateProcess(this.win, CssHtmlTree.propertyNames, {
onItem: function(aPropertyName) { onItem: function(aPropertyName) {
// Per-item callback. // Per-item callback.
if (this.viewedElement != aElement || !this.styleInspector.isOpen()) {
return false;
}
let propView = new PropertyView(this, aPropertyName); let propView = new PropertyView(this, aPropertyName);
fragment.appendChild(propView.buildMain()); fragment.appendChild(propView.buildMain());
fragment.appendChild(propView.buildSelectorContainer()); fragment.appendChild(propView.buildSelectorContainer());
if (propView.visible) { if (propView.visible) {
this.numVisibleProperties++; this.numVisibleProperties++;
} }
@ -324,7 +322,14 @@ CssHtmlTree.prototype = {
this.propertyContainer.appendChild(fragment); this.propertyContainer.appendChild(fragment);
this.noResults.hidden = this.numVisibleProperties > 0; this.noResults.hidden = this.numVisibleProperties > 0;
this._refreshProcess = null; this._refreshProcess = null;
// If a refresh was scheduled during the building, complete it.
if (this._needsRefresh) {
delete this._needsRefresh;
this.refreshPanel();
} else {
Services.obs.notifyObservers(null, "StyleInspector-populated", null); Services.obs.notifyObservers(null, "StyleInspector-populated", null);
}
}.bind(this)}); }.bind(this)});
this._refreshProcess.schedule(); this._refreshProcess.schedule();
@ -336,6 +341,15 @@ CssHtmlTree.prototype = {
*/ */
refreshPanel: function CssHtmlTree_refreshPanel() refreshPanel: function CssHtmlTree_refreshPanel()
{ {
// If we're still in the process of creating the initial layout,
// leave it alone.
if (!this.htmlComplete) {
if (this._refreshProcess) {
this._needsRefresh = true;
}
return;
}
if (this._refreshProcess) { if (this._refreshProcess) {
this._refreshProcess.cancel(); this._refreshProcess.cancel();
} }
@ -355,7 +369,7 @@ CssHtmlTree.prototype = {
}.bind(this), }.bind(this),
onDone: function() { onDone: function() {
this._refreshProcess = null; this._refreshProcess = null;
this.noResults.hidden = this.numVisibleProperties > 0 this.noResults.hidden = this.numVisibleProperties > 0;
Services.obs.notifyObservers(null, "StyleInspector-populated", null); Services.obs.notifyObservers(null, "StyleInspector-populated", null);
}.bind(this) }.bind(this)
}); });
@ -1203,11 +1217,6 @@ SelectorView.prototype = {
result = CssLogic.getShortName(source); result = CssLogic.getShortName(source);
} }
aElement.parentNode.querySelector(".rule-link > a").
addEventListener("click", function(aEvent) {
this.tree.styleInspector.selectFromPath(source);
aEvent.preventDefault();
}.bind(this), false);
result += ".style"; result += ".style";
} }

View File

@ -648,6 +648,10 @@ CssLogic.prototype = {
this._passId++; this._passId++;
this._matchedRules = []; this._matchedRules = [];
if (!element) {
return;
}
do { do {
let status = this.viewedElement === element ? let status = this.viewedElement === element ?
CssLogic.STATUS.MATCHED : CssLogic.STATUS.PARENT_MATCH; CssLogic.STATUS.MATCHED : CssLogic.STATUS.PARENT_MATCH;

View File

@ -763,15 +763,15 @@ CssRuleView.prototype = {
this.clear(); this.clear();
if (this._elementStyle) {
delete this._elementStyle;
}
this._viewedElement = aElement; this._viewedElement = aElement;
if (!this._viewedElement) { if (!this._viewedElement) {
return; return;
} }
if (this._elementStyle) {
delete this._elementStyle.onChanged;
}
this._elementStyle = new ElementStyle(aElement, this.store); this._elementStyle = new ElementStyle(aElement, this.store);
this._elementStyle.onChanged = function() { this._elementStyle.onChanged = function() {
this._changed(); this._changed();

View File

@ -23,6 +23,7 @@
* Contributor(s): * Contributor(s):
* Mike Ratcliffe <mratcliffe@mozilla.com> (Original Author) * Mike Ratcliffe <mratcliffe@mozilla.com> (Original Author)
* Rob Campbell <rcampbell@mozilla.com> * Rob Campbell <rcampbell@mozilla.com>
* Dave Camp <dcamp@mozilla.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -43,277 +44,19 @@ const Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource:///modules/devtools/CssRuleView.jsm");
Cu.import("resource:///modules/inspector.jsm");
var EXPORTED_SYMBOLS = ["StyleInspector"]; // This module doesn't currently export any symbols directly, it only
// registers inspector tools.
var EXPORTED_SYMBOLS = [];
/** /**
* StyleInspector Constructor Function. * Lookup l10n string from a string bundle.
* @param {window} aContext, the chrome window context we're calling from.
* @param {InspectorUI} aIUI (optional) An InspectorUI instance if called from the
* Highlighter.
*/
function StyleInspector(aContext, aIUI)
{
this._init(aContext, aIUI);
}
StyleInspector.prototype = {
/**
* Initialization method called from constructor.
* @param {window} aContext, the chrome window context we're calling from.
* @param {InspectorUI} aIUI (optional) An InspectorUI instance if called from
* the Highlighter.
*/
_init: function SI__init(aContext, aIUI)
{
this.window = aContext;
this.IUI = aIUI;
this.document = this.window.document;
this.cssLogic = new CssLogic();
this.panelReady = false;
this.iframeReady = false;
// Were we invoked from the Highlighter?
if (this.IUI) {
this.openDocked = true;
let isOpen = this.isOpen.bind(this);
this.registrationObject = {
id: "styleinspector",
label: this.l10n("style.highlighter.button.label2"),
tooltiptext: this.l10n("style.highlighter.button.tooltip2"),
accesskey: this.l10n("style.highlighter.accesskey2"),
context: this,
get isOpen() isOpen(),
onSelect: this.selectNode,
onChanged: this.updateNode,
show: this.open,
hide: this.close,
dim: this.dimTool,
panel: null,
unregister: this.destroy,
sidebar: true,
};
// Register the registrationObject with the Highlighter
this.IUI.registerTool(this.registrationObject);
this.createSidebarContent(true);
}
},
/**
* Create the iframe in the IUI sidebar's tab panel.
* @param {Boolean} aPreserveOnHide Prevents destroy from being called.
*/
createSidebarContent: function SI_createSidebarContent(aPreserveOnHide)
{
this.preserveOnHide = !!aPreserveOnHide;
let boundIframeOnLoad = function loadedInitializeIframe() {
if (this.iframe &&
this.iframe.getAttribute("src") ==
"chrome://browser/content/devtools/csshtmltree.xul") {
let selectedNode = this.selectedNode || null;
this.cssHtmlTree = new CssHtmlTree(this);
this.cssLogic.highlight(selectedNode);
this.cssHtmlTree.highlight(selectedNode);
this.iframe.removeEventListener("load", boundIframeOnLoad, true);
this.iframeReady = true;
// Now that we've loaded, select any node we were previously asked
// to show.
this.selectNode(this.selectedNode);
Services.obs.notifyObservers(null, "StyleInspector-opened", null);
}
}.bind(this);
this.iframe = this.IUI.getToolIframe(this.registrationObject);
this.iframe.addEventListener("load", boundIframeOnLoad, true);
},
/**
* Factory method to create the actual style panel
* @param {Boolean} aPreserveOnHide Prevents destroy from being called
* onpopuphide. USE WITH CAUTION: When this value is set to true then you are
* responsible to manually call destroy from outside the style inspector.
* @param {function} aCallback (optional) callback to fire when ready.
*/
createPanel: function SI_createPanel(aPreserveOnHide, aCallback)
{
let popupSet = this.document.getElementById("mainPopupSet");
let panel = this.document.createElement("panel");
this.preserveOnHide = !!aPreserveOnHide;
panel.setAttribute("class", "styleInspector");
panel.setAttribute("orient", "vertical");
panel.setAttribute("ignorekeys", "true");
panel.setAttribute("noautofocus", "true");
panel.setAttribute("noautohide", "true");
panel.setAttribute("titlebar", "normal");
panel.setAttribute("close", "true");
panel.setAttribute("label", this.l10n("panelTitle"));
panel.setAttribute("width", 350);
panel.setAttribute("height", this.window.screen.height / 2);
let iframe = this.document.createElement("iframe");
let boundIframeOnLoad = function loadedInitializeIframe()
{
this.iframe.removeEventListener("load", boundIframeOnLoad, true);
this.iframeReady = true;
if (aCallback)
aCallback(this);
}.bind(this);
iframe.flex = 1;
iframe.setAttribute("tooltip", "aHTMLTooltip");
iframe.addEventListener("load", boundIframeOnLoad, true);
iframe.setAttribute("src", "chrome://browser/content/devtools/csshtmltree.xul");
panel.appendChild(iframe);
popupSet.appendChild(panel);
this._boundPopupShown = this.popupShown.bind(this);
this._boundPopupHidden = this.popupHidden.bind(this);
panel.addEventListener("popupshown", this._boundPopupShown, false);
panel.addEventListener("popuphidden", this._boundPopupHidden, false);
this.panel = panel;
this.iframe = iframe;
return panel;
},
/**
* Event handler for the popupshown event.
*/
popupShown: function SI_popupShown()
{
this.panelReady = true;
if (this.iframeReady) {
this.cssHtmlTree = new CssHtmlTree(this);
let selectedNode = this.selectedNode || null;
this.cssLogic.highlight(selectedNode);
this.cssHtmlTree.highlight(selectedNode);
Services.obs.notifyObservers(null, "StyleInspector-opened", null);
}
},
/**
* Event handler for the popuphidden event.
* Hide the popup and conditionally destroy it
*/
popupHidden: function SI_popupHidden()
{
if (this.preserveOnHide) {
Services.obs.notifyObservers(null, "StyleInspector-closed", null);
} else {
this.destroy();
}
},
/**
* Check if the style inspector is open.
* @returns boolean
*/
isOpen: function SI_isOpen()
{
return this.openDocked ? this.IUI.isSidebarOpen &&
(this.IUI.sidebarDeck.selectedPanel == this.iframe) :
this.panel && this.panel.state && this.panel.state == "open";
},
isLoaded: function SI_isLoaded()
{
return this.openDocked ? this.iframeReady : this.iframeReady && this.panelReady;
},
/**
* Select from Path (via CssHtmlTree_pathClick)
* @param aNode The node to inspect.
*/
selectFromPath: function SI_selectFromPath(aNode)
{
if (this.IUI && this.IUI.selection) {
if (aNode != this.IUI.selection) {
this.IUI.inspectNode(aNode);
}
} else {
this.selectNode(aNode);
}
},
/**
* Select a node to inspect in the Style Inspector panel
* @param aNode The node to inspect.
*/
selectNode: function SI_selectNode(aNode)
{
this.selectedNode = aNode;
if (this.isLoaded() && !this.dimmed) {
this.cssLogic.highlight(aNode);
this.cssHtmlTree.highlight(aNode);
}
},
/**
* Update the display for the currently-selected node.
*/
updateNode: function SI_updateNode()
{
if (this.isLoaded() && !this.dimmed) {
this.cssLogic.highlight(this.selectedNode);
this.cssHtmlTree.refreshPanel();
}
},
/**
* Dim or undim a panel by setting or removing a dimmed attribute.
* @param aState
* true = dim, false = undim
*/
dimTool: function SI_dimTool(aState)
{
this.dimmed = aState;
},
/**
* Open the panel.
* @param {DOMNode} aSelection the (optional) DOM node to select.
*/
open: function SI_open(aSelection)
{
this.selectNode(aSelection);
if (this.openDocked) {
if (!this.iframeReady) {
this.iframe.setAttribute("src", "chrome://browser/content/devtools/csshtmltree.xul");
}
} else {
this.panel.openPopup(this.window.gBrowser.selectedBrowser, "end_before", 0, 0,
false, false);
}
},
/**
* Close the panel.
*/
close: function SI_close()
{
if (this.openDocked) {
Services.obs.notifyObservers(null, "StyleInspector-closed", null);
} else {
this.panel.hidePopup();
}
},
/**
* Memoized lookup of a l10n string from a string bundle.
* @param {string} aName The key to lookup. * @param {string} aName The key to lookup.
* @returns A localized version of the given key. * @returns A localized version of the given key.
*/ */
l10n: function SI_l10n(aName) function l10n(aName)
{ {
try { try {
return _strings.GetStringFromName(aName); return _strings.GetStringFromName(aName);
@ -321,38 +64,197 @@ StyleInspector.prototype = {
Services.console.logStringMessage("Error reading '" + aName + "'"); Services.console.logStringMessage("Error reading '" + aName + "'");
throw new Error("l10n error with " + aName); throw new Error("l10n error with " + aName);
} }
}
function RegisterStyleTools()
{
// Register the rules view
if (Services.prefs.getBoolPref("devtools.ruleview.enabled")) {
InspectorUI.registerSidebar({
id: "ruleview",
label: l10n("ruleView.label"),
tooltiptext: l10n("ruleView.tooltiptext"),
accesskey: l10n("ruleView.accesskey"),
contentURL: "chrome://browser/content/devtools/cssruleview.xul",
load: function(aInspector, aFrame) new RuleViewTool(aInspector, aFrame),
destroy: function(aContext) aContext.destroy()
});
}
// Register the computed styles view
if (Services.prefs.getBoolPref("devtools.styleinspector.enabled")) {
InspectorUI.registerSidebar({
id: "computedview",
label: this.l10n("style.highlighter.button.label2"),
tooltiptext: this.l10n("style.highlighter.button.tooltip2"),
accesskey: this.l10n("style.highlighter.accesskey2"),
contentURL: "chrome://browser/content/devtools/csshtmltree.xul",
load: function(aInspector, aFrame) new ComputedViewTool(aInspector, aFrame),
destroy: function(aContext) aContext.destroy()
});
}
}
function RuleViewTool(aInspector, aFrame)
{
this.inspector = aInspector;
this.chromeWindow = this.inspector.chromeWindow;
this.doc = aFrame.contentDocument;
this.view = new CssRuleView(this.doc, aInspector._getStore("ruleview"));
this.doc.documentElement.appendChild(this.view.element);
this._changeHandler = function() {
this.inspector.markDirty();
this.inspector.change("ruleview");
}.bind(this);
this.view.element.addEventListener("CssRuleViewChanged", this._changeHandler)
this._cssLinkHandler = function(aEvent) {
let rule = aEvent.detail.rule;
let styleSheet = rule.sheet;
let doc = this.chromeWindow.content.document;
let styleSheets = doc.styleSheets;
let contentSheet = false;
let line = rule.ruleLine || 0;
// Array.prototype.indexOf always returns -1 here so we loop through
// the styleSheets object instead.
for each (let sheet in styleSheets) {
if (sheet == styleSheet) {
contentSheet = true;
break;
}
}
if (contentSheet) {
this.chromeWindow.StyleEditor.openChrome(styleSheet, line);
} else {
let href = styleSheet ? styleSheet.href : "";
if (rule.elementStyle.element) {
href = rule.elementStyle.element.ownerDocument.location.href;
}
let viewSourceUtils = this.chromeWindow.gViewSourceUtils;
viewSourceUtils.viewSource(href, null, doc, line);
}
}.bind(this);
this.view.element.addEventListener("CssRuleViewCSSLinkClicked",
this._cssLinkHandler);
this._onSelect = this.onSelect.bind(this);
this.inspector.on("select", this._onSelect);
this._onChange = this.onChange.bind(this);
this.inspector.on("change", this._onChange);
this.onSelect();
}
RuleViewTool.prototype = {
onSelect: function RVT_onSelect(aEvent, aFrom) {
let node = this.inspector.selection;
if (!node) {
this.view.highlight(null);
return;
}
if (this.inspector.locked) {
this.view.highlight(node);
}
}, },
/** onChange: function RVT_onChange(aEvent, aFrom) {
* Destroy the style panel, remove listeners etc. // We're not that good yet at refreshing, only
*/ // refresh when we really need to.
destroy: function SI_destroy() if (aFrom != "pseudoclass") {
{ return;
if (this.isOpen())
this.close();
if (this.cssHtmlTree)
this.cssHtmlTree.destroy();
if (this.iframe) {
this.iframe.parentNode.removeChild(this.iframe);
delete this.iframe;
} }
if (this.inspector.locked) {
this.view.nodeChanged();
}
},
destroy: function RVT_destroy() {
this.inspector.removeListener("select", this._onSelect);
this.inspector.removeListener("change", this._onChange);
this.view.element.removeEventListener("CssRuleViewChanged",
this._changeHandler);
this.view.element.removeEventListener("CssRuleViewCSSLinkClicked",
this._cssLinkHandler);
this.doc.documentElement.removeChild(this.view.element);
this.view.destroy();
delete this._changeHandler;
delete this.view;
delete this.doc;
delete this.inspector;
}
}
function ComputedViewTool(aInspector, aFrame)
{
this.inspector = aInspector;
this.iframe = aFrame;
this.window = aInspector.chromeWindow;
this.document = this.window.document;
this.cssLogic = new CssLogic();
this.view = new CssHtmlTree(this);
this._onSelect = this.onSelect.bind(this);
this.inspector.on("select", this._onSelect);
this._onChange = this.onChange.bind(this);
this.inspector.on("change", this._onChange);
// Since refreshes of the computed view are non-destructive,
// refresh when the tab is changed so we can notice script-driven
// changes.
this.inspector.on("sidebaractivated", this._onChange);
this.cssLogic.highlight(null);
this.view.highlight(null);
this.onSelect();
}
ComputedViewTool.prototype = {
onSelect: function CVT_onSelect(aEvent)
{
if (this.inspector.locked) {
this.cssLogic.highlight(this.inspector.selection);
this.view.highlight(this.inspector.selection);
}
},
onChange: function CVT_change(aEvent, aFrom)
{
if (aFrom == "computedview" ||
this.inspector.selection != this.cssLogic.viewedElement) {
return;
}
this.cssLogic.highlight(this.inspector.selection);
this.view.refreshPanel();
},
destroy: function CVT_destroy(aContext)
{
this.inspector.removeListener("select", this._onSelect);
this.inspector.removeListener("change", this._onChange);
this.inspector.removeListener("sidebaractivated", this._onChange);
this.view.destroy();
delete this.view;
delete this.cssLogic; delete this.cssLogic;
delete this.cssHtmlTree; delete this.cssHtmlTree;
if (this.panel) { delete this.iframe;
this.panel.removeEventListener("popupshown", this._boundPopupShown, false); delete this.window;
this.panel.removeEventListener("popuphidden", this._boundPopupHidden, false); delete this.document;
delete this._boundPopupShown; }
delete this._boundPopupHidden;
this.panel.parentNode.removeChild(this.panel);
delete this.panel;
} }
delete this.doc;
delete this.win;
delete CssHtmlTree.win;
Services.obs.notifyObservers(null, "StyleInspector-closed", null);
},
};
XPCOMUtils.defineLazyGetter(this, "_strings", function() Services.strings XPCOMUtils.defineLazyGetter(this, "_strings", function() Services.strings
.createBundle("chrome://browser/locale/devtools/styleinspector.properties")); .createBundle("chrome://browser/locale/devtools/styleinspector.properties"));
@ -368,3 +270,5 @@ XPCOMUtils.defineLazyGetter(this, "CssHtmlTree", function() {
Cu.import("resource:///modules/devtools/CssHtmlTree.jsm", tmp); Cu.import("resource:///modules/devtools/CssHtmlTree.jsm", tmp);
return tmp.CssHtmlTree; return tmp.CssHtmlTree;
}); });
RegisterStyleTools();

View File

@ -14,19 +14,12 @@ function createDocument()
'<span class="matches">Some styled text</span>' + '<span class="matches">Some styled text</span>' +
'</div>'; '</div>';
doc.title = "Style Inspector key binding test"; doc.title = "Style Inspector key binding test";
stylePanel = new StyleInspector(window); stylePanel = new ComputedViewPanel(window);
Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false); stylePanel.createPanel(doc.body, runStyleInspectorTests);
stylePanel.createPanel(false, function() {
stylePanel.open(doc.body);
});
} }
function runStyleInspectorTests() function runStyleInspectorTests()
{ {
Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-opened", false);
ok(stylePanel.isOpen(), "style inspector is open");
Services.obs.addObserver(SI_test, "StyleInspector-populated", false); Services.obs.addObserver(SI_test, "StyleInspector-populated", false);
SI_inspectNode(); SI_inspectNode();
} }
@ -66,8 +59,8 @@ function SI_test()
testKey(iframe.contentWindow, "VK_RETURN", rulesTable); testKey(iframe.contentWindow, "VK_RETURN", rulesTable);
checkHelpLinkKeybinding(); checkHelpLinkKeybinding();
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
}); });
info("Adding focus event handler to search filter"); info("Adding focus event handler to search filter");
@ -94,6 +87,7 @@ function getFirstVisiblePropertyView()
propView = aPropView; propView = aPropView;
return true; return true;
} }
return false;
}); });
return propView; return propView;
@ -127,8 +121,6 @@ function checkHelpLinkKeybinding()
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
ok(!stylePanel.isOpen(), "style inspector is closed");
doc = stylePanel = null; doc = stylePanel = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -26,25 +26,18 @@ function tabLoaded()
browser.removeEventListener("load", tabLoaded, true); browser.removeEventListener("load", tabLoaded, true);
doc = content.document; doc = content.document;
// ok(StyleInspector.isEnabled, "style inspector preference is enabled"); // ok(StyleInspector.isEnabled, "style inspector preference is enabled");
stylePanel = new StyleInspector(window); stylePanel = new ComputedViewPanel(window);
Services.obs.addObserver(runTests, "StyleInspector-opened", false); stylePanel.createPanel(doc.body, runTests);
stylePanel.createPanel(false, function() {
stylePanel.open(doc.body);
});
} }
function runTests() function runTests()
{ {
Services.obs.removeObserver(runTests, "StyleInspector-opened", false);
ok(stylePanel.isOpen(), "style inspector is open");
testMatchedSelectors(); testMatchedSelectors();
//testUnmatchedSelectors(); //testUnmatchedSelectors();
info("finishing up"); info("finishing up");
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
} }
function testMatchedSelectors() function testMatchedSelectors()
@ -97,8 +90,6 @@ function testUnmatchedSelectors()
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
ok(!stylePanel.isOpen(), "style inspector is closed");
doc = stylePanel = null; doc = stylePanel = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -22,19 +22,12 @@ function docLoaded()
{ {
browser.removeEventListener("load", docLoaded, true); browser.removeEventListener("load", docLoaded, true);
doc = content.document; doc = content.document;
stylePanel = new StyleInspector(window); stylePanel = new ComputedViewPanel(window);
Services.obs.addObserver(checkSheets, "StyleInspector-opened", false); stylePanel.createPanel(doc.body, checkSheets);
stylePanel.createPanel(false, function() {
stylePanel.open(doc.body);
});
} }
function checkSheets() function checkSheets()
{ {
Services.obs.removeObserver(checkSheets, "StyleInspector-opened", false);
ok(stylePanel.isOpen(), "style inspector is open");
var div = doc.querySelector("div"); var div = doc.querySelector("div");
ok(div, "captain, we have the div"); ok(div, "captain, we have the div");
@ -55,13 +48,12 @@ function checkSheets()
is(cssLogic._matchedRules[1][0].source, source2, is(cssLogic._matchedRules[1][0].source, source2,
"rule.source gives correct output for rule 2"); "rule.source gives correct output for rule 2");
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
} }
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
doc = null; doc = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -12,16 +12,14 @@ function createDocument()
doc.body.innerHTML = "<div style='color:blue;'></div>"; doc.body.innerHTML = "<div style='color:blue;'></div>";
doc.title = "Style Inspector Selector Text Test"; doc.title = "Style Inspector Selector Text Test";
stylePanel = new StyleInspector(window); stylePanel = new ComputedViewPanel(window);
stylePanel.createPanel(false, function() {
Services.obs.addObserver(SI_checkText, "StyleInspector-populated", false); Services.obs.addObserver(SI_checkText, "StyleInspector-populated", false);
let span = doc.querySelector("div"); let span = doc.querySelector("div");
ok(span, "captain, we have the test div"); ok(span, "captain, we have the test div");
stylePanel.open(span);
}); stylePanel.createPanel(span);
} }
function SI_checkText() function SI_checkText()
@ -34,6 +32,7 @@ function SI_checkText()
propertyView = aView; propertyView = aView;
return true; return true;
} }
return false;
}); });
ok(propertyView, "found PropertyView for color"); ok(propertyView, "found PropertyView for color");
@ -57,13 +56,12 @@ function SI_checkText()
ok(false, "getting the selector text should not raise an exception"); ok(false, "getting the selector text should not raise an exception");
} }
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
} }
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
doc = stylePanel = null; doc = stylePanel = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -30,19 +30,15 @@ function createDocument()
let span = doc.querySelector("span"); let span = doc.querySelector("span");
ok(span, "captain, we have the span"); ok(span, "captain, we have the span");
stylePanel = new StyleInspector(window);
Services.obs.addObserver(testInlineStyle, "StyleInspector-populated", false); Services.obs.addObserver(testInlineStyle, "StyleInspector-populated", false);
stylePanel.createPanel(false, function() { stylePanel = new ComputedViewPanel(window);
stylePanel.open(span); stylePanel.createPanel(span);
});
} }
function testInlineStyle() function testInlineStyle()
{ {
Services.obs.removeObserver(testInlineStyle, "StyleInspector-populated", false); Services.obs.removeObserver(testInlineStyle, "StyleInspector-populated", false);
ok(stylePanel.isOpen(), "style inspector is open");
info("expanding property"); info("expanding property");
expandProperty(0, function propertyExpanded() { expandProperty(0, function propertyExpanded() {
Services.ww.registerNotification(function onWindow(aSubject, aTopic) { Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
@ -113,8 +109,8 @@ function validateStyleEditorSheet(aEditor)
info("closing window"); info("closing window");
win.close(); win.close();
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
} }
function expandProperty(aIndex, aCallback) function expandProperty(aIndex, aCallback)
@ -138,8 +134,6 @@ function getLinkByIndex(aIndex)
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
ok(!stylePanel.isOpen(), "style inspector is closed");
doc = win = stylePanel = null; doc = win = stylePanel = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -35,19 +35,15 @@ function createDocument()
let span = doc.querySelector("span"); let span = doc.querySelector("span");
ok(span, "captain, we have the span"); ok(span, "captain, we have the span");
stylePanel = new StyleInspector(window); stylePanel = new ComputedViewPanel(window);
Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-populated", false); Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-populated", false);
stylePanel.createPanel(false, function() { stylePanel.createPanel(span);
stylePanel.open(span);
});
} }
function runStyleInspectorTests() function runStyleInspectorTests()
{ {
Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-populated", false); Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-populated", false);
ok(stylePanel.isOpen(), "style inspector is open");
cssHtmlTree = stylePanel.cssHtmlTree; cssHtmlTree = stylePanel.cssHtmlTree;
let contentDocument = stylePanel.iframe.contentDocument; let contentDocument = stylePanel.iframe.contentDocument;
@ -166,14 +162,12 @@ function failedClipboard(aExpectedPattern, aCallback)
function closeStyleInspector() function closeStyleInspector()
{ {
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
} }
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
ok(!stylePanel.isOpen(), "style inspector is closed");
doc = stylePanel = cssHtmlTree = null; doc = stylePanel = cssHtmlTree = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -63,18 +63,14 @@ function inspectorUIOpen()
InspectorUI.stopInspecting(); InspectorUI.stopInspecting();
is(InspectorUI.selection, div, "selection matches the div element"); is(InspectorUI.selection, div, "selection matches the div element");
Services.obs.addObserver(testInlineStyle, InspectorUI.currentInspector.once("sidebaractivated-ruleview", testInlineStyle);
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
InspectorUI.showSidebar(); InspectorUI.sidebar.show();
InspectorUI.openRuleView(); InspectorUI.sidebar.activatePanel("ruleview");
} }
function testInlineStyle() function testInlineStyle()
{ {
Services.obs.removeObserver(testInlineStyle,
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
executeSoon(function() { executeSoon(function() {
info("clicking an inline style"); info("clicking an inline style");
@ -149,16 +145,15 @@ function validateStyleEditorSheet(aEditor)
function getLinkByIndex(aIndex) function getLinkByIndex(aIndex)
{ {
let ruleView = document.querySelector("#devtools-sidebar-iframe-ruleview"); let contentDoc = ruleView().doc;
let contentDoc = ruleView.contentDocument; contentWindow = contentDoc.defaultView;
let links = contentDoc.querySelectorAll(".ruleview-rule-source"); let links = contentDoc.querySelectorAll(".ruleview-rule-source");
contentWindow = ruleView.contentWindow;
return links[aIndex]; return links[aIndex];
} }
function finishup() function finishup()
{ {
InspectorUI.hideSidebar(); InspectorUI.sidebar.hide();
InspectorUI.closeInspectorUI(); InspectorUI.closeInspectorUI();
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
doc = contentWindow = win = null; doc = contentWindow = win = null;

View File

@ -11,6 +11,11 @@ XPCOMUtils.defineLazyGetter(this, "osString", function() {
return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS; return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
}); });
function ruleViewFrame()
{
return InspectorUI.sidebar._tools["ruleview"].frame;
}
function createDocument() function createDocument()
{ {
doc.body.innerHTML = '<style type="text/css"> ' + doc.body.innerHTML = '<style type="text/css"> ' +
@ -88,18 +93,13 @@ function inspectorUIOpen()
InspectorUI.stopInspecting(); InspectorUI.stopInspecting();
is(InspectorUI.selection, div, "selection matches the div element"); is(InspectorUI.selection, div, "selection matches the div element");
Services.obs.addObserver(testClip, InspectorUI.currentInspector.once("sidebaractivated-ruleview", testClip)
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false); InspectorUI.sidebar.show();
InspectorUI.sidebar.activatePanel("ruleview");
InspectorUI.showSidebar();
InspectorUI.openRuleView();
} }
function testClip() function testClip()
{ {
Services.obs.removeObserver(testClip,
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
executeSoon(function() { executeSoon(function() {
info("Checking that _onCopyRule() returns " + info("Checking that _onCopyRule() returns " +
"the correct clipboard value"); "the correct clipboard value");
@ -120,8 +120,7 @@ function testClip()
} }
function checkCopyRule() { function checkCopyRule() {
let ruleView = document.querySelector("#devtools-sidebar-iframe-ruleview"); let contentDoc = ruleViewFrame().contentDocument;
let contentDoc = ruleView.contentDocument;
let props = contentDoc.querySelectorAll(".ruleview-property"); let props = contentDoc.querySelectorAll(".ruleview-property");
is(props.length, 5, "checking property length"); is(props.length, 5, "checking property length");
@ -136,9 +135,9 @@ function checkCopyRule() {
// We need the context menu to open in the correct place in order for // We need the context menu to open in the correct place in order for
// popupNode to be propertly set. // popupNode to be propertly set.
EventUtils.synthesizeMouse(prop, 1, 1, { type: "contextmenu", button: 2 }, EventUtils.synthesizeMouse(prop, 1, 1, { type: "contextmenu", button: 2 },
ruleView.contentWindow); ruleViewFrame().contentWindow);
InspectorUI.ruleView._boundCopyRule(); ruleView()._boundCopyRule();
let menu = contentDoc.querySelector("#rule-view-context-menu"); let menu = contentDoc.querySelector("#rule-view-context-menu");
ok(menu, "we have the context menu"); ok(menu, "we have the context menu");
menu.hidePopup(); menu.hidePopup();
@ -146,8 +145,7 @@ function checkCopyRule() {
function checkCopyRuleWithEditorSelected() function checkCopyRuleWithEditorSelected()
{ {
let ruleView = document.querySelector("#devtools-sidebar-iframe-ruleview"); let contentDoc = ruleViewFrame().contentDocument;
let contentDoc = ruleView.contentDocument;
let rows = contentDoc.querySelectorAll(".rule-view-row"); let rows = contentDoc.querySelectorAll(".rule-view-row");
let propNodes = contentDoc.querySelectorAll(".ruleview-property"); let propNodes = contentDoc.querySelectorAll(".ruleview-property");
let propNode = propNodes[2]; let propNode = propNodes[2];
@ -172,7 +170,7 @@ function checkCopyRuleWithEditorSelected()
// We need the context menu to open in the correct place in order for // We need the context menu to open in the correct place in order for
// popupNode to be propertly set. // popupNode to be propertly set.
EventUtils.synthesizeMouse(aEditor.input, 1, 1, EventUtils.synthesizeMouse(aEditor.input, 1, 1,
{ type: "contextmenu", button: 2 }, ruleView.contentWindow); { type: "contextmenu", button: 2 }, ruleViewFrame().contentWindow);
SimpleTest.waitForClipboard(function IUI_boundCopyCheckWithSelection() { SimpleTest.waitForClipboard(function IUI_boundCopyCheckWithSelection() {
let menu = contentDoc.querySelector("#rule-view-context-menu"); let menu = contentDoc.querySelector("#rule-view-context-menu");
@ -180,11 +178,11 @@ function checkCopyRuleWithEditorSelected()
menu.hidePopup(); menu.hidePopup();
return checkClipboardData(expectedPattern); return checkClipboardData(expectedPattern);
}, InspectorUI.ruleView._boundCopyRule, waitForBlur, function() { }, ruleView()._boundCopyRule, waitForBlur, function() {
failedClipboard(expectedPattern, checkCopyProperty); failedClipboard(expectedPattern, checkCopyProperty);
}); });
}); });
EventUtils.synthesizeMouse(propNameNode, 1, 1, { }, ruleView.contentWindow); EventUtils.synthesizeMouse(propNameNode, 1, 1, { }, ruleViewFrame().contentWindow);
} }
function waitForBlur() function waitForBlur()
@ -198,8 +196,7 @@ function waitForBlur()
function checkCopyProperty() function checkCopyProperty()
{ {
let ruleView = document.querySelector("#devtools-sidebar-iframe-ruleview"); let contentDoc = ruleViewFrame().contentDocument;
let contentDoc = ruleView.contentDocument;
let props = contentDoc.querySelectorAll(".ruleview-property"); let props = contentDoc.querySelectorAll(".ruleview-property");
let prop = props[2]; let prop = props[2];
@ -210,12 +207,12 @@ function checkCopyProperty()
// We need the context menu to open in the correct place in order for // We need the context menu to open in the correct place in order for
// popupNode to be propertly set. // popupNode to be propertly set.
EventUtils.synthesizeMouse(prop, 1, 1, { type: "contextmenu", button: 2 }, EventUtils.synthesizeMouse(prop, 1, 1, { type: "contextmenu", button: 2 },
ruleView.contentWindow); ruleViewFrame().contentWindow);
SimpleTest.waitForClipboard(function IUI_boundCopyPropCheck() { SimpleTest.waitForClipboard(function IUI_boundCopyPropCheck() {
return checkClipboardData(expectedPattern); return checkClipboardData(expectedPattern);
}, },
InspectorUI.ruleView._boundCopyDeclaration, ruleView()._boundCopyDeclaration,
checkCopyPropertyName, function() { checkCopyPropertyName, function() {
failedClipboard(expectedPattern, checkCopyPropertyName); failedClipboard(expectedPattern, checkCopyPropertyName);
}); });
@ -230,7 +227,7 @@ function checkCopyPropertyName()
SimpleTest.waitForClipboard(function IUI_boundCopyPropNameCheck() { SimpleTest.waitForClipboard(function IUI_boundCopyPropNameCheck() {
return checkClipboardData(expectedPattern); return checkClipboardData(expectedPattern);
}, },
InspectorUI.ruleView._boundCopyProperty, ruleView()._boundCopyProperty,
checkCopyPropertyValue, function() { checkCopyPropertyValue, function() {
failedClipboard(expectedPattern, checkCopyPropertyValue); failedClipboard(expectedPattern, checkCopyPropertyValue);
}); });
@ -245,7 +242,7 @@ function checkCopyPropertyValue()
SimpleTest.waitForClipboard(function IUI_boundCopyPropValueCheck() { SimpleTest.waitForClipboard(function IUI_boundCopyPropValueCheck() {
return checkClipboardData(expectedPattern); return checkClipboardData(expectedPattern);
}, },
InspectorUI.ruleView._boundCopyPropertyValue, ruleView()._boundCopyPropertyValue,
checkCopySelection, function() { checkCopySelection, function() {
failedClipboard(expectedPattern, checkCopySelection); failedClipboard(expectedPattern, checkCopySelection);
}); });
@ -253,15 +250,14 @@ function checkCopyPropertyValue()
function checkCopySelection() function checkCopySelection()
{ {
let ruleView = document.querySelector("#devtools-sidebar-iframe-ruleview"); let contentDoc = ruleViewFrame().contentDocument;
let contentDoc = ruleView.contentDocument;
let props = contentDoc.querySelectorAll(".ruleview-property"); let props = contentDoc.querySelectorAll(".ruleview-property");
let range = document.createRange(); let range = document.createRange();
range.setStart(props[0], 0); range.setStart(props[0], 0);
range.setEnd(props[4], 8); range.setEnd(props[4], 8);
let selection = ruleView.contentWindow.getSelection(); let selection = ruleViewFrame().contentWindow.getSelection();
selection.addRange(range); selection.addRange(range);
info("Checking that _boundCopy() returns the correct" + info("Checking that _boundCopy() returns the correct" +
@ -276,7 +272,7 @@ function checkCopySelection()
SimpleTest.waitForClipboard(function IUI_boundCopyCheck() { SimpleTest.waitForClipboard(function IUI_boundCopyCheck() {
return checkClipboardData(expectedPattern); return checkClipboardData(expectedPattern);
},InspectorUI.ruleView._boundCopy, finishup, function() { },ruleView()._boundCopy, finishup, function() {
failedClipboard(expectedPattern, finishup); failedClipboard(expectedPattern, finishup);
}); });
} }
@ -312,7 +308,7 @@ function failedClipboard(aExpectedPattern, aCallback)
function finishup() function finishup()
{ {
InspectorUI.hideSidebar(); InspectorUI.sidebar.hide();
InspectorUI.closeInspectorUI(); InspectorUI.closeInspectorUI();
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
doc = null; doc = null;

View File

@ -13,18 +13,7 @@ let stylePanel;
function waitForRuleView(aCallback) function waitForRuleView(aCallback)
{ {
if (InspectorUI.ruleView) { InspectorUI.currentInspector.once("sidebaractivated-ruleview", aCallback);
aCallback();
return;
}
let ruleViewFrame = InspectorUI.getToolIframe(InspectorUI.ruleViewObject);
ruleViewFrame.addEventListener("load", function(evt) {
ruleViewFrame.removeEventListener(evt.type, arguments.callee, true);
executeSoon(function() {
aCallback();
});
}, true);
} }
function waitForEditorFocus(aParent, aCallback) function waitForEditorFocus(aParent, aCallback)
@ -54,8 +43,8 @@ function openRuleView()
// Open the rule view sidebar. // Open the rule view sidebar.
waitForRuleView(testFocus); waitForRuleView(testFocus);
InspectorUI.showSidebar(); InspectorUI.sidebar.show();
InspectorUI.ruleButton.click(); InspectorUI.sidebar.activatePanel("ruleview");
testFocus(); testFocus();
}, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false); }, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
@ -64,7 +53,7 @@ function openRuleView()
function testFocus() function testFocus()
{ {
let ruleViewFrame = InspectorUI.getToolIframe(InspectorUI.ruleViewObject); let ruleViewFrame = InspectorUI.sidebar._tools["ruleview"].frame;
let brace = ruleViewFrame.contentDocument.querySelectorAll(".ruleview-ruleclose")[0]; let brace = ruleViewFrame.contentDocument.querySelectorAll(".ruleview-ruleclose")[0];
waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) { waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) {
aEditor.input.value = "color"; aEditor.input.value = "color";
@ -89,7 +78,7 @@ function testFocus()
function finishUp() function finishUp()
{ {
InspectorUI.hideSidebar(); InspectorUI.sidebar.hide();
InspectorUI.closeInspectorUI(); InspectorUI.closeInspectorUI();
doc = stylePanel = null; doc = stylePanel = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();

View File

@ -26,19 +26,12 @@ function createDocument()
'<p>Inspect using inspectstyle(document.querySelectorAll("span")[0])</p>' + '<p>Inspect using inspectstyle(document.querySelectorAll("span")[0])</p>' +
'</div>'; '</div>';
doc.title = "Style Inspector Test"; doc.title = "Style Inspector Test";
stylePanel = new StyleInspector(window); stylePanel = new ComputedViewPanel(window);
Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false); stylePanel.createPanel(doc.body, runStyleInspectorTests);
stylePanel.createPanel(false, function() {
stylePanel.open(doc.body);
});
} }
function runStyleInspectorTests() function runStyleInspectorTests()
{ {
Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-opened", false);
ok(stylePanel.isOpen(), "style inspector is open");
var spans = doc.querySelectorAll("span"); var spans = doc.querySelectorAll("span");
ok(spans, "captain, we have the spans"); ok(spans, "captain, we have the spans");
@ -54,8 +47,8 @@ function runStyleInspectorTests()
} }
SI_CheckProperty(); SI_CheckProperty();
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
} }
function SI_CheckProperty() function SI_CheckProperty()
@ -68,8 +61,6 @@ function SI_CheckProperty()
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
ok(!stylePanel.isOpen(), "style inspector is closed");
doc = stylePanel = null; doc = stylePanel = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -15,19 +15,12 @@ function createDocument()
'</div>'; '</div>';
doc.title = "Style Inspector Search Filter Test"; doc.title = "Style Inspector Search Filter Test";
// ok(StyleInspector.isEnabled, "style inspector preference is enabled"); // ok(StyleInspector.isEnabled, "style inspector preference is enabled");
stylePanel = new StyleInspector(window); stylePanel = new ComputedViewPanel(window);
Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false); stylePanel.createPanel(doc.body, runStyleInspectorTests);
stylePanel.createPanel(false, function() {
stylePanel.open(doc.body);
});
} }
function runStyleInspectorTests() function runStyleInspectorTests()
{ {
Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-opened", false);
ok(stylePanel.isOpen(), "style inspector is open");
Services.obs.addObserver(SI_toggleDefaultStyles, "StyleInspector-populated", false); Services.obs.addObserver(SI_toggleDefaultStyles, "StyleInspector-populated", false);
SI_inspectNode(); SI_inspectNode();
} }
@ -86,14 +79,12 @@ function SI_checkFilter()
"span " + name + " property visibility check"); "span " + name + " property visibility check");
}); });
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
} }
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
ok(!stylePanel.isOpen(), "style inspector is closed");
doc = stylePanel = null; doc = stylePanel = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -15,19 +15,12 @@ function createDocument()
'</div>'; '</div>';
doc.title = "Style Inspector Default Styles Test"; doc.title = "Style Inspector Default Styles Test";
// ok(StyleInspector.isEnabled, "style inspector preference is enabled"); // ok(StyleInspector.isEnabled, "style inspector preference is enabled");
stylePanel = new StyleInspector(window); stylePanel = new ComputedViewPanel(window);
Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false); stylePanel.createPanel(doc.body, runStyleInspectorTests);
stylePanel.createPanel(false, function() {
stylePanel.open(doc.body);
});
} }
function runStyleInspectorTests() function runStyleInspectorTests()
{ {
Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-opened", false);
ok(stylePanel.isOpen(), "style inspector is open");
Services.obs.addObserver(SI_check, "StyleInspector-populated", false); Services.obs.addObserver(SI_check, "StyleInspector-populated", false);
SI_inspectNode(); SI_inspectNode();
} }
@ -75,8 +68,8 @@ function SI_checkDefaultStyles()
is(propertyVisible("background-color"), true, is(propertyVisible("background-color"), true,
"span background-color property is visible"); "span background-color property is visible");
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
} }
function propertyVisible(aName) function propertyVisible(aName)
@ -88,12 +81,11 @@ function propertyVisible(aName)
return propView.visible; return propView.visible;
} }
} }
return false;
} }
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
ok(!stylePanel.isOpen(), "style inspector is closed");
doc = stylePanel = null; doc = stylePanel = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -13,19 +13,12 @@ function createDocument()
'.matches {color: #F00;}</style>' + '.matches {color: #F00;}</style>' +
'<span id="matches" class="matches">Some styled text</span>'; '<span id="matches" class="matches">Some styled text</span>';
doc.title = "Tests that the no results placeholder works properly"; doc.title = "Tests that the no results placeholder works properly";
stylePanel = new StyleInspector(window); stylePanel = new ComputedViewPanel(window);
Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false); stylePanel.createPanel(doc.body, runStyleInspectorTests);
stylePanel.createPanel(false, function() {
stylePanel.open(doc.body);
});
} }
function runStyleInspectorTests() function runStyleInspectorTests()
{ {
Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-opened", false);
ok(stylePanel.isOpen(), "style inspector is open");
Services.obs.addObserver(SI_AddFilterText, "StyleInspector-populated", false); Services.obs.addObserver(SI_AddFilterText, "StyleInspector-populated", false);
let span = doc.querySelector("#matches"); let span = doc.querySelector("#matches");
@ -90,14 +83,12 @@ function SI_checkPlaceholderHidden()
is(display, "none", "placeholder is hidden"); is(display, "none", "placeholder is hidden");
Services.obs.addObserver(finishUp, "StyleInspector-closed", false); stylePanel.destroy();
stylePanel.close(); finishUp();
} }
function finishUp() function finishUp()
{ {
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
ok(!stylePanel.isOpen(), "style inspector is closed");
doc = stylePanel = null; doc = stylePanel = null;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View File

@ -36,11 +36,13 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
let tempScope = {}; let tempScope = {};
Cu.import("resource:///modules/devtools/StyleInspector.jsm", tempScope); Cu.import("resource:///modules/devtools/CssLogic.jsm", tempScope);
Cu.import("resource:///modules/devtools/CssHtmlTree.jsm", tempScope);
Cu.import("resource://gre/modules/HUDService.jsm", tempScope); Cu.import("resource://gre/modules/HUDService.jsm", tempScope);
let StyleInspector = tempScope.StyleInspector;
let HUDService = tempScope.HUDService; let HUDService = tempScope.HUDService;
let ConsoleUtils = tempScope.ConsoleUtils; let ConsoleUtils = tempScope.ConsoleUtils;
let CssLogic = tempScope.CssLogic;
let CssHtmlTree = tempScope.CssHtmlTree;
function log(aMsg) function log(aMsg)
{ {
@ -192,6 +194,149 @@ function tearDown()
tab = browser = hudId = hud = filterBox = outputNode = cs = null; tab = browser = hudId = hud = filterBox = outputNode = cs = null;
} }
/**
* Shows the computed view in its own panel.
*/
function ComputedViewPanel(aContext)
{
this._init(aContext);
}
ComputedViewPanel.prototype = {
_init: function CVP_init(aContext)
{
this.window = aContext;
this.document = this.window.document;
this.cssLogic = new CssLogic();
this.panelReady = false;
this.iframeReady = false;
},
/**
* Factory method to create the actual style panel
* @param {function} aCallback (optional) callback to fire when ready.
*/
createPanel: function SI_createPanel(aSelection, aCallback)
{
let popupSet = this.document.getElementById("mainPopupSet");
let panel = this.document.createElement("panel");
panel.setAttribute("class", "styleInspector");
panel.setAttribute("orient", "vertical");
panel.setAttribute("ignorekeys", "true");
panel.setAttribute("noautofocus", "true");
panel.setAttribute("noautohide", "true");
panel.setAttribute("titlebar", "normal");
panel.setAttribute("close", "true");
panel.setAttribute("label", "Computed View");
panel.setAttribute("width", 350);
panel.setAttribute("height", this.window.screen.height / 2);
this._openCallback = aCallback;
this.selectedNode = aSelection;
let iframe = this.document.createElement("iframe");
let boundIframeOnLoad = function loadedInitializeIframe()
{
this.iframeReady = true;
this.iframe.removeEventListener("load", boundIframeOnLoad, true);
this.panel.openPopup(this.window.gBrowser.selectedBrowser, "end_before", 0, 0, false, false);
}.bind(this);
iframe.flex = 1;
iframe.setAttribute("tooltip", "aHTMLTooltip");
iframe.addEventListener("load", boundIframeOnLoad, true);
iframe.setAttribute("src", "chrome://browser/content/devtools/csshtmltree.xul");
panel.appendChild(iframe);
popupSet.appendChild(panel);
this._boundPopupShown = this.popupShown.bind(this);
panel.addEventListener("popupshown", this._boundPopupShown, false);
this.panel = panel;
this.iframe = iframe;
return panel;
},
/**
* Event handler for the popupshown event.
*/
popupShown: function SI_popupShown()
{
this.panelReady = true;
this.cssHtmlTree = new CssHtmlTree(this);
let selectedNode = this.selectedNode || null;
this.cssLogic.highlight(selectedNode);
this.cssHtmlTree.highlight(selectedNode);
if (this._openCallback) {
this._openCallback();
delete this._openCallback;
}
},
isLoaded: function SI_isLoaded()
{
return this.iframeReady && this.panelReady;
},
/**
* Select from Path (via CssHtmlTree_pathClick)
* @param aNode The node to inspect.
*/
selectFromPath: function SI_selectFromPath(aNode)
{
this.selectNode(aNode);
},
/**
* Select a node to inspect in the Style Inspector panel
* @param aNode The node to inspect.
*/
selectNode: function SI_selectNode(aNode)
{
this.selectedNode = aNode;
if (this.isLoaded()) {
this.cssLogic.highlight(aNode);
this.cssHtmlTree.highlight(aNode);
}
},
/**
* Destroy the style panel, remove listeners etc.
*/
destroy: function SI_destroy()
{
this.panel.hidePopup();
if (this.cssHtmlTree) {
this.cssHtmlTree.destroy();
delete this.cssHtmlTree;
}
if (this.iframe) {
this.iframe.parentNode.removeChild(this.iframe);
delete this.iframe;
}
delete this.cssLogic;
this.panel.removeEventListener("popupshown", this._boundPopupShown, false);
delete this._boundPopupShown;
this.panel.parentNode.removeChild(this.panel);
delete this.panel;
delete this.doc;
delete this.win;
delete CssHtmlTree.win;
},
};
function ruleView()
{
return InspectorUI.sidebar._toolContext("ruleview").view;
}
registerCleanupFunction(tearDown); registerCleanupFunction(tearDown);
waitForExplicitFinish(); waitForExplicitFinish();

View File

@ -20,12 +20,6 @@ breadcrumbs.siblings=Siblings
# LOCALIZATION NOTE (htmlPanel): Used in the Inspector tool's openInspectorUI # LOCALIZATION NOTE (htmlPanel): Used in the Inspector tool's openInspectorUI
# method when registering the HTML panel. # method when registering the HTML panel.
# LOCALIZATION NOTE (ruleView.*): Button label, accesskey and tooltip text
# associated with the Highlighter's CSS Rule View in the Style Sidebar.
ruleView.label=Rules
ruleView.accesskey=R
ruleView.tooltiptext=View and Edit CSS
# LOCALIZATION NOTE (inspectButton.tooltiptext): # LOCALIZATION NOTE (inspectButton.tooltiptext):
# This button appears in the Inspector Toolbar. inspectButton is stateful, # This button appears in the Inspector Toolbar. inspectButton is stateful,
# if it's pressed users can select an element with the mouse. # if it's pressed users can select an element with the mouse.

View File

@ -121,3 +121,9 @@ rule.contextmenu.copypropertyvalue=Copy property value
# LOCALIZATION NOTE (rule.contextmenu.copypropertyvalue.accesskey): The rule # LOCALIZATION NOTE (rule.contextmenu.copypropertyvalue.accesskey): The rule
# view's context menu copy property value access key. # view's context menu copy property value access key.
rule.contextmenu.copypropertyvalue.accesskey=U rule.contextmenu.copypropertyvalue.accesskey=U
# LOCALIZATION NOTE (ruleView.*): Button label, accesskey and tooltip text
# associated with the Highlighter's CSS Rule View in the Style Sidebar.
ruleView.label=Rules
ruleView.accesskey=R
ruleView.tooltiptext=View and Edit CSS