diff --git a/devtools/client/netmonitor/src/assets/styles/netmonitor.css b/devtools/client/netmonitor/src/assets/styles/netmonitor.css index b500028782a9..4de65e36dea8 100644 --- a/devtools/client/netmonitor/src/assets/styles/netmonitor.css +++ b/devtools/client/netmonitor/src/assets/styles/netmonitor.css @@ -103,6 +103,17 @@ body, text-overflow: ellipsis; } +.learn-more-link { + color: var(--theme-highlight-blue); + cursor: pointer; + margin: 0 5px; + white-space: nowrap; +} + +.learn-more-link:hover { + text-decoration: underline; +} + /* Status bar */ .status-bar-label { @@ -152,6 +163,8 @@ body, .notice-perf-message { margin-top: 2px; + display: flex; + align-items: center; } .requests-list-perf-notice-button { @@ -868,18 +881,6 @@ body, color: var(--theme-selection-color); } -.learn-more-link { - color: var(--theme-highlight-blue); - cursor: pointer; - margin: 0 5px; - white-space: nowrap; - flex-grow: 1; -} - -.learn-more-link:hover { - text-decoration: underline; -} - /* Headers tabpanel */ .headers-overview { @@ -930,6 +931,10 @@ body, width: auto!important; } +.headers-summary .learn-more-link { + flex-grow: 1; +} + /* Response tabpanel */ .response-error-header { @@ -1163,6 +1168,14 @@ body, height: 100%; } +.statistics-panel .learn-more-link { + font-weight: 400; +} + +.statistics-panel .table-chart-title { + display: flex; +} + .pie-table-chart-container { display: flex; justify-content: center; diff --git a/devtools/client/netmonitor/src/components/request-list-empty-notice.js b/devtools/client/netmonitor/src/components/request-list-empty-notice.js index f2b1db480275..baa19d545f95 100644 --- a/devtools/client/netmonitor/src/components/request-list-empty-notice.js +++ b/devtools/client/netmonitor/src/components/request-list-empty-notice.js @@ -6,6 +6,7 @@ const { createClass, + createFactory, DOM, PropTypes, } = require("devtools/client/shared/vendor/react"); @@ -14,6 +15,10 @@ const Actions = require("../actions/index"); const { ACTIVITY_TYPE } = require("../constants"); const { NetMonitorController } = require("../netmonitor-controller"); const { L10N } = require("../utils/l10n"); +const { getPerformanceAnalysisURL } = require("../utils/mdn-utils"); + +// Components +const MDNLink = createFactory(require("./mdn-link")); const { button, div, span } = DOM; @@ -54,7 +59,8 @@ const RequestListEmptyNotice = createClass({ "data-standalone": true, onClick: this.props.onPerfClick, }), - span(null, L10N.getStr("netmonitor.perfNotice2")) + span(null, L10N.getStr("netmonitor.perfNotice2")), + MDNLink({ url: getPerformanceAnalysisURL() }) ) ); } diff --git a/devtools/client/netmonitor/src/components/statistics-panel.js b/devtools/client/netmonitor/src/components/statistics-panel.js index 6afb26c725a1..88f5f51f9f16 100644 --- a/devtools/client/netmonitor/src/components/statistics-panel.js +++ b/devtools/client/netmonitor/src/components/statistics-panel.js @@ -4,8 +4,10 @@ "use strict"; +const ReactDOM = require("devtools/client/shared/vendor/react-dom"); const { createClass, + createFactory, DOM, PropTypes, } = require("devtools/client/shared/vendor/react"); @@ -19,6 +21,10 @@ const { getTimeWithDecimals } = require("../utils/format-utils"); const { L10N } = require("../utils/l10n"); +const { getPerformanceAnalysisURL } = require("../utils/mdn-utils"); + +// Components +const MDNLink = createFactory(require("./mdn-link")); const { button, div } = DOM; const MediaQueryList = window.matchMedia("(min-width: 700px)"); @@ -48,6 +54,10 @@ const StatisticsPanel = createClass({ }; }, + componentWillMount() { + this.mdnLinkContainerNodes = new Map(); + }, + componentDidUpdate(prevProps) { MediaQueryList.addListener(this.onLayoutChange); @@ -68,10 +78,35 @@ const StatisticsPanel = createClass({ title: CHARTS_CACHE_DISABLED, data: ready ? this.sanitizeChartDataSource(requests, true) : null, }); + + this.createMDNLink("primedCacheChart", getPerformanceAnalysisURL()); + this.createMDNLink("emptyCacheChart", getPerformanceAnalysisURL()); }, componentWillUnmount() { MediaQueryList.removeListener(this.onLayoutChange); + this.unmountMDNLinkContainers(); + }, + + createMDNLink(chartId, url) { + if (this.mdnLinkContainerNodes.has(chartId)) { + ReactDOM.unmountComponentAtNode(this.mdnLinkContainerNodes.get(chartId)); + } + + // MDNLink is a React component but Chart isn't. To get the link + // into the chart we mount a new ReactDOM at the appropriate + // location after the chart has been created. + let title = this.refs[chartId].querySelector(".table-chart-title"); + let containerNode = document.createElement("span"); + title.appendChild(containerNode); + ReactDOM.render(MDNLink({ url }), containerNode); + this.mdnLinkContainerNodes.set(chartId, containerNode); + }, + + unmountMDNLinkContainers() { + for (let [, node] of this.mdnLinkContainerNodes) { + ReactDOM.unmountComponentAtNode(node); + } }, createChart({ id, title, data }) { diff --git a/devtools/client/netmonitor/src/utils/mdn-utils.js b/devtools/client/netmonitor/src/utils/mdn-utils.js index b1538e576f21..9297f875f23f 100644 --- a/devtools/client/netmonitor/src/utils/mdn-utils.js +++ b/devtools/client/netmonitor/src/utils/mdn-utils.js @@ -140,12 +140,10 @@ const SUPPORTED_HTTP_CODES = [ "511" ]; +const MDN_URL = "https://developer.mozilla.org/docs/"; const GA_PARAMS = "?utm_source=mozilla&utm_medium=devtools-netmonitor&utm_campaign=default"; -const NETWORK_MONITOR_TIMINGS_MDN_URL = - "https://developer.mozilla.org/docs/Tools/Network_Monitor#Timings"; - /** * Get the MDN URL for the specified header. * @@ -158,7 +156,7 @@ function getHeadersURL(header) { let idx = SUPPORTED_HEADERS.findIndex(item => item.toLowerCase() === lowerCaseHeader); return idx > -1 ? - `https://developer.mozilla.org/docs/Web/HTTP/Headers/${SUPPORTED_HEADERS[idx] + GA_PARAMS}` : null; + `${MDN_URL}Web/HTTP/Headers/${SUPPORTED_HEADERS[idx] + GA_PARAMS}` : null; } /** @@ -170,7 +168,8 @@ function getHeadersURL(header) { */ function getHTTPStatusCodeURL(statusCode) { let idx = SUPPORTED_HTTP_CODES.indexOf(statusCode); - return idx > -1 ? `https://developer.mozilla.org/docs/Web/HTTP/Status/${SUPPORTED_HTTP_CODES[idx] + GA_PARAMS}` : null; + return idx > -1 ? + `${MDN_URL}Web/HTTP/Status/${SUPPORTED_HTTP_CODES[idx] + GA_PARAMS}` : null; } /** @@ -179,11 +178,21 @@ function getHTTPStatusCodeURL(statusCode) { * @return {string} the MDN URL of the Timings tag for Network Monitor. */ function getNetMonitorTimingsURL() { - return NETWORK_MONITOR_TIMINGS_MDN_URL; + return `${MDN_URL}Tools/Network_Monitor${GA_PARAMS}#Timings`; +} + +/** + * Get the MDN URL for Performance Analysis + * + * @return {string} The MDN URL for the documentation of Performance Analysis. + */ +function getPerformanceAnalysisURL() { + return `${MDN_URL}Tools/Network_Monitor${GA_PARAMS}#Performance_analysis`; } module.exports = { getHeadersURL, getHTTPStatusCodeURL, getNetMonitorTimingsURL, + getPerformanceAnalysisURL, };