Bug 1394681 - Properly open links. r=rickychien

MozReview-Commit-ID: HdtFyQnIOUj
This commit is contained in:
Jan Odvarko 2017-09-06 12:27:17 +02:00
Родитель 11d2b6b69e
Коммит 54796f8e3c
14 изменённых файлов: 84 добавлений и 22 удалений

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

@ -38,25 +38,36 @@
window.Netmonitor = { window.Netmonitor = {
bootstrap({ toolbox }) { bootstrap({ toolbox }) {
this.mount = document.querySelector("#mount"); this.mount = document.querySelector("#mount");
const connection = { const connection = {
tabConnection: { tabConnection: {
tabTarget: toolbox.target, tabTarget: toolbox.target,
}, },
toolbox, toolbox,
}; };
const openLink = (link) => {
let parentDoc = toolbox.doc;
let iframe = parentDoc.getElementById("toolbox-panel-iframe-netmonitor");
let top = iframe.ownerDocument.defaultView.top;
top.openUILinkIn(link, "tab");
};
const App = createFactory(require("./src/components/app")); const App = createFactory(require("./src/components/app"));
const sourceMapService = toolbox.sourceMapURLService; const sourceMapService = toolbox.sourceMapURLService;
render(Provider({ store }, App({ sourceMapService })), this.mount); const app = App({ sourceMapService, openLink });
render(Provider({ store }, app), this.mount);
return onFirefoxConnect(connection, actions, store.getState); return onFirefoxConnect(connection, actions, store.getState);
}, },
destroy() { destroy() {
unmountComponentAtNode(this.mount); unmountComponentAtNode(this.mount);
return onDisconnect(); return onDisconnect();
} },
}; };
// Implement support for chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs // Implement support for:
// chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs
// where 1234 is the tab id, you can retrieve from about:debugging#tabs links. // where 1234 is the tab id, you can retrieve from about:debugging#tabs links.
// Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs. // Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs.
@ -64,7 +75,8 @@
let href = window.location.href.replace(/chrome:/, "http://"); let href = window.location.href.replace(/chrome:/, "http://");
let url = new window.URL(href); let url = new window.URL(href);
// If query parameters are given in a chrome tab, the inspector is running in standalone. // If query parameters are given in a chrome tab, the inspector
// is running in standalone.
if (window.location.protocol === "chrome:" && url.search.length > 1) { if (window.location.protocol === "chrome:" && url.search.length > 1) {
const { targetFromURL } = require("devtools/client/framework/target-from-url"); const { targetFromURL } = require("devtools/client/framework/target-from-url");
@ -83,7 +95,8 @@
}; };
window.Netmonitor.bootstrap({ toolbox }); window.Netmonitor.bootstrap({ toolbox });
})().catch(e => { })().catch(e => {
window.alert("Unable to start the network monitor:" + e.message + "\n" + e.stack); window.alert("Unable to start the network monitor:" +
e.message + "\n" + e.stack);
}); });
} }
</script> </script>

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

