зеркало из https://github.com/mozilla/gecko-dev.git
Bug 699475 - Integrate RuleView into Highlighter Sidebar; r=dcamp
This commit is contained in:
Родитель
5fe53f36e1
Коммит
7c8aa5c30d
|
@ -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
|
Загрузка…
Ссылка в новой задаче