mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
Bug 1421213 - Clicking on the request status code should open the corresponding MDN page. r=nchevobbe
MozReview-Commit-ID: JlU7pJiZ689 --HG-- extra : rebase_source : b5ecdb6868e33759e75efa75511df39951cc9940
This commit is contained in:
parent
af5f219381
commit
3b4ce6bd81
@ -35,7 +35,9 @@ function onLearnMoreClick(e, url) {
|
||||
e.preventDefault();
|
||||
|
||||
let win = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
|
||||
if (e.button === 1) {
|
||||
let { button, ctrlKey, metaKey } = e;
|
||||
let isOSX = Services.appinfo.OS == "Darwin";
|
||||
if (button === 1 || (button === 0 && (isOSX ? metaKey : ctrlKey))) {
|
||||
win.openUILinkIn(url, "tabshifted");
|
||||
} else {
|
||||
win.openUILinkIn(url, "tab");
|
||||
|
@ -141,8 +141,9 @@ const SUPPORTED_HTTP_CODES = [
|
||||
];
|
||||
|
||||
const MDN_URL = "https://developer.mozilla.org/docs/";
|
||||
const GA_PARAMS =
|
||||
"?utm_source=mozilla&utm_medium=devtools-netmonitor&utm_campaign=default";
|
||||
const getGAParams = (panelId = "netmonitor") => {
|
||||
return `?utm_source=mozilla&utm_medium=devtools-${panelId}&utm_campaign=default`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the MDN URL for the specified header.
|
||||
@ -156,7 +157,7 @@ function getHeadersURL(header) {
|
||||
let idx = SUPPORTED_HEADERS.findIndex(item =>
|
||||
item.toLowerCase() === lowerCaseHeader);
|
||||
return idx > -1 ?
|
||||
`${MDN_URL}Web/HTTP/Headers/${SUPPORTED_HEADERS[idx] + GA_PARAMS}` : null;
|
||||
`${MDN_URL}Web/HTTP/Headers/${SUPPORTED_HEADERS[idx] + getGAParams()}` : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,10 +167,11 @@ function getHeadersURL(header) {
|
||||
*
|
||||
* @return {string} The MDN URL for the HTTP status code, or null if not available.
|
||||
*/
|
||||
function getHTTPStatusCodeURL(statusCode) {
|
||||
function getHTTPStatusCodeURL(statusCode, panelId) {
|
||||
let idx = SUPPORTED_HTTP_CODES.indexOf(statusCode);
|
||||
return idx > -1 ?
|
||||
`${MDN_URL}Web/HTTP/Status/${SUPPORTED_HTTP_CODES[idx] + GA_PARAMS}` : null;
|
||||
`${MDN_URL}Web/HTTP/Status/${SUPPORTED_HTTP_CODES[idx] + getGAParams(panelId)}`
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,7 +180,7 @@ function getHTTPStatusCodeURL(statusCode) {
|
||||
* @return {string} the MDN URL of the Timings tag for Network Monitor.
|
||||
*/
|
||||
function getNetMonitorTimingsURL() {
|
||||
return `${MDN_URL}Tools/Network_Monitor${GA_PARAMS}#Timings`;
|
||||
return `${MDN_URL}Tools/Network_Monitor${getGAParams()}#Timings`;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,7 +189,7 @@ function getNetMonitorTimingsURL() {
|
||||
* @return {string} The MDN URL for the documentation of Performance Analysis.
|
||||
*/
|
||||
function getPerformanceAnalysisURL() {
|
||||
return `${MDN_URL}Tools/Network_Monitor${GA_PARAMS}#Performance_analysis`;
|
||||
return `${MDN_URL}Tools/Network_Monitor${getGAParams()}#Performance_analysis`;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -1012,6 +1012,8 @@ a.learn-more-link.webconsole-learn-more-link {
|
||||
.webconsole-output-wrapper .message.network .status .status-info .status-code {
|
||||
padding: 0 2px;
|
||||
border-radius: 3px;
|
||||
text-decoration: none;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.webconsole-output-wrapper .message.network .status .status-info .status-code:not([data-code^="3"]) {
|
||||
|
@ -420,9 +420,14 @@ WebConsole.prototype = {
|
||||
* @param string aLink
|
||||
* The URL you want to open in a new tab.
|
||||
*/
|
||||
openLink: function WC_openLink(aLink)
|
||||
openLink: function WC_openLink(aLink, e)
|
||||
{
|
||||
this.chromeUtilsWindow.openUILinkIn(aLink, "tab");
|
||||
let isOSX = Services.appinfo.OS == "Darwin";
|
||||
if (e != null && (e.button === 1 || (e.button === 0 && (isOSX ? e.metaKey : e.ctrlKey)))) {
|
||||
this.chromeUtilsWindow.openUILinkIn(aLink, "tabshifted");
|
||||
} else {
|
||||
this.chromeUtilsWindow.openUILinkIn(aLink, "tab");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -93,9 +93,9 @@ class Message extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
onLearnMoreClick() {
|
||||
onLearnMoreClick(e) {
|
||||
let {exceptionDocURL} = this.props;
|
||||
this.props.serviceContainer.openLink(exceptionDocURL);
|
||||
this.props.serviceContainer.openLink(exceptionDocURL, e);
|
||||
}
|
||||
|
||||
onContextMenu(e) {
|
||||
|
@ -14,6 +14,8 @@ const Message = createFactory(require("devtools/client/webconsole/new-console-ou
|
||||
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
|
||||
const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const TabboxPanel = createFactory(require("devtools/client/netmonitor/src/components/TabboxPanel"));
|
||||
const { getHTTPStatusCodeURL } = require("devtools/client/netmonitor/src/utils/mdn-utils");
|
||||
const LEARN_MORE = l10n.getStr("webConsoleMoreInfoLabel");
|
||||
|
||||
NetworkEventMessage.displayName = "NetworkEventMessage";
|
||||
|
||||
@ -74,7 +76,17 @@ function NetworkEventMessage({
|
||||
let statusCode, statusInfo;
|
||||
|
||||
if (httpVersion && status && statusText !== undefined && totalTime !== undefined) {
|
||||
statusCode = dom.span({className: "status-code", "data-code": status}, status);
|
||||
let statusCodeDocURL = getHTTPStatusCodeURL(status.toString(), "webconsole");
|
||||
statusCode = dom.a({
|
||||
className: "status-code",
|
||||
"data-code": status,
|
||||
title: LEARN_MORE,
|
||||
onClick: (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
serviceContainer.openLink(statusCodeDocURL, e);
|
||||
}
|
||||
}, status);
|
||||
statusInfo = dom.span(
|
||||
{className: "status-info"},
|
||||
`[${httpVersion} `, statusCode, ` ${statusText} ${totalTime}ms]`
|
||||
|
@ -88,8 +88,8 @@ NewConsoleOutputWrapper.prototype = {
|
||||
}]));
|
||||
},
|
||||
hudProxy: hud.proxy,
|
||||
openLink: url => {
|
||||
hud.owner.openLink(url);
|
||||
openLink: (url, e) => {
|
||||
hud.owner.openLink(url, e);
|
||||
},
|
||||
createElement: nodename => {
|
||||
return this.document.createElement(nodename);
|
||||
|
@ -326,6 +326,7 @@ skip-if = true # Bug 1404886
|
||||
[browser_webconsole_network_exceptions.js]
|
||||
[browser_webconsole_network_messages_expand.js]
|
||||
[browser_webconsole_network_messages_openinnet.js]
|
||||
[browser_webconsole_network_messages_status_code.js]
|
||||
[browser_webconsole_network_requests_from_chrome.js]
|
||||
[browser_webconsole_network_reset_filter.js]
|
||||
[browser_webconsole_nodes_highlight.js]
|
||||
|
@ -43,8 +43,30 @@ add_task(async function () {
|
||||
const mixedActiveContentMessage = await onMixedActiveContent;
|
||||
ok(true, "Mixed active content warning message is visible");
|
||||
|
||||
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");
|
||||
const url = await simulateLinkClick(learnMoreLink);
|
||||
is(url, LEARN_MORE_URI, `Clicking the provided link opens ${url}`);
|
||||
let linkSimulation = await simulateLinkClick(learnMoreLink);
|
||||
checkLink({
|
||||
...linkSimulation,
|
||||
expectedLink: LEARN_MORE_URI,
|
||||
expectedTab: "tab"
|
||||
});
|
||||
|
||||
let isOSX = Services.appinfo.OS == "Darwin";
|
||||
let 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"
|
||||
});
|
||||
});
|
||||
|
@ -49,8 +49,8 @@ add_task(async function() {
|
||||
|
||||
info("Clicking on the Learn More link");
|
||||
let learnMoreLink = blockedMixedActiveContentMessage.querySelector(".learn-more-link");
|
||||
let url = await simulateLinkClick(learnMoreLink);
|
||||
is(url, LEARN_MORE_URI, `Clicking the provided link opens ${url}`);
|
||||
let response = await simulateLinkClick(learnMoreLink);
|
||||
is(response.link, LEARN_MORE_URI, `Clicking the provided link opens ${response.link}`);
|
||||
|
||||
info("Test disabling mixed content protection");
|
||||
|
||||
@ -74,8 +74,8 @@ add_task(async function() {
|
||||
|
||||
info("Clicking on the Learn More link");
|
||||
learnMoreLink = mixedActiveContentMessage.querySelector(".learn-more-link");
|
||||
url = await simulateLinkClick(learnMoreLink);
|
||||
is(url, LEARN_MORE_URI, `Clicking the provided link opens ${url}`);
|
||||
response = await simulateLinkClick(learnMoreLink);
|
||||
is(response.link, LEARN_MORE_URI, `Clicking the provided link opens ${response.link}`);
|
||||
});
|
||||
|
||||
function pushPrefEnv() {
|
||||
|
@ -0,0 +1,104 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_FILE = "test-network-request.html";
|
||||
const TEST_PATH = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/";
|
||||
const TEST_URI = TEST_PATH + TEST_FILE;
|
||||
|
||||
const NET_PREF = "devtools.webconsole.filter.net";
|
||||
const XHR_PREF = "devtools.webconsole.filter.netxhr";
|
||||
let { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const LEARN_MORE_URI = "https://developer.mozilla.org/docs/Web/HTTP/Status/200" + STATUS_CODES_GA_PARAMS;
|
||||
|
||||
pushPref(NET_PREF, true);
|
||||
pushPref(XHR_PREF, true);
|
||||
|
||||
add_task(async function task() {
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
const currentTab = gBrowser.selectedTab;
|
||||
let target = TargetFactory.forTab(currentTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
let {ui} = toolbox.getCurrentPanel().hud;
|
||||
const onNetworkMessageUpdate = ui.jsterm.hud.once("network-message-updated");
|
||||
|
||||
// Fire an XHR POST request.
|
||||
await ContentTask.spawn(gBrowser.selectedBrowser, null, function () {
|
||||
content.wrappedJSObject.testXhrPost();
|
||||
});
|
||||
|
||||
info("XHR executed");
|
||||
await onNetworkMessageUpdate;
|
||||
|
||||
let xhrUrl = TEST_PATH + "test-data.json";
|
||||
let messageNode = await waitFor(() => findMessage(hud, xhrUrl));
|
||||
let urlNode = messageNode.querySelector(".url");
|
||||
let statusCodeNode = messageNode.querySelector(".status-code");
|
||||
info("Network message found.");
|
||||
|
||||
ok(statusCodeNode.title, l10n.getStr("webConsoleMoreInfoLabel"));
|
||||
let {
|
||||
middleMouseEvent,
|
||||
ctrlOrCmdKeyMouseEvent,
|
||||
rightClickMouseEvent,
|
||||
rightClickCtrlOrCmdKeyMouseEvent,
|
||||
} = getMouseEvents();
|
||||
|
||||
let 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 (let testCase of testCases) {
|
||||
const { clickEvent } = testCase;
|
||||
let onConsoleMenuOpened = [rightClickMouseEvent, rightClickCtrlOrCmdKeyMouseEvent].includes(clickEvent) ?
|
||||
hud.ui.newConsoleOutput.once("menu-open") : null;
|
||||
|
||||
let { link, where } = await simulateLinkClick(statusCodeNode, testCase.clickEvent);
|
||||
is(link, testCase.link, `Clicking the provided link opens ${link}`);
|
||||
is(where, testCase.where, `Link opened in correct tab`);
|
||||
|
||||
if (onConsoleMenuOpened) {
|
||||
info("Check if context menu is opened on right clicking the status-code");
|
||||
await onConsoleMenuOpened;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function getMouseEvents() {
|
||||
let isOSX = Services.appinfo.OS == "Darwin";
|
||||
|
||||
let middleMouseEvent = new MouseEvent("click", {
|
||||
bubbles: true,
|
||||
button: 1,
|
||||
view: window
|
||||
});
|
||||
let ctrlOrCmdKeyMouseEvent = new MouseEvent("click", {
|
||||
bubbles: true,
|
||||
[isOSX ? "metaKey" : "ctrlKey"]: true,
|
||||
view: window
|
||||
});
|
||||
let rightClickMouseEvent = new MouseEvent("contextmenu", {
|
||||
bubbles: true,
|
||||
button: 2,
|
||||
view: window
|
||||
});
|
||||
let rightClickCtrlOrCmdKeyMouseEvent = new MouseEvent("contextmenu", {
|
||||
bubbles: true,
|
||||
button: 2,
|
||||
[isOSX ? "metaKey" : "ctrlKey"]: true,
|
||||
view: window
|
||||
});
|
||||
|
||||
return {
|
||||
middleMouseEvent,
|
||||
ctrlOrCmdKeyMouseEvent,
|
||||
rightClickMouseEvent,
|
||||
rightClickCtrlOrCmdKeyMouseEvent,
|
||||
};
|
||||
}
|
@ -20,9 +20,16 @@ Services.scriptloader.loadSubScript(
|
||||
|
||||
var {HUDService} = require("devtools/client/webconsole/hudservice");
|
||||
var WCUL10n = require("devtools/client/webconsole/webconsole-l10n");
|
||||
const DOCS_GA_PARAMS = "?utm_source=mozilla" +
|
||||
"&utm_medium=firefox-console-errors" +
|
||||
"&utm_campaign=default";
|
||||
const DOCS_GA_PARAMS = `?${new URLSearchParams({
|
||||
"utm_source": "mozilla",
|
||||
"utm_medium": "firefox-console-errors",
|
||||
"utm_campaign": "default"
|
||||
})}`;
|
||||
const STATUS_CODES_GA_PARAMS = `?${new URLSearchParams({
|
||||
"utm_source": "mozilla",
|
||||
"utm_medium": "devtools-webconsole",
|
||||
"utm_campaign": "default"
|
||||
})}`;
|
||||
|
||||
Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", true);
|
||||
registerCleanupFunction(function* () {
|
||||
@ -413,24 +420,53 @@ async function closeConsole(tab = gBrowser.selectedTab) {
|
||||
* Fake clicking a link and return the URL we would have navigated to.
|
||||
* This function should be used to check external links since we can't access
|
||||
* network in tests.
|
||||
* This can also be used to test that a click will not be fired.
|
||||
*
|
||||
* @param ElementNode element
|
||||
* The <a> element we want to simulate click on.
|
||||
* @param Object clickEventProps
|
||||
* The custom properties which would be used to dispatch a click event
|
||||
* @returns Promise
|
||||
* A Promise that resolved when the link clik simulation occured.
|
||||
* 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) {
|
||||
return new Promise((resolve) => {
|
||||
// Override openUILinkIn to prevent navigating.
|
||||
let oldOpenUILinkIn = window.openUILinkIn;
|
||||
window.openUILinkIn = function (link) {
|
||||
function simulateLinkClick(element, clickEventProps) {
|
||||
// Override openUILinkIn to prevent navigating.
|
||||
let oldOpenUILinkIn = window.openUILinkIn;
|
||||
|
||||
const onOpenLink = new Promise((resolve) => {
|
||||
window.openUILinkIn = function (link, where) {
|
||||
window.openUILinkIn = oldOpenUILinkIn;
|
||||
resolve(link);
|
||||
resolve({link: link, where});
|
||||
};
|
||||
|
||||
// Click on the link.
|
||||
element.click();
|
||||
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 openUILinkIn was not called.
|
||||
let timeoutId;
|
||||
const onTimeout = new Promise(function(resolve, reject) {
|
||||
timeoutId = setTimeout(() => {
|
||||
window.openUILinkIn = oldOpenUILinkIn;
|
||||
timeoutId = null;
|
||||
resolve({link: null, where: null});
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
onOpenLink.then(() => {
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
});
|
||||
return Promise.race([onOpenLink, onTimeout]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user