Bug 1320233 - Add Learn More link to headers in Network panel. r=Honza

This commit is contained in:
Eduardo Boucas 2017-02-03 17:19:20 +00:00
parent e22752b858
commit 8953ccbc24
7 changed files with 244 additions and 1 deletions

View File

@ -749,3 +749,7 @@ netmonitor.custom.cancel=Cancel
# LOCALIZATION NOTE (netmonitor.backButton): This is the label displayed
# on the button which exists the performance statistics view
netmonitor.backButton=Back
# LOCALIZATION NOTE (netmonitor.headers.learnMore): This is the label displayed
# next to a header list item, with a link to external documentation
netmonitor.headers.learnMore=Learn More

View File

@ -0,0 +1,119 @@
/* 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/. */
/**
* A mapping of header names to external documentation. Any header included
* here will show a "Learn More" link alongside it.
*/
"use strict";
var URL_DOMAIN = "https://developer.mozilla.org";
const URL_PATH = "/en-US/docs/Web/HTTP/Headers/";
const URL_PARAMS =
"?utm_source=mozilla&utm_medium=devtools-netmonitor&utm_campaign=default";
var SUPPORTED_HEADERS = [
"Accept",
"Accept-Charset",
"Accept-Encoding",
"Accept-Language",
"Accept-Ranges",
"Access-Control-Allow-Credentials",
"Access-Control-Allow-Headers",
"Access-Control-Allow-Methods",
"Access-Control-Allow-Origin",
"Access-Control-Expose-Headers",
"Access-Control-Max-Age",
"Access-Control-Request-Headers",
"Access-Control-Request-Method",
"Age",
"Cache-Control",
"Connection",
"Content-Disposition",
"Content-Encoding",
"Content-Language",
"Content-Length",
"Content-Location",
"Content-Security-Policy",
"Content-Security-Policy-Report-Only",
"Content-Type",
"Cookie",
"Cookie2",
"DNT",
"Date",
"ETag",
"Expires",
"From",
"Host",
"If-Match",
"If-Modified-Since",
"If-None-Match",
"If-Range",
"If-Unmodified-Since",
"Keep-Alive",
"Last-Modified",
"Location",
"Origin",
"Pragma",
"Public-Key-Pins",
"Public-Key-Pins-Report-Only",
"Referer",
"Referrer-Policy",
"Retry-After",
"Server",
"Set-Cookie",
"Set-Cookie2",
"Strict-Transport-Security",
"TE",
"Tk",
"Trailer",
"Transfer-Encoding",
"Upgrade-Insecure-Requests",
"User-Agent",
"Vary",
"Via",
"Warning",
"X-Content-Type-Options",
"X-DNS-Prefetch-Control",
"X-Frame-Options",
"X-XSS-Protection"
];
/**
* Get the MDN URL for the specified header
*
* @param {string} Name of the header
* The baseURL to use.
*
* @return {string}
* The MDN URL for the header, or null if not available.
*/
exports.getURL = (header) => {
if (SUPPORTED_HEADERS.indexOf(header) === -1) {
return null;
}
return URL_DOMAIN + URL_PATH + header + URL_PARAMS;
};
/**
* Use a different domain for the URLs. Used only for testing.
*
* @param {string} domain
* The domain to use.
*/
exports.setDomain = (domain) => {
URL_DOMAIN = domain;
};
/**
* Use a different list of supported headers. Used only for testing.
*
* @param {array} headers
* The supported headers to use.
*/
exports.setSupportedHeaders = (headers) => {
SUPPORTED_HEADERS = headers;
};

View File