@ -21,10 +21,14 @@ const { div } = DOM;
* App component * App component
* The top level component for representing main panel * The top level component for representing main panel
*/ */
function App({ statisticsOpen, sourceMapService }) { function App({
openLink,
sourceMapService,
statisticsOpen,
}) {
return ( return (
div({ className: "network-monitor" }, div({ className: "network-monitor" },
!statisticsOpen ? MonitorPanel({sourceMapService}) : StatisticsPanel() !statisticsOpen ? MonitorPanel({ openLink, sourceMapService }) : StatisticsPanel()
) )
); );
} }
@ -32,9 +36,10 @@ function App({ statisticsOpen, sourceMapService }) {
App.displayName = "App"; App.displayName = "App";
App.propTypes = { App.propTypes = {
statisticsOpen: PropTypes.bool.isRequired, openLink: PropTypes.func,
// Service to enable the source map feature. // Service to enable the source map feature.
sourceMapService: PropTypes.object, sourceMapService: PropTypes.object,
statisticsOpen: PropTypes.bool.isRequired,
}; };
module.exports = connect( module.exports = connect(

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

@ -31,6 +31,7 @@ const SECTION_NAMES = [
*/ */
function CookiesPanel({ function CookiesPanel({
request, request,
openLink,
}) { }) {
let { let {
requestCookies = { cookies: [] }, requestCookies = { cookies: [] },
@ -62,6 +63,7 @@ function CookiesPanel({
object, object,
filterPlaceHolder: COOKIES_FILTER_TEXT, filterPlaceHolder: COOKIES_FILTER_TEXT,
sectionNames: SECTION_NAMES, sectionNames: SECTION_NAMES,
openLink,
}) })
) )
); );
@ -71,6 +73,7 @@ CookiesPanel.displayName = "CookiesPanel";
CookiesPanel.propTypes = { CookiesPanel.propTypes = {
request: PropTypes.object.isRequired, request: PropTypes.object.isRequired,
openLink: PropTypes.func,
}; };
/** /**

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

@ -54,7 +54,8 @@ const HeadersPanel = createClass({
propTypes: { propTypes: {
cloneSelectedRequest: PropTypes.func.isRequired, cloneSelectedRequest: PropTypes.func.isRequired,
request: PropTypes.object.isRequired, request: PropTypes.object.isRequired,
renderValue: PropTypes.func renderValue: PropTypes.func,
openLink: PropTypes.func,
}, },
getInitialState() { getInitialState() {
@ -125,6 +126,7 @@ const HeadersPanel = createClass({
render() { render() {
const { const {
openLink,
cloneSelectedRequest, cloneSelectedRequest,
request: { request: {
fromCache, fromCache,
@ -256,6 +258,7 @@ const HeadersPanel = createClass({
filterPlaceHolder: HEADERS_FILTER_TEXT, filterPlaceHolder: HEADERS_FILTER_TEXT,
sectionNames: Object.keys(object), sectionNames: Object.keys(object),
renderValue: this.renderValue, renderValue: this.renderValue,
openLink,
}), }),
) )
); );

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

@ -40,6 +40,7 @@ const MonitorPanel = createClass({
request: PropTypes.object, request: PropTypes.object,
// Service to enable the source map feature. // Service to enable the source map feature.
sourceMapService: PropTypes.object, sourceMapService: PropTypes.object,
openLink: PropTypes.func,
updateRequest: PropTypes.func.isRequired, updateRequest: PropTypes.func.isRequired,
}, },
@ -104,7 +105,13 @@ const MonitorPanel = createClass({
}, },
render() { render() {
let { isEmpty, networkDetailsOpen, sourceMapService } = this.props; let {
isEmpty,
networkDetailsOpen,
sourceMapService,
openLink
} = this.props;
let initialWidth = Services.prefs.getIntPref( let initialWidth = Services.prefs.getIntPref(
"devtools.netmonitor.panes-network-details-width"); "devtools.netmonitor.panes-network-details-width");
let initialHeight = Services.prefs.getIntPref( let initialHeight = Services.prefs.getIntPref(
@ -123,6 +130,7 @@ const MonitorPanel = createClass({
endPanel: networkDetailsOpen && NetworkDetailsPanel({ endPanel: networkDetailsOpen && NetworkDetailsPanel({
ref: "endPanel", ref: "endPanel",
sourceMapService, sourceMapService,
openLink,
}), }),
endPanelCollapsed: !networkDetailsOpen, endPanelCollapsed: !networkDetailsOpen,
endPanelControl: true, endPanelControl: true,

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

@ -28,6 +28,7 @@ function NetworkDetailsPanel({
request, request,
selectTab, selectTab,
sourceMapService, sourceMapService,
openLink,
}) { }) {
if (!request) { if (!request) {
return null; return null;
@ -38,10 +39,11 @@ function NetworkDetailsPanel({
!request.isCustom ? !request.isCustom ?
TabboxPanel({ TabboxPanel({
activeTabId, activeTabId,
cloneSelectedRequest,
request, request,
selectTab, selectTab,
sourceMapService, sourceMapService,
cloneSelectedRequest, openLink,
}) : }) :
CustomRequestPanel({ CustomRequestPanel({
request, request,
@ -60,6 +62,7 @@ NetworkDetailsPanel.propTypes = {
selectTab: PropTypes.func.isRequired, selectTab: PropTypes.func.isRequired,
// Service to enable the source map feature. // Service to enable the source map feature.
sourceMapService: PropTypes.object, sourceMapService: PropTypes.object,
openLink: PropTypes.func,
}; };
module.exports = connect( module.exports = connect(

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

@ -34,7 +34,10 @@ const SECTION_NAMES = [
* Params panel component * Params panel component
* Displays the GET parameters and POST data of a request * Displays the GET parameters and POST data of a request
*/ */
function ParamsPanel({ request }) { function ParamsPanel({
openLink,
request,
}) {
let { let {
formDataSections, formDataSections,
mimeType, mimeType,
@ -92,6 +95,7 @@ function ParamsPanel({ request }) {
object, object,
filterPlaceHolder: PARAMS_FILTER_TEXT, filterPlaceHolder: PARAMS_FILTER_TEXT,
sectionNames: SECTION_NAMES, sectionNames: SECTION_NAMES,
openLink,
}) })
) )
); );
@ -101,6 +105,7 @@ ParamsPanel.displayName = "ParamsPanel";
ParamsPanel.propTypes = { ParamsPanel.propTypes = {
request: PropTypes.object.isRequired, request: PropTypes.object.isRequired,
openLink: PropTypes.func,
}; };
/** /**

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

@ -49,6 +49,7 @@ const PropertiesView = createClass({
expandableStrings: PropTypes.bool, expandableStrings: PropTypes.bool,
filterPlaceHolder: PropTypes.string, filterPlaceHolder: PropTypes.string,
sectionNames: PropTypes.array, sectionNames: PropTypes.array,
openLink: PropTypes.func,
}, },
getDefaultProps() { getDefaultProps() {
@ -148,6 +149,7 @@ const PropertiesView = createClass({
renderRow, renderRow,
renderValue, renderValue,
sectionNames, sectionNames,
openLink,
} = this.props; } = this.props;
return ( return (
@ -181,6 +183,7 @@ const PropertiesView = createClass({
onFilter: (props) => this.onFilter(props, sectionNames), onFilter: (props) => this.onFilter(props, sectionNames),
renderRow: renderRow || this.renderRowWithEditor, renderRow: renderRow || this.renderRowWithEditor,
renderValue: renderValue || this.renderValueWithRep, renderValue: renderValue || this.renderValueWithRep,
openLink,
}), }),
), ),
) )

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

@ -33,6 +33,7 @@ const ResponsePanel = createClass({
propTypes: { propTypes: {
request: PropTypes.object.isRequired, request: PropTypes.object.isRequired,
openLink: PropTypes.func,
}, },
getInitialState() { getInitialState() {
@ -110,7 +111,8 @@ const ResponsePanel = createClass({
}, },
render() { render() {
let { responseContent, url } = this.props.request; let { openLink, request } = this.props;
let { responseContent, url } = request;
if (!responseContent || typeof responseContent.content.text !== "string") { if (!responseContent || typeof responseContent.content.text !== "string") {
return null; return null;
@ -175,6 +177,7 @@ const ResponsePanel = createClass({
object, object,
filterPlaceHolder: JSON_FILTER_TEXT, filterPlaceHolder: JSON_FILTER_TEXT,
sectionNames: Object.keys(object), sectionNames: Object.keys(object),
openLink,
}), }),
) )
); );

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

@ -24,7 +24,10 @@ const { div, input, span } = DOM;
* This contains details about the secure connection used including the protocol, * This contains details about the secure connection used including the protocol,
* the cipher suite, and certificate details * the cipher suite, and certificate details
*/ */
function SecurityPanel({ request }) { function SecurityPanel({
openLink,
request,
}) {
const { securityInfo, url } = request; const { securityInfo, url } = request;
if (!securityInfo || !url) { if (!securityInfo || !url) {
@ -101,6 +104,7 @@ function SecurityPanel({ request }) {
renderValue: (props) => renderValue(props, securityInfo.weaknessReasons), renderValue: (props) => renderValue(props, securityInfo.weaknessReasons),
enableFilter: false, enableFilter: false,
expandedNodes: TreeViewClass.getExpandedNodes(object), expandedNodes: TreeViewClass.getExpandedNodes(object),
openLink,
}) })
); );
} }
@ -109,6 +113,7 @@ SecurityPanel.displayName = "SecurityPanel";
SecurityPanel.propTypes = { SecurityPanel.propTypes = {
request: PropTypes.object.isRequired, request: PropTypes.object.isRequired,
openLink: PropTypes.func,
}; };
function renderValue(props, weaknessReasons = []) { function renderValue(props, weaknessReasons = []) {

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

@ -16,7 +16,11 @@ const { div } = DOM;
// Components // Components
const StackTrace = createFactory(require("devtools/client/shared/components/stack-trace")); const StackTrace = createFactory(require("devtools/client/shared/components/stack-trace"));
function StackTracePanel({ request, sourceMapService }) { function StackTracePanel({
openLink,
request,
sourceMapService,
}) {
let { stacktrace } = request.cause; let { stacktrace } = request.cause;
return ( return (
@ -25,6 +29,7 @@ function StackTracePanel({ request, sourceMapService }) {
stacktrace, stacktrace,
onViewSourceInDebugger: ({ url, line }) => viewSourceInDebugger(url, line), onViewSourceInDebugger: ({ url, line }) => viewSourceInDebugger(url, line),
sourceMapService, sourceMapService,
openLink,
}), }),
) )
); );
@ -36,6 +41,7 @@ StackTracePanel.propTypes = {
request: PropTypes.object.isRequired, request: PropTypes.object.isRequired,
// Service to enable the source map feature. // Service to enable the source map feature.
sourceMapService: PropTypes.object, sourceMapService: PropTypes.object,
openLink: PropTypes.func,
}; };
module.exports = StackTracePanel; module.exports = StackTracePanel;

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

