--- a/devtools/client/accessibility/components/Accessible.js
+++ b/devtools/client/accessibility/components/Accessible.js
@@ -19,16 +19,18 @@ const {flashElementOn, flashElementOff}
require("devtools/client/inspector/markup/utils");
const { updateDetails } = require("../actions/details");
const Tree = createFactory(require("devtools/client/shared/components/VirtualizedTree"));
// Reps
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
const { Rep, ElementNode } = REPS;
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
+
const TELEMETRY_NODE_INSPECTED_COUNT = "devtools.accessibility.node_inspected_count";
class AccessiblePropertyClass extends Component {
static get propTypes() {
return {
accessible: PropTypes.string,
object: PropTypes.any,
focused: PropTypes.bool,
@@ -170,33 +172,17 @@ class Accessible extends Component {
return;
}
gToolbox.selectTool("inspector").then(() =>
gToolbox.selection.setNodeFront(nodeFront, reason));
}
openLink(link, e) {
- if (!gToolbox) {
- return;
- }
-
- // Avoid using Services.appinfo.OS in order to keep accessible pane's frontend free of
- // priveleged code.
- const os = window.navigator.userAgent;
- const isOSX = os && os.includes("Mac");
- let where = "tab";
- if (e && (e.button === 1 || (e.button === 0 && (isOSX ? e.metaKey : e.ctrlKey)))) {
- where = "tabshifted";
- } else if (e && e.shiftKey) {
- where = "window";
- }
-
- const win = gToolbox.doc.defaultView.top;
- win.openWebLinkIn(link, where);
+ openContentLink(link);
}
renderItem(item, depth, focused, arrow, expanded) {
const object = item.contents;
const valueProps = {
object,
mode: MODE.TINY,
title: "Object",
--- a/devtools/client/accessibility/test/mochitest/test_accessible_openLink.html
+++ b/devtools/client/accessibility/test/mochitest/test_accessible_openLink.html
@@ -17,73 +17,61 @@ Test that openLink function is called if
<pre id="test">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
"use strict";
window.onload = async function() {
try {
+ const { gDevTools } = require("devtools/client/framework/devtools");
const Services = browserRequire("Services");
const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
const { createFactory, createElement } =
browserRequire("devtools/client/shared/vendor/react");
const { Provider } = require("devtools/client/shared/vendor/react-redux");
const createStore = require("devtools/client/shared/redux/create-store")();
const { Simulate } =
browserRequire("devtools/client/shared/vendor/react-dom-test-utils");
const Accessible = createFactory(
browserRequire("devtools/client/accessibility/components/Accessible"));
function testLinkClicked(link, event, expectedUrl, expectedWhere) {
+ const browserWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+ const defaultOpenWebLinkIn = browserWindow.openWebLinkIn;
+
const checker = Symbol();
let onClickArgs = checker;
- const mockToolbox = {
- doc: {
- defaultView: {
- top: {
- openWebLinkIn: (url, where) => {
- onClickArgs = { url, where };
- }
- }
- }
- }
+ browserWindow.openWebLinkIn = (url, where) => {
+ onClickArgs = { url, where };
};
- window.gToolbox = mockToolbox;
Simulate.click(link, event);
ok(onClickArgs !== checker, "Link was clicked");
is(onClickArgs.url, expectedUrl, "Correct URL is opened");
is(onClickArgs.where, expectedWhere, "URL was opened correctly");
- window.gToolbox = null;
+ browserWindow.openWebLinkIn = defaultOpenWebLinkIn;
}
const a = Accessible({ labelledby: "Test Accessible" });
ok(a, "Should be able to create Accessible instances");
let URL = "http://example.com";
const mockStore = createStore((state, action) =>
action ? { ...state, ...action } : state,
{ details: { DOMNode: {}, accessible: { value: URL } } });
const provider = createElement(Provider, { store: mockStore }, a);
const accessible = ReactDOM.render(provider, window.document.body);
ok(accessible, "Should be able to mount Accessible instances");
let link = document.querySelector(".url");
testLinkClicked(link, null, URL, "tab");
- let event = { button: 0 };
- event[Services.appinfo.OS == "Darwin" ? "metaKey" : "ctrlKey"] = true;
- testLinkClicked(link, event, URL, "tabshifted");
-
- event = { shiftKey: true };
- testLinkClicked(link, event, URL, "window");
-
URL = "non-URL";
await mockStore.dispatch(
{ type: "update", details: { DOMNode: {}, accessible: { value: URL } } });
link = document.querySelector(".url");
ok(!link, "Non URL link should not be rendered as a link.");
} catch (e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
--- a/devtools/client/application/src/components/WorkerListEmpty.js
+++ b/devtools/client/application/src/components/WorkerListEmpty.js
@@ -1,15 +1,15 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-const { openWebLink, openTrustedLink } = require("devtools/client/shared/link");
+const { openDocLink, openTrustedLink } = require("devtools/client/shared/link");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { createFactory, Component } = require("devtools/client/shared/vendor/react");
const { a, article, h1, li, p, ul } = require("devtools/client/shared/vendor/react-dom-factories");
const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized);
const DOC_URL = "https://developer.mozilla.org/docs/Web/API/Service_Worker_API/Using_Service_Workers" +
@@ -34,17 +34,17 @@ class WorkerListEmpty extends Component
this.props.serviceContainer.selectTool("jsdebugger");
}
openAboutDebugging() {
openTrustedLink("about:debugging#workers");
}
openDocumentation() {
- openWebLink(DOC_URL);
+ openDocLink(DOC_URL);
}
render() {
return article(
{ className: "worker-list-empty" },
Localized({
id: "serviceworker-empty-intro",
a: a({ className: "external-link", onClick: () => this.openDocumentation() })
--- a/devtools/client/debugger/content/views/sources-view.js
+++ b/devtools/client/debugger/content/views/sources-view.js
@@ -23,17 +23,18 @@ const { bindActionCreators } = require("
const { extend } = require("devtools/shared/extend");
const {
WidgetMethods,
setNamedTimeout
} = require("devtools/client/shared/widgets/view-helpers");
const { Task } = require("devtools/shared/task");
const { SideMenuWidget } = require("resource://devtools/client/shared/widgets/SideMenuWidget.jsm");
const { gDevTools } = require("devtools/client/framework/devtools");
-const {KeyCodes} = require("devtools/client/shared/keycodes");
+const { KeyCodes } = require("devtools/client/shared/keycodes");
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
const NEW_SOURCE_DISPLAY_DELAY = 200; // ms
const FUNCTION_SEARCH_POPUP_POSITION = "topcenter bottomleft";
const BREAKPOINT_LINE_TOOLTIP_MAX_LENGTH = 1000; // chars
const BREAKPOINT_CONDITIONAL_POPUP_POSITION = "before_start";
const BREAKPOINT_CONDITIONAL_POPUP_OFFSET_X = 7; // px
const BREAKPOINT_CONDITIONAL_POPUP_OFFSET_Y = -3; // px
@@ -893,20 +894,18 @@ SourcesView.prototype = extend(WidgetMet
}
clipboardHelper.copyString(selected.source.url);
},
/**
* Opens selected item source in a new tab.
*/
_onNewTabCommand: function () {
- let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
let selected = this.selectedItem.attachment;
- win.openWebLinkIn(selected.source.url, "tab", {
- triggeringPrincipal: win.document.nodePrincipal,
+ openContentLink(selected.source.url, {
relatedToCurrent: true,
});
},
/**
* Function called each time a breakpoint item is removed.
*
* @param object aItem
--- a/devtools/client/debugger/new/panel.js
+++ b/devtools/client/debugger/new/panel.js
@@ -3,16 +3,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Task } = require("devtools/shared/task");
const { LocalizationHelper } = require("devtools/shared/l10n");
const { gDevTools } = require("devtools/client/framework/devtools");
const { TargetFactory } = require("devtools/client/framework/target");
const { Toolbox } = require("devtools/client/framework/toolbox");
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
const DBG_STRINGS_URI = "devtools/client/locales/debugger.properties";
const L10N = new LocalizationHelper(DBG_STRINGS_URI);
function DebuggerPanel(iframeWindow, toolbox) {
this.panelWin = iframeWindow;
this.panelWin.L10N = L10N;
this.toolbox = toolbox;
@@ -58,34 +59,17 @@ DebuggerPanel.prototype = {
};
},
_getState: function() {
return this._store.getState();
},
openLink: function(url) {
- const parentDoc = this.toolbox.doc;
- if (!parentDoc) {
- return;
- }
-
- const win = parentDoc.querySelector("window");
- if (!win) {
- return;
- }
-
- const top = win.ownerDocument.defaultView.top;
- if (!top || typeof top.openWebLink !== "function") {
- return;
- }
-
- top.openWebLinkIn(url, "tab", {
- triggeringPrincipal: win.document.nodePrincipal
- });
+ openContentLink(url);
},
openWorkerToolbox: async function(worker) {
const [response, workerClient] =
await this.toolbox.target.client.attachWorker(worker.actor);
const workerTarget = TargetFactory.forWorker(workerClient);
const toolbox = await gDevTools.showToolbox(workerTarget, "jsdebugger", Toolbox.HostType.WINDOW);
toolbox.once("destroy", () => workerClient.detach());
--- a/devtools/client/dom/dom-panel.js
+++ b/devtools/client/dom/dom-panel.js
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Cu } = require("chrome");
const ObjectClient = require("devtools/shared/client/object-client");
const defer = require("devtools/shared/defer");
const EventEmitter = require("devtools/shared/event-emitter");
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
/**
* This object represents DOM panel. It's responsibility is to
* render Document Object Model of the current debugger target.
*/
function DomPanel(iframeWindow, toolbox) {
this.panelWin = iframeWindow;
this._toolbox = toolbox;
@@ -174,20 +175,17 @@ DomPanel.prototype = {
});
this.pendingRequests.set(grip.actor, deferred.promise);
return deferred.promise;
},
openLink: function(url) {
- const parentDoc = this._toolbox.doc;
- const iframe = parentDoc.getElementById("this._toolbox");
- const top = iframe.ownerDocument.defaultView.top;
- top.openWebLinkIn(url, "tab");
+ openContentLink(url);
},
getRootGrip: function() {
const deferred = defer();
// Attach Console. It might involve RDP communication, so wait
// asynchronously for the result
this.target.activeConsole.evaluateJSAsync("window", res => {
--- a/devtools/client/framework/components/ToolboxToolbar.js
+++ b/devtools/client/framework/components/ToolboxToolbar.js
@@ -2,17 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const {div, button} = dom;
-const {openWebLink} = require("devtools/client/shared/link");
+const {openDocLink} = require("devtools/client/shared/link");
const Menu = require("devtools/client/framework/menu");
const MenuItem = require("devtools/client/framework/menu-item");
const ToolboxTabs = createFactory(require("devtools/client/framework/components/ToolboxTabs"));
/**
* This is the overall component for the toolbox toolbar. It is designed to not know how
* the state is being managed, and attempts to be as pure as possible. The
@@ -427,27 +427,27 @@ function showMeatballMenu(
menu.append(new MenuItem({ type: "separator" }));
}
// Getting started
menu.append(new MenuItem({
id: "toolbox-meatball-menu-documentation",
label: L10N.getStr("toolbox.meatballMenu.documentation.label"),
click: () => {
- openWebLink(
+ openDocLink(
"https://developer.mozilla.org/docs/Tools?utm_source=devtools&utm_medium=tabbar-menu");
},
}));
// Give feedback
menu.append(new MenuItem({
id: "toolbox-meatball-menu-community",
label: L10N.getStr("toolbox.meatballMenu.community.label"),
click: () => {
- openWebLink(
+ openDocLink(
"https://discourse.mozilla.org/c/devtools?utm_source=devtools&utm_medium=tabbar-menu");
},
}));
const rect = menuButton.getBoundingClientRect();
const screenX = menuButton.ownerDocument.defaultView.mozInnerScreenX;
const screenY = menuButton.ownerDocument.defaultView.mozInnerScreenY;
--- a/devtools/client/framework/target.js
+++ b/devtools/client/framework/target.js
@@ -385,16 +385,29 @@ TabTarget.prototype = {
return parsedURL.pathname;
} catch (e) {
// Return the url if unable to resolve the pathname.
return url;
}
},
/**
+ * For local tabs, returns the tab's contentPrincipal, which can be used as a
+ * `triggeringPrincipal` when opening links. However, this is a hack as it is not
+ * correct for subdocuments and it won't work for remote debugging. Bug 1467945 hopes
+ * to devise a better approach.
+ */
+ get contentPrincipal() {
+ if (!this.isLocalTab) {
+ return null;
+ }
+ return this.tab.linkedBrowser.contentPrincipal;
+ },
+
+ /**
* Adds remote protocol capabilities to the target, so that it can be used
* for tools that support the Remote Debugging Protocol even for local
* connections.
*/
makeRemote: async function() {
if (this._remote) {
return this._remote.promise;
}
--- a/devtools/client/inspector/computed/computed.js
+++ b/devtools/client/inspector/computed/computed.js
@@ -22,16 +22,17 @@ const {
VIEW_NODE_IMAGE_URL_TYPE,
VIEW_NODE_FONT_TYPE,
} = require("devtools/client/inspector/shared/node-types");
const TooltipsOverlay = require("devtools/client/inspector/shared/tooltips-overlay");
loader.lazyRequireGetter(this, "StyleInspectorMenu", "devtools/client/inspector/shared/style-inspector-menu");
loader.lazyRequireGetter(this, "KeyShortcuts", "devtools/client/shared/key-shortcuts");
loader.lazyRequireGetter(this, "clipboardHelper", "devtools/shared/platform/clipboard");
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
const STYLE_INSPECTOR_PROPERTIES = "devtools/shared/locales/styleinspector.properties";
const {LocalizationHelper} = require("devtools/shared/l10n");
const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
const FILTER_CHANGED_TIMEOUT = 150;
const HTML_NS = "http://www.w3.org/1999/xhtml";
@@ -693,18 +694,17 @@ CssComputedView.prototype = {
},
_onClick: function(event) {
const target = event.target;
if (target.nodeName === "a") {
event.stopPropagation();
event.preventDefault();
- const browserWin = this.inspector.target.tab.ownerDocument.defaultView;
- browserWin.openWebLinkIn(target.href, "tab");
+ openContentLink(target.href);
}
},
/**
* Callback for copy event. Copy selected text.
*
* @param {Event} event
* copy event object.
@@ -1185,22 +1185,17 @@ PropertyView.prototype = {
this.refreshMatchedSelectors();
event.preventDefault();
},
/**
* The action when a user clicks on the MDN help link for a property.
*/
mdnLinkClick: function(event) {
- const inspector = this.tree.inspector;
-
- if (inspector.target.tab) {
- const browserWin = inspector.target.tab.ownerDocument.defaultView;
- browserWin.openWebLinkIn(this.link, "tab");
- }
+ openContentLink(this.link);
},
/**
* Destroy this property view, removing event listeners
*/
destroy: function() {
if (this._matchedSelectorViews) {
for (const view of this._matchedSelectorViews) {
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -30,16 +30,17 @@ loader.lazyRequireGetter(this, "ToolSide
loader.lazyRequireGetter(this, "MarkupView", "devtools/client/inspector/markup/markup");
loader.lazyRequireGetter(this, "HighlightersOverlay", "devtools/client/inspector/shared/highlighters-overlay");
loader.lazyRequireGetter(this, "nodeConstants", "devtools/shared/dom-node-constants");
loader.lazyRequireGetter(this, "Menu", "devtools/client/framework/menu");
loader.lazyRequireGetter(this, "MenuItem", "devtools/client/framework/menu-item");
loader.lazyRequireGetter(this, "ExtensionSidebar", "devtools/client/inspector/extensions/extension-sidebar");
loader.lazyRequireGetter(this, "CommandUtils", "devtools/client/shared/developer-toolbar", true);
loader.lazyRequireGetter(this, "clipboardHelper", "devtools/shared/platform/clipboard");
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
const {LocalizationHelper, localizeMarkup} = require("devtools/shared/l10n");
const INSPECTOR_L10N =
new LocalizationHelper("devtools/client/locales/inspector.properties");
loader.lazyGetter(this, "TOOLBOX_L10N", function() {
return new LocalizationHelper("devtools/client/locales/toolbox.properties");
});
@@ -2353,18 +2354,17 @@ Inspector.prototype = {
return;
}
if (type === "uri" || type === "cssresource" || type === "jsresource") {
// Open link in a new tab.
this.inspector.resolveRelativeURL(
link, this.selection.nodeFront).then(url => {
if (type === "uri") {
- const browserWin = this.target.tab.ownerDocument.defaultView;
- browserWin.openWebLinkIn(url, "tab");
+ openContentLink(url);
} else if (type === "cssresource") {
return this.toolbox.viewSourceInStyleEditor(url);
} else if (type === "jsresource") {
return this.toolbox.viewSourceInDebugger(url);
}
return null;
}).catch(console.error);
} else if (type == "idref") {
--- a/devtools/client/inspector/rules/views/text-property-editor.js
+++ b/devtools/client/inspector/rules/views/text-property-editor.js
@@ -1,29 +1,32 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-const {l10n} = require("devtools/shared/inspector/css-logic");
+const Services = require("Services");
+
+const { l10n } = require("devtools/shared/inspector/css-logic");
const {getCssProperties} = require("devtools/shared/fronts/css-properties");
const {InplaceEditor, editableField} =
require("devtools/client/shared/inplace-editor");
const {
createChild,
appendText,
advanceValidate,
blurOnMultipleProperties
} = require("devtools/client/inspector/shared/utils");
const {
parseDeclarations,
parseSingleValue,
} = require("devtools/shared/css/parsing-utils");
-const Services = require("Services");
+
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
const HTML_NS = "http://www.w3.org/1999/xhtml";
const SHARED_SWATCH_CLASS = "ruleview-swatch";
const COLOR_SWATCH_CLASS = "ruleview-colorswatch";
const BEZIER_SWATCH_CLASS = "ruleview-bezierswatch";
const FILTER_SWATCH_CLASS = "ruleview-filterswatch";
const ANGLE_SWATCH_CLASS = "ruleview-angleswatch";
@@ -279,18 +282,17 @@ TextPropertyEditor.prototype = {
});
this.valueSpan.addEventListener("click", (event) => {
const target = event.target;
if (target.nodeName === "a") {
event.stopPropagation();
event.preventDefault();
- const browserWin = this.ruleView.inspector.target.tab.ownerDocument.defaultView;
- browserWin.openWebLinkIn(target.href, "tab");
+ openContentLink(target.href);
}
});
editableField({
start: this._onStartEditing,
element: this.valueSpan,
done: this._onValueDone,
destroy: this.update,
--- a/devtools/client/inspector/shared/three-pane-onboarding-tooltip.js
+++ b/devtools/client/inspector/shared/three-pane-onboarding-tooltip.js
@@ -1,16 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Services = require("Services");
-const { openWebLink } = require("devtools/client/shared/link");
+const { openDocLink } = require("devtools/client/shared/link");
const { HTMLTooltip } = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
const { LocalizationHelper } = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/client/locales/inspector.properties");
const SHOW_THREE_PANE_ONBOARDING_PREF = "devtools.inspector.show-three-pane-tooltip";
const XHTML_NS = "http://www.w3.org/1999/xhtml";
@@ -98,13 +98,13 @@ class ThreePaneOnboardingTooltip {
/**
* Handler for the "click" event on the learn more button. Hides the onboarding tooltip
* and opens the link to the mdn page in a new tab.
*/
onLearnMoreLinkClick() {
Services.prefs.setBoolPref(SHOW_THREE_PANE_ONBOARDING_PREF, false);
this.tooltip.hide();
- openWebLink(LEARN_MORE_LINK);
+ openDocLink(LEARN_MORE_LINK);
}
}
module.exports = ThreePaneOnboardingTooltip;
--- a/devtools/client/menus.js
+++ b/devtools/client/menus.js
@@ -29,16 +29,17 @@
*/
const { Cu } = require("chrome");
loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
loader.lazyRequireGetter(this, "CommandUtils", "devtools/client/shared/developer-toolbar", true);
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
loader.lazyRequireGetter(this, "ResponsiveUIManager", "devtools/client/responsive.html/manager", true);
+loader.lazyRequireGetter(this, "openDocLink", "devtools/client/shared/link", true);
loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm");
loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
exports.menuitems = [
{ id: "menu_devToolbox",
l10nKey: "devToolboxMenuItem",
oncommand(event) {
@@ -127,13 +128,12 @@ exports.menuitems = [
}
},
{ separator: true,
id: "devToolsEndSeparator"
},
{ id: "getMoreDevtools",
l10nKey: "getMoreDevtoolsCmd",
oncommand(event) {
- const window = event.target.ownerDocument.defaultView;
- window.openWebLinkIn("https://addons.mozilla.org/firefox/collections/mozilla/webdeveloper/", "tab");
+ openDocLink("https://addons.mozilla.org/firefox/collections/mozilla/webdeveloper/");
}
},
];
--- a/devtools/client/netmonitor/src/utils/open-request-in-tab.js
+++ b/devtools/client/netmonitor/src/utils/open-request-in-tab.js
@@ -9,26 +9,24 @@
// implement the similar functionalities on its own.
//
// Please keep in mind that if the feature in this file has changed, don't
// forget to also change that accordingly in
// devtools/client/netmonitor/src/utils/firefox/open-request-in-tab.js.
"use strict";
-const Services = require("Services");
-const { gDevTools } = require("devtools/client/framework/devtools");
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
/**
* Opens given request in a new tab.
*/
function openRequestInTab(url, requestPostData) {
- const win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
if (!requestPostData) {
- win.openWebLinkIn(url, "tab", {relatedToCurrent: true});
+ openContentLink(url, {relatedToCurrent: true});
} else {
openPostRequestInTabHelper({
url,
data: requestPostData.postData
});
}
}
--- a/devtools/client/performance-new/components/Description.js
+++ b/devtools/client/performance-new/components/Description.js
@@ -1,16 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { PureComponent } = require("devtools/client/shared/vendor/react");
const { div, button, p } = require("devtools/client/shared/vendor/react-dom-factories");
-const { openWebLink } = require("devtools/client/shared/link");
+const { openDocLink } = require("devtools/client/shared/link");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const selectors = require("devtools/client/performance-new/store/selectors");
/**
* This component provides a helpful description for what is going on in the component
* and provides some external links.
*/
@@ -23,17 +23,17 @@ class Description extends PureComponent
}
constructor(props) {
super(props);
this.handleLinkClick = this.handleLinkClick.bind(this);
}
handleLinkClick(event) {
- openWebLink(event.target.value);
+ openDocLink(event.target.value);
}
/**
* Implement links as buttons to avoid any risk of loading the link in the
* the panel.
*/
renderLink(href, text) {
return button(
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -83,16 +83,17 @@ ChromeUtils.defineModuleGetter(this, "Va
"resource://devtools/client/shared/widgets/VariablesViewController.jsm");
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
loader.lazyRequireGetter(this, "EnvironmentClient", "devtools/shared/client/environment-client");
loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/object-client");
loader.lazyRequireGetter(this, "HUDService", "devtools/client/webconsole/hudservice", true);
+loader.lazyRequireGetter(this, "openDocLink", "devtools/client/shared/link", true);
XPCOMUtils.defineLazyGetter(this, "REMOTE_TIMEOUT", () =>
Services.prefs.getIntPref("devtools.debugger.remote-timeout"));
ChromeUtils.defineModuleGetter(this, "ShortcutUtils",
"resource://gre/modules/ShortcutUtils.jsm");
ChromeUtils.defineModuleGetter(this, "Reflect",
@@ -1982,18 +1983,17 @@ var Scratchpad = {
}
}
},
/**
* Opens the MDN documentation page for Scratchpad.
*/
openDocumentationPage: function SP_openDocumentationPage() {
- const url = this.strings.GetStringFromName("help.openDocumentationPage");
- this.browserWindow.openWebLinkIn(url, "tab");
+ openDocLink(this.strings.GetStringFromName("help.openDocumentationPage"));
this.browserWindow.focus();
},
};
/**
* Represents the DebuggerClient connection to a specific tab as used by the
* Scratchpad.
*
--- a/devtools/client/shared/components/MdnLink.js
+++ b/devtools/client/shared/components/MdnLink.js
@@ -1,20 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-const Services = require("Services");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
-const { gDevTools } = require("devtools/client/framework/devtools");
+const { a } = dom;
-const { a } = dom;
+loader.lazyRequireGetter(this, "openDocLink", "devtools/client/shared/link", true);
function MDNLink({ url, title }) {
return (
a({
className: "devtools-button learn-more-link",
title,
onClick: (e) => onLearnMoreClick(e, url),
})
@@ -25,20 +24,12 @@ MDNLink.displayName = "MDNLink";
MDNLink.propTypes = {
url: PropTypes.string.isRequired,
};
function onLearnMoreClick(e, url) {
e.stopPropagation();
e.preventDefault();
-
- const win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
- const { button, ctrlKey, metaKey } = e;
- const isOSX = Services.appinfo.OS == "Darwin";
- let where = "tab";
- if (button === 1 || (button === 0 && (isOSX ? metaKey : ctrlKey))) {
- where = "tabshifted";
- }
- win.openWebLinkIn(url, where, {triggeringPrincipal: win.document.nodePrincipal});
+ openDocLink(url);
}
module.exports = MDNLink;
--- a/devtools/client/shared/link.js
+++ b/devtools/client/shared/link.js
@@ -1,45 +1,86 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Services = require("Services");
const { gDevTools } = require("devtools/client/framework/devtools");
+const { TargetFactory } = require("devtools/client/framework/target");
/**
* Retrieve the most recent chrome window.
*/
function _getTopWindow() {
- return Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+ // Try the main application window, such as a browser window.
+ let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+ if (win && win.openWebLinkIn && win.openTrustedLinkIn) {
+ return win;
+ }
+ // For non-browser cases like Browser Toolbox, try any chrome window.
+ win = Services.wm.getMostRecentWindow(null);
+ if (win && win.openWebLinkIn && win.openTrustedLinkIn) {
+ return win;
+ }
+ return null;
}
/**
- * Opens a |url| controlled by webcontent in a new tab.
+ * Opens a |url| that does not require trusted access, such as a documentation page, in a
+ * new tab.
*
* @param {String} url
* The url to open.
* @param {Object} options
* Optional parameters, see documentation for openUILinkIn in utilityOverlay.js
*/
-exports.openWebLink = async function(url, options) {
+exports.openDocLink = async function(url, options) {
const top = _getTopWindow();
- if (top && typeof top.openWebLinkIn === "function") {
- top.openWebLinkIn(url, "tab", options);
+ if (!top) {
+ return;
}
+ top.openWebLinkIn(url, "tab", options);
+};
+
+/**
+ * Opens a |url| controlled by web content in a new tab.
+ *
+ * If the current tab has an open toolbox, this will attempt to refine the
+ * `triggeringPrincipal` of the link using the tab's `contentPrincipal`. This is only an
+ * approximation, so bug 1467945 hopes to improve this.
+ *
+ * @param {String} url
+ * The url to open.
+ * @param {Object} options
+ * Optional parameters, see documentation for openUILinkIn in utilityOverlay.js
+ */
+exports.openContentLink = async function(url, options = {}) {
+ const top = _getTopWindow();
+ if (!top) {
+ return;
+ }
+ if (!options.triggeringPrincipal && top.gBrowser) {
+ const tab = top.gBrowser.selectedTab;
+ if (TargetFactory.isKnownTab(tab)) {
+ const target = TargetFactory.forTab(tab);
+ options.triggeringPrincipal = target.contentPrincipal;
+ }
+ }
+ top.openWebLinkIn(url, "tab", options);
};
/**
* Open a trusted |url| in a new tab using the SystemPrincipal.
*
* @param {String} url
* The url to open.
* @param {Object} options
* Optional parameters, see documentation for openUILinkIn in utilityOverlay.js
*/
exports.openTrustedLink = async function(url, options) {
const top = _getTopWindow();
- if (top && typeof top.openTrustedLinkIn === "function") {
- top.openTrustedLinkIn(url, "tab", options);
+ if (!top) {
+ return;
}
+ top.openTrustedLinkIn(url, "tab", options);
};
--- a/devtools/client/shared/test/browser_link.js
+++ b/devtools/client/shared/test/browser_link.js
@@ -1,30 +1,30 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
-// Test link helpers openWebLink, openTrustedLink.
+// Test link helpers openDocLink, openTrustedLink.
// Use any valid test page here.
const TEST_URI = TEST_URI_ROOT + "dummy.html";
-const {openWebLink, openTrustedLink} =
+const {openDocLink, openTrustedLink} =
require("devtools/client/shared/link");
add_task(async function() {
// Open a link to a page that will not trigger any request.
info("Open web link to example.com test page");
- openWebLink(TEST_URI);
+ openDocLink(TEST_URI);
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
is(gBrowser.selectedBrowser.currentURI.spec, TEST_URI,
- "openWebLink opened a tab with the expected url");
+ "openDocLink opened a tab with the expected url");
info("Open trusted link to about:debugging");
openTrustedLink("about:debugging");
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
is(gBrowser.selectedBrowser.currentURI.spec, "about:debugging",
"openTrustedLink opened a tab with the expected url");
--- a/devtools/client/styleeditor/StyleEditorUI.jsm
+++ b/devtools/client/styleeditor/StyleEditorUI.jsm
@@ -23,16 +23,17 @@ const {SplitView} = require("resource://
const {StyleSheetEditor} = require("resource://devtools/client/styleeditor/StyleSheetEditor.jsm");
const {PluralForm} = require("devtools/shared/plural-form");
const {PrefObserver} = require("devtools/client/shared/prefs");
const csscoverage = require("devtools/shared/fronts/csscoverage");
const {KeyCodes} = require("devtools/client/shared/keycodes");
const {OriginalSource} = require("devtools/client/styleeditor/original-source");
loader.lazyRequireGetter(this, "ResponsiveUIManager", "devtools/client/responsive.html/manager", true);
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
const LOAD_ERROR = "error-load";
const STYLE_EDITOR_TEMPLATE = "stylesheet";
const SELECTOR_HIGHLIGHTER_TYPE = "SelectorHighlighter";
const PREF_MEDIA_SIDEBAR = "devtools.styleeditor.showMediaSidebar";
const PREF_SIDEBAR_WIDTH = "devtools.styleeditor.mediaSidebarWidth";
const PREF_NAV_WIDTH = "devtools.styleeditor.navSidebarWidth";
const PREF_ORIG_SOURCES = "devtools.source-map.client-service.enabled";
@@ -482,17 +483,17 @@ StyleEditorUI.prototype = {
}
},
/**
* Open a particular stylesheet in a new tab.
*/
_openLinkNewTab: function() {
if (this._contextMenuStyleSheet) {
- this._window.openWebLinkIn(this._contextMenuStyleSheet.href, "tab");
+ openContentLink(this._contextMenuStyleSheet.href);
}
},
/**
* Remove a particular stylesheet editor from the UI
*
* @param {StyleSheetEditor} editor
* The editor to remove.
--- a/devtools/client/styleeditor/test/browser_styleeditor_opentab.js
+++ b/devtools/client/styleeditor/test/browser_styleeditor_opentab.js
@@ -16,21 +16,22 @@ add_task(async function() {
"The menu item is not disabled");
is(ui._openLinkNewTabItem.getAttribute("hidden"), "false",
"The menu item is not hidden");
const url = "https://example.com/browser/devtools/client/styleeditor/test/" +
"simple.css";
is(ui._contextMenuStyleSheet.href, url, "Correct URL for sheet");
- const originalOpenWebLinkIn = ui._window.openWebLinkIn;
+ const browserWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+ const originalOpenWebLinkIn = browserWindow.openWebLinkIn;
const tabOpenedDefer = new Promise(resolve => {
- ui._window.openWebLinkIn = newUrl => {
+ browserWindow.openWebLinkIn = newUrl => {
// Reset the actual openWebLinkIn function before proceeding.
- ui._window.openWebLinkIn = originalOpenWebLinkIn;
+ browserWindow.openWebLinkIn = originalOpenWebLinkIn;
is(newUrl, url, "The correct tab has been opened");
resolve();
};
});
ui._openLinkNewTabItem.click();
--- a/devtools/client/webconsole/hudservice.js
+++ b/devtools/client/webconsole/hudservice.js
@@ -11,16 +11,17 @@ loader.lazyRequireGetter(this, "TargetFa
loader.lazyRequireGetter(this, "Tools", "devtools/client/definitions", true);
loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
loader.lazyRequireGetter(this, "WebConsoleFrame", "devtools/client/webconsole/webconsole-frame", true);
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
loader.lazyRequireGetter(this, "viewSource", "devtools/client/shared/view-source");
loader.lazyRequireGetter(this, "l10n", "devtools/client/webconsole/webconsole-l10n");
+loader.lazyRequireGetter(this, "openDocLink", "devtools/client/shared/link", true);
const BC_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
// The preference prefix for all of the Browser Console filters.
const BC_FILTER_PREFS_PREFIX = "devtools.browserconsole.filter.";
var gHudId = 0;
function HUD_SERVICE() {
@@ -359,22 +360,17 @@ WebConsole.prototype = {
/**
* Open a link in a new tab.
*
* @param string link
* The URL you want to open in a new tab.
*/
openLink(link, e) {
- const isOSX = Services.appinfo.OS == "Darwin";
- let where = "tab";
- if (e && (e.button === 1 || (e.button === 0 && (isOSX ? e.metaKey : e.ctrlKey)))) {
- where = "tabshifted";
- }
- this.chromeUtilsWindow.openWebLinkIn(link, where);
+ openDocLink(link);
},
/**
* Open a link in Firefox's view source.
*
* @param string sourceURL
* The URL of the file.
* @param integer sourceLine
--- a/devtools/client/webconsole/test/mochitest/browser_webconsole_allow_mixedcontent_securityerrors.js
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_allow_mixedcontent_securityerrors.js
@@ -47,28 +47,15 @@ add_task(async function() {
const checkLink = ({ link, where, expectedLink, expectedTab }) => {
is(link, expectedLink, `Clicking the provided link opens ${link}`);
is(where, expectedTab, `Clicking the provided link opens in expected tab`);
};
info("Clicking on the Learn More link");
const learnMoreLink = mixedActiveContentMessage.querySelector(".learn-more-link");
- let linkSimulation = await simulateLinkClick(learnMoreLink);
+ const linkSimulation = await simulateLinkClick(learnMoreLink);
checkLink({
...linkSimulation,
expectedLink: LEARN_MORE_URI,
expectedTab: "tab"
});
-
- const isOSX = Services.appinfo.OS == "Darwin";
- const ctrlOrCmdKeyMouseEvent = new MouseEvent("click", {
- bubbles: true,
- [isOSX ? "metaKey" : "ctrlKey"]: true,
- view: window
- });
- linkSimulation = await simulateLinkClick(learnMoreLink, ctrlOrCmdKeyMouseEvent);
- checkLink({
- ...linkSimulation,
- expectedLink: LEARN_MORE_URI,
- expectedTab: "tabshifted"
- });
});
--- a/devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_status_code.js
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_network_messages_status_code.js
@@ -35,26 +35,22 @@ add_task(async function task() {
const xhrUrl = TEST_PATH + "test-data.json";
const messageNode = await waitFor(() => findMessage(hud, xhrUrl));
const statusCodeNode = messageNode.querySelector(".status-code");
info("Network message found.");
ok(statusCodeNode.title, l10n.getStr("webConsoleMoreInfoLabel"));
const {
- middleMouseEvent,
- ctrlOrCmdKeyMouseEvent,
rightClickMouseEvent,
rightClickCtrlOrCmdKeyMouseEvent,
} = getMouseEvents();
const testCases = [
- { clickEvent: middleMouseEvent, link: LEARN_MORE_URI, where: "tabshifted" },
{ clickEvent: null, link: LEARN_MORE_URI, where: "tab" },
- { clickEvent: ctrlOrCmdKeyMouseEvent, link: LEARN_MORE_URI, where: "tabshifted" },
{ clickEvent: rightClickMouseEvent, link: null, where: null },
{ clickEvent: rightClickCtrlOrCmdKeyMouseEvent, link: null, where: null }
];
for (const testCase of testCases) {
const { clickEvent } = testCase;
const onConsoleMenuOpened = [
rightClickMouseEvent,
@@ -70,37 +66,25 @@ add_task(async function task() {
await onConsoleMenuOpened;
}
}
});
function getMouseEvents() {
const isOSX = Services.appinfo.OS == "Darwin";
- const middleMouseEvent = new MouseEvent("click", {
- bubbles: true,
- button: 1,
- view: window
- });
- const ctrlOrCmdKeyMouseEvent = new MouseEvent("click", {
- bubbles: true,
- [isOSX ? "metaKey" : "ctrlKey"]: true,
- view: window
- });
const rightClickMouseEvent = new MouseEvent("contextmenu", {
bubbles: true,
button: 2,
view: window
});
const rightClickCtrlOrCmdKeyMouseEvent = new MouseEvent("contextmenu", {
bubbles: true,
button: 2,
[isOSX ? "metaKey" : "ctrlKey"]: true,
view: window
});
return {
- middleMouseEvent,
- ctrlOrCmdKeyMouseEvent,
rightClickMouseEvent,
rightClickCtrlOrCmdKeyMouseEvent,
};
}
--- a/devtools/client/webconsole/test/mochitest/head.js
+++ b/devtools/client/webconsole/test/mochitest/head.js
@@ -490,42 +490,45 @@ async function closeConsole(tab = gBrows
* A Promise that is resolved when the link click simulation occured or
* when the click is not dispatched.
* The promise resolves with an object that holds the following properties
* - link: url of the link or null(if event not fired)
* - where: "tab" if tab is active or "tabshifted" if tab is inactive
* or null(if event not fired)
*/
function simulateLinkClick(element, clickEventProps) {
+ const browserWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+
// Override LinkIn methods to prevent navigating.
- const oldOpenTrustedLinkIn = window.openTrustedLinkIn;
- const oldOpenWebLinkIn = window.openWebLinkIn;
+ const oldOpenTrustedLinkIn = browserWindow.openTrustedLinkIn;
+ const oldOpenWebLinkIn = browserWindow.openWebLinkIn;
const onOpenLink = new Promise((resolve) => {
- window.openWebLinkIn = window.openTrustedLinkIn = function(link, where) {
- window.openTrustedLinkIn = oldOpenTrustedLinkIn;
- window.openWebLinkIn = oldOpenWebLinkIn;
+ const openLinkIn = function(link, where) {
+ browserWindow.openTrustedLinkIn = oldOpenTrustedLinkIn;
+ browserWindow.openWebLinkIn = oldOpenWebLinkIn;
resolve({link: link, where});
};
+ browserWindow.openWebLinkIn = browserWindow.openTrustedLinkIn = openLinkIn;
if (clickEventProps) {
// Click on the link using the event properties.
element.dispatchEvent(clickEventProps);
} else {
// Click on the link.
element.click();
}
});
// Declare a timeout Promise that we can use to make sure openTrustedLinkIn or
// openWebLinkIn was not called.
let timeoutId;
const onTimeout = new Promise(function(resolve) {
timeoutId = setTimeout(() => {
- window.openTrustedLinkIn = oldOpenTrustedLinkIn;
- window.openWebLinkIn = oldOpenWebLinkIn;
+ browserWindow.openTrustedLinkIn = oldOpenTrustedLinkIn;
+ browserWindow.openWebLinkIn = oldOpenWebLinkIn;
timeoutId = null;
resolve({link: null, where: null});
}, 1000);
});
onOpenLink.then(() => {
if (timeoutId) {
clearTimeout(timeoutId);
--- a/devtools/client/webconsole/utils/context-menu.js
+++ b/devtools/client/webconsole/utils/context-menu.js
@@ -1,27 +1,26 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-const Services = require("Services");
-const {gDevTools} = require("devtools/client/framework/devtools");
-
const Menu = require("devtools/client/framework/menu");
const MenuItem = require("devtools/client/framework/menu-item");
const { MESSAGE_SOURCE } = require("devtools/client/webconsole/constants");
const clipboardHelper = require("devtools/shared/platform/clipboard");
const { l10n } = require("devtools/client/webconsole/utils/messages");
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
+
/**
* Create a Menu instance for the webconsole.
*
* @param {Object} hud
* The webConsoleFrame.
* @param {Element} parentNode
* The container of the new console frontend output wrapper.
* @param {Object} options
@@ -84,20 +83,17 @@ function createContextMenu(hud, parentNo
id: "console-menu-open-url",
label: l10n.getStr("webconsole.menu.openURL.label"),
accesskey: l10n.getStr("webconsole.menu.openURL.accesskey"),
visible: source === MESSAGE_SOURCE.NETWORK,
click: () => {
if (!request) {
return;
}
- const mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
- mainWindow.openWebLinkIn(request.url, "tab", {
- triggeringPrincipal: mainWindow.document.nodePrincipal,
- });
+ openContentLink(request.url);
},
}));
// Store as global variable.
menu.append(new MenuItem({
id: "console-menu-store",
label: l10n.getStr("webconsole.menu.storeAsGlobalVar.label"),
accesskey: l10n.getStr("webconsole.menu.storeAsGlobalVar.accesskey"),
--- a/devtools/client/webide/content/webide.js
+++ b/devtools/client/webide/content/webide.js
@@ -15,16 +15,17 @@ const {AppProjects} = require("devtools/
const {Connection} = require("devtools/shared/client/connection-manager");
const {AppManager} = require("devtools/client/webide/modules/app-manager");
const EventEmitter = require("devtools/shared/event-emitter");
const promise = require("promise");
const {GetAvailableAddons} = require("devtools/client/webide/modules/addons");
const {getJSON} = require("devtools/client/shared/getjson");
const Telemetry = require("devtools/client/shared/telemetry");
const {RuntimeScanners} = require("devtools/client/webide/modules/runtimes");
+const {openContentLink} = require("devtools/client/shared/link");
const Strings =
Services.strings.createBundle("chrome://devtools/locale/webide.properties");
const TELEMETRY_WEBIDE_IMPORT_PROJECT_COUNT = "DEVTOOLS_WEBIDE_IMPORT_PROJECT_COUNT";
const HELP_URL = "https://developer.mozilla.org/docs/Tools/WebIDE/Troubleshooting";
@@ -172,24 +173,17 @@ var UI = {
case "runtime-targets":
this.autoSelectProject();
break;
}
this._updatePromise = promise.resolve();
},
openInBrowser: function(url) {
- // Open a URL in a Firefox window
- const mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
- if (mainWindow) {
- mainWindow.openWebLinkIn(url, "tab");
- mainWindow.focus();
- } else {
- window.open(url);
- }
+ openContentLink(url);
},
updateTitle: function() {
const project = AppManager.selectedProject;
if (project) {
window.document.title = Strings.formatStringFromName("title_app", [project.name], 1);
} else {
window.document.title = Strings.GetStringFromName("title_noApp");
--- a/devtools/shared/gcli/commands/screenshot.js
+++ b/devtools/shared/gcli/commands/screenshot.js
@@ -8,16 +8,18 @@ const { Cc, Ci, Cr, Cu } = require("chro
const ChromeUtils = require("ChromeUtils");
const l10n = require("gcli/l10n");
const Services = require("Services");
const { NetUtil } = require("resource://gre/modules/NetUtil.jsm");
const { getRect } = require("devtools/shared/layout/utils");
const defer = require("devtools/shared/defer");
const { Task } = require("devtools/shared/task");
+loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
+
loader.lazyImporter(this, "Downloads", "resource://gre/modules/Downloads.jsm");
loader.lazyImporter(this, "OS", "resource://gre/modules/osfile.jsm");
loader.lazyImporter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm");
loader.lazyImporter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
// String used as an indication to generate default file name in the following
// format: "Screen Shot yyyy-mm-dd at HH.MM.SS.png"
@@ -155,20 +157,17 @@ exports.items = [
root.appendChild(image);
}
// Click handler
if (imageSummary.href || imageSummary.filename) {
root.style.cursor = "pointer";
root.addEventListener("click", () => {
if (imageSummary.href) {
- const mainWindow = context.environment.chromeWindow;
- mainWindow.openWebLinkIn(imageSummary.href, "tab", {
- triggeringPrincipal: document.nodePrincipal,
- });
+ openContentLink(imageSummary.href);
} else if (imageSummary.filename) {
const file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(imageSummary.filename);
file.reveal();
}
});
}