@ -15,11 +15,16 @@ const {
const { L10N } = require("../../l10n");
const { writeHeaderText } = require("../../request-utils");
const { getFormattedSize } = require("../../utils/format-utils");
const Services = require("Services");
const { gDevTools } = require("devtools/client/framework/devtools");
const HeadersMDN = require("devtools/client/netmonitor/shared/components/headers-mdn");
const { REPS, MODE } = require("devtools/client/shared/components/reps/load-reps");
const Rep = createFactory(REPS.Rep);
// Components
const PropertiesView = createFactory(require("./properties-view"));
const { div, input, textarea } = DOM;
const { a, div, input, textarea } = DOM;
const EDIT_AND_RESEND = L10N.getStr("netmonitor.summary.editAndResend");
const RAW_HEADERS = L10N.getStr("netmonitor.summary.rawHeaders");
const RAW_HEADERS_REQUEST = L10N.getStr("netmonitor.summary.rawHeaders.requestHeaders");
@ -45,6 +50,7 @@ const HeadersPanel = createClass({
propTypes: {
cloneSelectedRequest: PropTypes.func.isRequired,
request: PropTypes.object.isRequired,
renderValue: PropTypes.func
},
getInitialState() {
@ -213,10 +219,49 @@ const HeadersPanel = createClass({
object,
filterPlaceHolder: HEADERS_FILTER_TEXT,
sectionNames: Object.keys(object),
renderValue
}),
)
);
}
});
function onLearnMoreClick(e, headerDocURL) {
e.stopPropagation();
e.preventDefault();
let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
win.openUILinkIn(headerDocURL, "tab");
}
function renderValue(props) {
const { member, value } = props;
if (typeof value !== "string") {
return null;
}
let headerDocURL = HeadersMDN.getURL(member.name);
return (
div({ className: "treeValueCellDivider" },
Rep(Object.assign(props, {
// FIXME: A workaround for the issue in StringRep
// Force StringRep to crop the text everytime
member: Object.assign({}, member, { open: false }),
mode: MODE.TINY,
cropLimit: 60,
})),
headerDocURL ?
a({
className: "learn-more-link",
title: headerDocURL,
onClick: (e) => onLearnMoreClick(e, headerDocURL),
}, `[${L10N.getStr("netmonitor.headers.learnMore")}]`)
:
null
)
);
}
module.exports = HeadersPanel;

View File

@ -6,6 +6,7 @@ DevToolsModules(
'cookies-panel.js',
'details-panel.js',
'editor.js',
'headers-mdn.js',
'headers-panel.js',
'params-panel.js',
'preview-panel.js',

View File

@ -98,6 +98,7 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
[browser_net_cyrillic-01.js]
[browser_net_cyrillic-02.js]
[browser_net_frame.js]
[browser_net_header-docs.js]
skip-if = (os == 'linux' && debug && bits == 32) # Bug 1321434
[browser_net_filter-01.js]
skip-if = (os == 'linux' && debug && bits == 32) # Bug 1303439

View File

@ -0,0 +1,56 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const HeadersMDN = require("devtools/client/netmonitor/shared/components/headers-mdn");
/**
* Tests if "Learn More" links are correctly displayed
* next to headers.
*/
add_task(function* () {
let { tab, monitor } = yield initNetMonitor(POST_DATA_URL);
info("Starting test... ");
let { document, NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
let wait = waitForNetworkEvents(monitor, 0, 2);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
content.wrappedJSObject.performRequests();
});
yield wait;
let origItem = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = origItem;
EventUtils.sendMouseEvent({ type: "click" },
document.querySelectorAll(".request-list-item")[0]);
testShowLearnMore(origItem);
return teardown(monitor);
/*
* Tests that a "Learn More" button is only shown if
* and only if a header is documented in MDN.
*/
function testShowLearnMore(data) {
document.querySelectorAll(".properties-view .treeRow.stringRow").forEach((rowEl, index) => {
let headerName = rowEl.querySelectorAll(".treeLabelCell .treeLabel")[0].textContent;
let headerDocURL = HeadersMDN.getURL(headerName);
let learnMoreEl = rowEl.querySelectorAll(".treeValueCell .learn-more-link");
if (headerDocURL === null) {
ok(learnMoreEl.length === 0,
"undocumented header does not include a \"Learn More\" button");
} else {
ok(learnMoreEl[0].getAttribute("title") === headerDocURL,
"documented header includes a \"Learn More\" button with a link to MDN");
}
});
}
});

View File

@ -77,6 +77,23 @@
display: none;
}
.treeTable .treeValueCellDivider {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
/* Learn More link */
.treeTable .treeValueCell .learn-more-link {
color: var(--theme-highlight-blue);
cursor: pointer;
margin: 0 5px;
}
.treeTable .treeValueCell .learn-more-link:hover {
text-decoration: underline;
}
/******************************************************************************/
/* Toggle Icon */