@ -41,6 +41,7 @@ function TabboxPanel({
request, request,
selectTab, selectTab,
sourceMapService, sourceMapService,
openLink,
}) { }) {
if (!request) { if (!request) {
return null; return null;
@ -58,25 +59,25 @@ function TabboxPanel({
id: PANELS.HEADERS, id: PANELS.HEADERS,
title: HEADERS_TITLE, title: HEADERS_TITLE,
}, },
HeadersPanel({ request, cloneSelectedRequest }), HeadersPanel({ request, cloneSelectedRequest, openLink }),
), ),
TabPanel({ TabPanel({
id: PANELS.COOKIES, id: PANELS.COOKIES,
title: COOKIES_TITLE, title: COOKIES_TITLE,
}, },
CookiesPanel({ request }), CookiesPanel({ request, openLink }),
), ),
TabPanel({ TabPanel({
id: PANELS.PARAMS, id: PANELS.PARAMS,
title: PARAMS_TITLE, title: PARAMS_TITLE,
}, },
ParamsPanel({ request }), ParamsPanel({ request, openLink }),
), ),
TabPanel({ TabPanel({
id: PANELS.RESPONSE, id: PANELS.RESPONSE,
title: RESPONSE_TITLE, title: RESPONSE_TITLE,
}, },
ResponsePanel({ request }), ResponsePanel({ request, openLink }),
), ),
TabPanel({ TabPanel({
id: PANELS.TIMINGS, id: PANELS.TIMINGS,
@ -89,14 +90,14 @@ function TabboxPanel({
id: PANELS.STACK_TRACE, id: PANELS.STACK_TRACE,
title: STACK_TRACE_TITLE, title: STACK_TRACE_TITLE,
}, },
StackTracePanel({ request, sourceMapService }), StackTracePanel({ request, sourceMapService, openLink }),
), ),
request.securityState && request.securityState !== "insecure" && request.securityState && request.securityState !== "insecure" &&
TabPanel({ TabPanel({
id: PANELS.SECURITY, id: PANELS.SECURITY,
title: SECURITY_TITLE, title: SECURITY_TITLE,
}, },
SecurityPanel({ request }), SecurityPanel({ request, openLink }),
), ),
) )
); );
@ -111,6 +112,7 @@ TabboxPanel.propTypes = {
selectTab: PropTypes.func.isRequired, selectTab: PropTypes.func.isRequired,
// Service to enable the source map feature. // Service to enable the source map feature.
sourceMapService: PropTypes.object, sourceMapService: PropTypes.object,
openLink: PropTypes.func,
}; };
module.exports = connect()(TabboxPanel); module.exports = connect()(TabboxPanel);

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

@ -107,6 +107,7 @@ function NetworkEventMessage({
activeTabId: networkMessageActiveTabId, activeTabId: networkMessageActiveTabId,
request: networkMessageUpdate, request: networkMessageUpdate,
sourceMapService: serviceContainer.sourceMapService, sourceMapService: serviceContainer.sourceMapService,
openLink: serviceContainer.openLink,
selectTab: (tabId) => { selectTab: (tabId) => {
dispatch(actions.selectNetworkMessageTab(tabId)); dispatch(actions.selectNetworkMessageTab(tabId));
}, },

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

@ -80,7 +80,9 @@ NewConsoleOutputWrapper.prototype = {
}])); }]));
}, },
hudProxyClient: this.jsterm.hud.proxy.client, hudProxyClient: this.jsterm.hud.proxy.client,
openLink: url => this.jsterm.hud.owner.openLink(url), openLink: url => {
this.jsterm.hud.owner.openLink(url);
},
createElement: nodename => { createElement: nodename => {
return this.document.createElementNS("http://www.w3.org/1999/xhtml", nodename); return this.document.createElementNS("http://www.w3.org/1999/xhtml", nodename);
}, },