diff --git a/browser/devtools/highlighter/inspector.jsm b/browser/devtools/highlighter/inspector.jsm
index 4498e60a458..361fd38621e 100644
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -1011,6 +1011,9 @@ InspectorUI.prototype = {
* 1. Open the link in view source (for element style attributes)
* 2. Open the link in the style editor
*
+ * Like the style editor, we only view stylesheets contained in
+ * document.styleSheets.
+ *
* @param aEvent The event containing the style rule to act on
*/
ruleViewCSSLinkClicked: function(aEvent)
@@ -1021,12 +1024,29 @@ InspectorUI.prototype = {
let rule = aEvent.detail.rule;
let styleSheet = rule.sheet;
+ let doc = this.chromeWin.content.document;
+ let styleSheets = doc.styleSheets;
+ let contentSheet = false;
+ let line = rule.ruleLine || 0;
- if (styleSheet) {
- this.chromeWin.StyleEditor.openChrome(styleSheet, rule.ruleLine);
+ // 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.chromeWin.StyleEditor.openChrome(styleSheet, line);
} else {
- let href = rule.elementStyle.element.ownerDocument.location.href;
- this.chromeWin.openUILinkIn("view-source:" + href, "window");
+ let href = styleSheet ? styleSheet.href : "";
+ if (rule.elementStyle.element) {
+ href = rule.elementStyle.element.ownerDocument.location.href;
+ }
+ let viewSourceUtils = this.chromeWin.gViewSourceUtils;
+ viewSourceUtils.viewSource(href, null, doc, line);
}
},
diff --git a/browser/devtools/styleinspector/CssHtmlTree.jsm b/browser/devtools/styleinspector/CssHtmlTree.jsm
index 73db08312ae..4b31af15ed1 100644
--- a/browser/devtools/styleinspector/CssHtmlTree.jsm
+++ b/browser/devtools/styleinspector/CssHtmlTree.jsm
@@ -1211,18 +1211,45 @@ SelectorView.prototype = {
* 1. Open the link in view source (for element style attributes).
* 2. Open the link in the style editor.
*
+ * Like the style editor, we only view stylesheets contained in
+ * document.styleSheets inside the style editor.
+ *
* @param aEvent The click event
*/
openStyleEditor: function(aEvent)
{
- if (this.selectorInfo.selector._cssRule._cssSheet) {
- let styleSheet = this.selectorInfo.selector._cssRule._cssSheet.domSheet;
- let line = this.selectorInfo.ruleLine;
+ let rule = this.selectorInfo.selector._cssRule;
+ let doc = this.tree.win.content.document;
+ let line = this.selectorInfo.ruleLine || 0;
+ let cssSheet = rule._cssSheet;
+ let contentSheet = false;
+ let styleSheet;
+ let styleSheets;
+ if (cssSheet) {
+ styleSheet = cssSheet.domSheet;
+ styleSheets = doc.styleSheets;
+
+ // Array.prototype.indexOf always returns -1 here so we loop through
+ // the styleSheets array instead.
+ for each (let sheet in styleSheets) {
+ if (sheet == styleSheet) {
+ contentSheet = true;
+ break;
+ }
+ }
+ }
+
+ if (contentSheet) {
this.tree.win.StyleEditor.openChrome(styleSheet, line);
} else {
- let href = this.selectorInfo.sourceElement.ownerDocument.location.href;
- this.tree.win.openUILinkIn("view-source:" + href, "window");
+ let href = styleSheet ? styleSheet.href : "";
+ let viewSourceUtils = this.tree.win.gViewSourceUtils;
+
+ if (this.selectorInfo.sourceElement) {
+ href = this.selectorInfo.sourceElement.ownerDocument.location.href;
+ }
+ viewSourceUtils.viewSource(href, null, doc, line);
}
},
};
diff --git a/browser/devtools/styleinspector/test/Makefile.in b/browser/devtools/styleinspector/test/Makefile.in
index b4cae20ef6a..b5b7253b0d5 100644
--- a/browser/devtools/styleinspector/test/Makefile.in
+++ b/browser/devtools/styleinspector/test/Makefile.in
@@ -67,6 +67,8 @@ _BROWSER_TEST_FILES = \
browser_bug_592743_specificity.js \
browser_ruleview_bug_703643_context_menu_copy.js \
browser_computedview_bug_703643_context_menu_copy.js \
+ browser_ruleview_734259_style_editor_link.js \
+ browser_computedview_734259_style_editor_link.js \
head.js \
$(NULL)
diff --git a/browser/devtools/styleinspector/test/browser_computedview_734259_style_editor_link.js b/browser/devtools/styleinspector/test/browser_computedview_734259_style_editor_link.js
new file mode 100644
index 00000000000..a35c4ffc469
--- /dev/null
+++ b/browser/devtools/styleinspector/test/browser_computedview_734259_style_editor_link.js
@@ -0,0 +1,161 @@
+/* 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 doc;
+let win;
+let stylePanel;
+
+function createDocument()
+{
+ doc.body.innerHTML = '
\n' +
+ '
Some header text
\n' +
+ '
hi.
\n' +
+ '
I am a test-case. This text exists ' +
+ 'solely to provide some things to ' +
+ 'highlight and count ' +
+ 'style list-items in the box at right. If you are reading this, ' +
+ 'you should go do something else instead. Maybe read a book. Or better ' +
+ 'yet, write some test-cases for another bit of code. ' +
+ 'some text
\n' +
+ '
more text
\n' +
+ '
even more text
' +
+ '
';
+ doc.title = "Rule view style editor link test";
+
+ let span = doc.querySelector("span");
+ ok(span, "captain, we have the span");
+
+ stylePanel = new StyleInspector(window);
+ Services.obs.addObserver(testInlineStyle, "StyleInspector-populated", false);
+ stylePanel.createPanel(false, function() {
+ stylePanel.open(span);
+ });
+}
+
+function testInlineStyle()
+{
+ Services.obs.removeObserver(testInlineStyle, "StyleInspector-populated", false);
+
+ ok(stylePanel.isOpen(), "style inspector is open");
+
+ info("expanding property");
+ expandProperty(0, function propertyExpanded() {
+ Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
+ if (aTopic != "domwindowopened") {
+ return;
+ }
+ info("window opened");
+ win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+ win.addEventListener("load", function windowLoad() {
+ win.removeEventListener("load", windowLoad);
+ info("window load completed");
+ let windowType = win.document.documentElement.getAttribute("windowtype");
+ is(windowType, "navigator:view-source", "view source window is open");
+ info("closing window");
+ win.close();
+ Services.ww.unregisterNotification(onWindow);
+ testInlineStyleSheet();
+ });
+ });
+ let link = getLinkByIndex(0);
+ link.click();
+ });
+}
+
+function testInlineStyleSheet()
+{
+ info("clicking an inline stylesheet");
+
+ Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
+ if (aTopic != "domwindowopened") {
+ return;
+ }
+ info("window opened");
+ win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+ win.addEventListener("load", function windowLoad() {
+ win.removeEventListener("load", windowLoad);
+ info("window load completed");
+ let windowType = win.document.documentElement.getAttribute("windowtype");
+ is(windowType, "Tools:StyleEditor", "style editor window is open");
+
+ win.styleEditorChrome.addChromeListener({
+ onEditorAdded: function checkEditor(aChrome, aEditor) {
+ if (!aEditor.sourceEditor) {
+ aEditor.addActionListener({
+ onAttach: function (aEditor) {
+ aEditor.removeActionListener(this);
+ validateStyleEditorSheet(aEditor);
+ }
+ });
+ } else {
+ validateStyleEditorSheet(aEditor);
+ }
+ }
+ });
+ Services.ww.unregisterNotification(onWindow);
+ });
+ });
+ let link = getLinkByIndex(1);
+ link.click();
+}
+
+function validateStyleEditorSheet(aEditor)
+{
+ info("validating style editor stylesheet");
+
+ let sheet = doc.styleSheets[0];
+ is(aEditor.styleSheet, sheet, "loaded stylesheet matches document stylesheet");
+ info("closing window");
+ win.close();
+
+ Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
+ stylePanel.close();
+}
+
+function expandProperty(aIndex, aCallback)
+{
+ let iframe = stylePanel.iframe;
+ let contentDoc = iframe.contentDocument;
+ let contentWindow = iframe.contentWindow;
+ let expando = contentDoc.querySelectorAll(".expandable")[aIndex];
+ expando.click();
+
+ // We use executeSoon to give the property time to expand.
+ executeSoon(aCallback);
+}
+
+function getLinkByIndex(aIndex)
+{
+ let contentDoc = stylePanel.iframe.contentDocument;
+ let links = contentDoc.querySelectorAll(".rule-link .link");
+ return links[aIndex];
+}
+
+function finishUp()
+{
+ Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
+ ok(!stylePanel.isOpen(), "style inspector is closed");
+ doc = win = stylePanel = null;
+ gBrowser.removeCurrentTab();
+ finish();
+}
+
+function test()
+{
+ waitForExplicitFinish();
+
+ gBrowser.selectedTab = gBrowser.addTab();
+ gBrowser.selectedBrowser.addEventListener("load", function(evt) {
+ gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
+ true);
+ doc = content.document;
+ waitForFocus(createDocument, content);
+ }, true);
+
+ content.location = "data:text/html,Computed view style editor link test
";
+}
diff --git a/browser/devtools/styleinspector/test/browser_ruleview_734259_style_editor_link.js b/browser/devtools/styleinspector/test/browser_ruleview_734259_style_editor_link.js
new file mode 100644
index 00000000000..9ca43c8202b
--- /dev/null
+++ b/browser/devtools/styleinspector/test/browser_ruleview_734259_style_editor_link.js
@@ -0,0 +1,181 @@
+/* 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 win;
+let doc;
+let contentWindow;
+
+let tempScope = {};
+Cu.import("resource:///modules/Services.jsm", tempScope);
+let Services = tempScope.Services;
+
+function createDocument()
+{
+ doc.body.innerHTML = ' \n' +
+ '
Some header text
\n' +
+ '
hi.
\n' +
+ '
I am a test-case. This text exists ' +
+ 'solely to provide some things to ' +
+ 'highlight and count ' +
+ 'style list-items in the box at right. If you are reading this, ' +
+ 'you should go do something else instead. Maybe read a book. Or better ' +
+ 'yet, write some test-cases for another bit of code. ' +
+ 'some text
\n' +
+ '
more text
\n' +
+ '
even more text
' +
+ '
';
+ doc.title = "Rule view style editor link test";
+
+ openInspector();
+}
+
+function openInspector()
+{
+ ok(window.InspectorUI, "InspectorUI variable exists");
+ ok(!InspectorUI.inspecting, "Inspector is not highlighting");
+ ok(InspectorUI.store.isEmpty(), "Inspector.store is empty");
+
+ Services.obs.addObserver(inspectorUIOpen,
+ InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
+ InspectorUI.openInspectorUI();
+}
+
+function inspectorUIOpen()
+{
+ Services.obs.removeObserver(inspectorUIOpen,
+ 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.
+ let div = content.document.getElementsByTagName("div")[0];
+ InspectorUI.inspectNode(div);
+ InspectorUI.stopInspecting();
+ is(InspectorUI.selection, div, "selection matches the div element");
+
+ Services.obs.addObserver(testInlineStyle,
+ InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
+
+ InspectorUI.showSidebar();
+ InspectorUI.openRuleView();
+}
+
+function testInlineStyle()
+{
+ Services.obs.removeObserver(testInlineStyle,
+ InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
+
+ executeSoon(function() {
+ info("clicking an inline style");
+
+ Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
+ if (aTopic != "domwindowopened") {
+ return;
+ }
+
+ win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+ win.addEventListener("load", function windowLoad() {
+ win.removeEventListener("load", windowLoad);
+ let windowType = win.document.documentElement.getAttribute("windowtype");
+ is(windowType, "navigator:view-source", "view source window is open");
+ win.close();
+ Services.ww.unregisterNotification(onWindow);
+ testInlineStyleSheet();
+ });
+ });
+ EventUtils.synthesizeMouseAtCenter(getLinkByIndex(0), { }, contentWindow);
+ });
+}
+
+function testInlineStyleSheet()
+{
+ info("clicking an inline stylesheet");
+
+ Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
+ if (aTopic != "domwindowopened") {
+ return;
+ }
+
+ win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+ win.addEventListener("load", function windowLoad() {
+ win.removeEventListener("load", windowLoad);
+
+ let windowType = win.document.documentElement.getAttribute("windowtype");
+ is(windowType, "Tools:StyleEditor", "style editor window is open");
+
+ win.styleEditorChrome.addChromeListener({
+ onEditorAdded: function checkEditor(aChrome, aEditor) {
+ if (!aEditor.sourceEditor) {
+ aEditor.addActionListener({
+ onAttach: function (aEditor) {
+ aEditor.removeActionListener(this);
+ validateStyleEditorSheet(aEditor);
+ }
+ });
+ } else {
+ validateStyleEditorSheet(aEditor);
+ }
+ }
+ });
+
+ Services.ww.unregisterNotification(onWindow);
+ });
+ });
+
+ EventUtils.synthesizeMouse(getLinkByIndex(1), 5, 5, { }, contentWindow);
+}
+
+function validateStyleEditorSheet(aEditor)
+{
+ info("validating style editor stylesheet");
+
+ let sheet = doc.styleSheets[0];
+
+ is(aEditor.styleSheet, sheet, "loaded stylesheet matches document stylesheet");
+ win.close();
+
+ finishup();
+}
+
+function getLinkByIndex(aIndex)
+{
+ let ruleView = document.querySelector("#devtools-sidebar-iframe-ruleview");
+ let contentDoc = ruleView.contentDocument;
+ let links = contentDoc.querySelectorAll(".ruleview-rule-source");
+ contentWindow = ruleView.contentWindow;
+ return links[aIndex];
+}
+
+function finishup()
+{
+ InspectorUI.hideSidebar();
+ InspectorUI.closeInspectorUI();
+ gBrowser.removeCurrentTab();
+ doc = contentWindow = win = null;
+ finish();
+}
+
+function test()
+{
+ waitForExplicitFinish();
+
+ gBrowser.selectedTab = gBrowser.addTab();
+ gBrowser.selectedBrowser.addEventListener("load", function(evt) {
+ gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
+ true);
+ doc = content.document;
+ waitForFocus(createDocument, content);
+ }, true);
+
+ content.location = "data:text/html,Rule view style editor link test
";
+}
diff --git a/browser/devtools/styleinspector/test/browser_ruleview_bug_703643_context_menu_copy.js b/browser/devtools/styleinspector/test/browser_ruleview_bug_703643_context_menu_copy.js
index 25e37ffe8bf..9dd38b895bb 100644
--- a/browser/devtools/styleinspector/test/browser_ruleview_bug_703643_context_menu_copy.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_bug_703643_context_menu_copy.js
@@ -187,6 +187,7 @@ function checkClipboardData(aExpectedPattern)
function finishup()
{
+ InspectorUI.hideSidebar();
InspectorUI.closeInspectorUI();
gBrowser.removeCurrentTab();
doc = null;
diff --git a/browser/devtools/styleinspector/test/browser_ruleview_focus.js b/browser/devtools/styleinspector/test/browser_ruleview_focus.js
index 3500a586013..29f051207a5 100644
--- a/browser/devtools/styleinspector/test/browser_ruleview_focus.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_focus.js
@@ -77,7 +77,7 @@ function testFocus()
// If not, we'll wait here until we time out.
waitForEditorFocus(brace.parentNode, function onNewEditor(aEditor) {
aEditor.input.blur();
- finishTest();
+ finishUp();
});
EventUtils.sendKey("return");
});
@@ -89,6 +89,8 @@ function testFocus()
function finishUp()
{
+ InspectorUI.hideSidebar();
+ InspectorUI.closeInspectorUI();
doc = stylePanel = null;
gBrowser.removeCurrentTab();
finish();