Bug 699475 - Integrate RuleView into Highlighter Sidebar; r=dcamp

This commit is contained in:
Rob Campbell 2011-11-03 18:40:36 -03:00
Родитель 5fe53f36e1
Коммит 7c8aa5c30d
5 изменённых файлов: 191 добавлений и 7 удалений

Просмотреть файл

@ -1008,6 +1008,9 @@ pref("devtools.inspector.enabled", true);
// Enable the style inspector
pref("devtools.styleinspector.enabled", true);
// Enable the rules view
pref("devtools.ruleview.enabled", true);
// Enable the Scratchpad tool.
pref("devtools.scratchpad.enabled", true);

Просмотреть файл

@ -50,6 +50,7 @@ var EXPORTED_SYMBOLS = ["InspectorUI"];
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource:///modules/TreePanel.jsm");
Cu.import("resource:///modules/devtools/CssRuleView.jsm");
const INSPECTOR_INVISIBLE_ELEMENTS = {
"head": true,
@ -78,9 +79,15 @@ const INSPECTOR_NOTIFICATIONS = {
// Fires once the Inspector is closed.
CLOSED: "inspector-closed",
// Fires when the Inspector is reopened after tab-switch.
STATE_RESTORED: "inspector-state-restored",
// Fires when the Tree Panel is opened and initialized.
TREEPANELREADY: "inspector-treepanel-ready",
// Fires when the CSS Rule View is opened and initialized.
RULEVIEWREADY: "inspector-ruleview-ready",
// Event notifications for the attribute-value editor
EDITOR_OPENED: "inspector-editor-opened",
EDITOR_CLOSED: "inspector-editor-closed",
@ -740,6 +747,7 @@ InspectorUI.prototype = {
toolEvents: null,
inspecting: false,
treePanelEnabled: true,
ruleViewEnabled: true,
isDirty: false,
store: null,
@ -891,6 +899,11 @@ InspectorUI.prototype = {
this.treePanel = new TreePanel(this.chromeWin, this);
}
if (Services.prefs.getBoolPref("devtools.ruleview.enabled") &&
!this.toolRegistered("ruleview")) {
this.registerRuleView();
}
if (Services.prefs.getBoolPref("devtools.styleinspector.enabled") &&
!this.toolRegistered("styleinspector")) {
this.stylePanel = new StyleInspector(this.chromeWin, this);
@ -910,6 +923,31 @@ InspectorUI.prototype = {
this.initializeHighlighter();
},
/**
* Register the Rule View in the Sidebar.
*/
registerRuleView: function IUI_registerRuleView()
{
let isOpen = this.isRuleViewOpen.bind(this);
this.ruleViewObject = {
id: "ruleview",
label: this.strings.GetStringFromName("ruleView.label"),
tooltiptext: this.strings.GetStringFromName("ruleView.tooltiptext"),
accesskey: this.strings.GetStringFromName("ruleView.accesskey"),
context: this,
get isOpen() isOpen(),
show: this.openRuleView,
hide: this.closeRuleView,
onSelect: this.selectInRuleView,
panel: null,
unregister: this.destroyRuleView,
sidebar: true,
};
this.registerTool(this.ruleViewObject);
},
/**
* Register and initialize any included tools.
*/
@ -1271,6 +1309,82 @@ InspectorUI.prototype = {
}
},
/////////////////////////////////////////////////////////////////////////
//// CssRuleView methods
/**
* Is the cssRuleView open?
*/
isRuleViewOpen: function IUI_isRuleViewOpen()
{
return this.isSidebarOpen && this.ruleButton.hasAttribute("checked") &&
(this.sidebarDeck.selectedPanel == this.getToolIframe(this.ruleViewObject));
},
/**
* Convenience getter to retrieve the Rule Button.
*/
get ruleButton()
{
return this.chromeDoc.getElementById(
this.getToolbarButtonId(this.ruleViewObject.id));
},
/**
* Open the CssRuleView.
*/
openRuleView: function IUI_openRuleView()
{
let iframe = this.getToolIframe(this.ruleViewObject);
let boundLoadListener = function() {
iframe.removeEventListener("load", boundLoadListener, true);
let doc = iframe.contentDocument;
this.ruleView = new CssRuleView(doc);
let body = doc.getElementById("ruleview-body");
body.appendChild(this.ruleView.element);
this.ruleView.highlight(this.selection);
Services.obs.notifyObservers(null,
INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, null);
}.bind(this);
iframe.addEventListener("load", boundLoadListener, true);
iframe.setAttribute("src", "chrome://browser/content/devtools/cssruleview.xhtml");
},
/**
* Stub to Close the CSS Rule View. Does nothing currently because the
* Rule View lives in the sidebar.
*/
closeRuleView: function IUI_closeRuleView()
{
// do nothing for now
},
/**
* Update the selected node in the Css Rule View.
* @param {nsIDOMnode} the selected node.
*/
selectInRuleView: function IUI_selectInRuleView(aNode)
{
if (this.ruleView)
this.ruleView.highlight(aNode);
},
/**
* Destroy the rule view.
*/
destroyRuleView: function IUI_destroyRuleView()
{
let iframe = this.getToolIframe(this.ruleViewObject);
iframe.parentNode.removeChild(iframe);
if (this.ruleView) {
this.ruleView.clear();
delete this.ruleView;
}
},
/////////////////////////////////////////////////////////////////////////
//// Utility Methods
@ -1552,10 +1666,6 @@ InspectorUI.prototype = {
// wire up button to show the iframe
this.bindToolEvent(btn, "click", function showIframe() {
let visible = this.sidebarDeck.selectedPanel == iframe;
if (!visible) {
sidebarDeck.selectedPanel = iframe;
}
this.toolShow(aRegObj);
}.bind(this));
},
@ -1580,6 +1690,14 @@ InspectorUI.prototype = {
let btn = this.chromeDoc.getElementById(this.getToolbarButtonId(aTool.id));
btn.setAttribute("checked", "true");
if (aTool.sidebar) {
this.sidebarDeck.selectedPanel = this.getToolIframe(aTool);
this.sidebarTools.forEach(function(other) {
if (other != aTool)
this.chromeDoc.getElementById(
this.getToolbarButtonId(other.id)).removeAttribute("checked");
}.bind(this));
}
},
/**
@ -1689,16 +1807,24 @@ InspectorUI.prototype = {
restoreToolState: function IUI_restoreToolState(aWinID)
{
let openTools = this.store.getValue(aWinID, "openTools");
let activeSidebarTool;
if (openTools) {
this.toolsDo(function IUI_toolsOnShow(aTool) {
if (aTool.id in openTools) {
if (aTool.sidebar && !this.isSidebarOpen) {
this.showSidebar();
activeSidebarTool = aTool;
}
this.toolShow(aTool);
}
}.bind(this));
this.sidebarTools.forEach(function(tool) {
if (tool != activeSidebarTool)
this.chromeDoc.getElementById(
this.getToolbarButtonId(tool.id)).removeAttribute("checked");
}.bind(this));
}
Services.obs.notifyObservers(null, INSPECTOR_NOTIFICATIONS.STATE_RESTORED, null);
},
/**

Просмотреть файл

@ -95,22 +95,34 @@ function treePanelTests()
executeSoon(function() {
InspectorUI.showSidebar();
document.getElementById(InspectorUI.getToolbarButtonId("styleinspector")).click();
});
}
function stylePanelTests()
{
Services.obs.removeObserver(stylePanelTests, "StyleInspector-opened");
Services.obs.addObserver(runContextMenuTest,
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open");
ok(InspectorUI.stylePanel.cssHtmlTree, "Style Panel has a cssHtmlTree");
InspectorUI.ruleButton.click();
executeSoon(function() {
ruleViewTests();
});
}
function ruleViewTests()
{
Services.obs.addObserver(runContextMenuTest,
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
ok(InspectorUI.isRuleViewOpen(), "Rule View is open");
ok(InspectorUI.ruleView, "InspectorUI has a cssRuleView");
executeSoon(function() {
InspectorUI.closeInspectorUI();
});
}
function runContextMenuTest()
@ -193,6 +205,10 @@ function finishInspectorTests()
ok(!InspectorUI.treePanel, "Inspector Tree Panel is closed");
ok(!InspectorUI.inspecting, "Inspector is not inspecting");
ok(!InspectorUI.isSidebarOpen, "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");
gBrowser.removeCurrentTab();

Просмотреть файл

@ -62,6 +62,7 @@ function inspectorUIOpen1()
// 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");
@ -88,6 +89,7 @@ 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");
// Activate the inspector again.
@ -147,6 +149,26 @@ function inspectorOpenTreePanelTab1()
is(InspectorUI.store.length, 2, "Inspector.store.length = 2");
is(InspectorUI.selection, div, "selection matches the div element");
Services.obs.addObserver(inspectorSidebarStyleView1, "StyleInspector-opened", false);
executeSoon(function() {
InspectorUI.showSidebar();
InspectorUI.toolShow(InspectorUI.stylePanel.registrationObject);
});
}
function inspectorSidebarStyleView1()
{
Services.obs.removeObserver(inspectorSidebarStyleView1, "StyleInspector-opened");
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open");
ok(InspectorUI.stylePanel, "Inspector Has a Style Panel Instance");
InspectorUI.sidebarTools.forEach(function(aTool) {
let btn = document.getElementById(InspectorUI.getToolbarButtonId(aTool.id));
is(btn.hasAttribute("checked"),
(aTool == InspectorUI.stylePanel.registrationObject),
"Button " + btn.id + " has correct checked attribute");
});
// Switch back to tab 2.
Services.obs.addObserver(inspectorFocusTab2,
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
@ -161,6 +183,7 @@ function inspectorFocusTab2()
// Make sure the inspector is still open.
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
is(InspectorUI.store.length, 2, "Inspector.store.length is 2");
isnot(InspectorUI.selection, div, "selection does not match the div element");
@ -180,6 +203,15 @@ function inspectorSecondFocusTab1()
is(InspectorUI.store.length, 2, "Inspector.store.length = 2");
is(InspectorUI.selection, div, "selection matches the div element");
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open");
ok(InspectorUI.stylePanel, "Inspector Has a Style Panel Instance");
InspectorUI.sidebarTools.forEach(function(aTool) {
let btn = document.getElementById(InspectorUI.getToolbarButtonId(aTool.id));
is(btn.hasAttribute("checked"),
(aTool == InspectorUI.stylePanel.registrationObject),
"Button " + btn.id + " has correct checked attribute");
});
// Switch back to tab 2.
Services.obs.addObserver(inspectorSecondFocusTab2,
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
@ -194,6 +226,8 @@ function inspectorSecondFocusTab2()
// Make sure the inspector is still open.
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
is(InspectorUI.store.length, 2, "Inspector.store.length is 2");
isnot(InspectorUI.selection, div, "selection does not match the div element");

Просмотреть файл

@ -23,3 +23,8 @@ htmlPanel.tooltiptext=HTML panel
# toolbar button.
htmlPanel.accesskey=H
# 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