gecko-dev/browser/base/content/test/general/browser_contentAreaClick.js
Frederic Wang 138d2ac0fb Bug 1575870. Remove support for XLink on MathML elements. r=emilio
See https://groups.google.com/forum/#!topic/mozilla.dev.platform/70NFnet82cU

This commit introduces a new mathml.xlink.disabled option to disable support
for XLink attributes on MathML elements together with a use counter and
deprecation warning when support is enabled. For now, support is only disabled
in Nightly.

In the past, we relied on custom MathML deprecation warnings but those are
removed here. Corresponding tests for these legacy warning messages are
also removed from test_bug553917.html.

link-1.xhtml is run with XLink support enabled (since it checks xlink:href)
while browser_contentAltClick.js and browser_contentAreaClick.js are updated
to instead check MathML links (i.e. href instead of xlink:href).

Differential Revision: https://phabricator.services.mozilla.com/D43332

--HG--
extra : moz-landing-system : lando
2019-10-05 21:47:38 +00:00

329 lines
9.6 KiB
JavaScript

/* 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/. */
/**
* Test for bug 549340.
* Test for browser.js::contentAreaClick() util.
*
* The test opens a new browser window, then replaces browser.js methods invoked
* by contentAreaClick with a mock function that tracks which methods have been
* called.
* Each sub-test synthesizes a mouse click event on links injected in content,
* the event is collected by a click handler that ensures that contentAreaClick
* correctly prevent default events, and follows the correct code path.
*/
const { sinon } = ChromeUtils.import("resource://testing-common/Sinon.jsm");
var gTests = [
{
desc: "Simple left click",
setup() {},
clean() {},
event: {},
targets: ["commonlink", "mathlink", "svgxlink", "maplink"],
expectedInvokedMethods: [],
preventDefault: false,
},
{
desc: "Ctrl/Cmd left click",
setup() {},
clean() {},
event: { ctrlKey: true, metaKey: true },
targets: ["commonlink", "mathlink", "svgxlink", "maplink"],
expectedInvokedMethods: ["urlSecurityCheck", "openLinkIn"],
preventDefault: true,
},
// The next test should just be like Alt click.
{
desc: "Shift+Alt left click",
setup() {
Services.prefs.setBoolPref("browser.altClickSave", true);
},
clean() {
Services.prefs.clearUserPref("browser.altClickSave");
},
event: { shiftKey: true, altKey: true },
targets: ["commonlink", "maplink"],
expectedInvokedMethods: ["gatherTextUnder", "saveURL"],
preventDefault: true,
},
{
desc: "Shift+Alt left click on XLinks",
setup() {
Services.prefs.setBoolPref("browser.altClickSave", true);
},
clean() {
Services.prefs.clearUserPref("browser.altClickSave");
},
event: { shiftKey: true, altKey: true },
targets: ["mathlink", "svgxlink"],
expectedInvokedMethods: ["saveURL"],
preventDefault: true,
},
{
desc: "Shift click",
setup() {},
clean() {},
event: { shiftKey: true },
targets: ["commonlink", "mathlink", "svgxlink", "maplink"],
expectedInvokedMethods: ["urlSecurityCheck", "openLinkIn"],
preventDefault: true,
},
{
desc: "Alt click",
setup() {
Services.prefs.setBoolPref("browser.altClickSave", true);
},
clean() {
Services.prefs.clearUserPref("browser.altClickSave");
},
event: { altKey: true },
targets: ["commonlink", "maplink"],
expectedInvokedMethods: ["gatherTextUnder", "saveURL"],
preventDefault: true,
},
{
desc: "Alt click on XLinks",
setup() {
Services.prefs.setBoolPref("browser.altClickSave", true);
},
clean() {
Services.prefs.clearUserPref("browser.altClickSave");
},
event: { altKey: true },
targets: ["mathlink", "svgxlink"],
expectedInvokedMethods: ["saveURL"],
preventDefault: true,
},
{
desc: "Panel click",
setup() {},
clean() {},
event: {},
targets: ["panellink"],
expectedInvokedMethods: ["urlSecurityCheck", "loadURI"],
preventDefault: true,
},
{
desc: "Simple middle click opentab",
setup() {},
clean() {},
event: { button: 1 },
wantedEvent: "auxclick",
targets: ["commonlink", "mathlink", "svgxlink", "maplink"],
expectedInvokedMethods: ["urlSecurityCheck", "openLinkIn"],
preventDefault: true,
},
{
desc: "Simple middle click openwin",
setup() {
Services.prefs.setBoolPref("browser.tabs.opentabfor.middleclick", false);
},
clean() {
Services.prefs.clearUserPref("browser.tabs.opentabfor.middleclick");
},
event: { button: 1 },
wantedEvent: "auxclick",
targets: ["commonlink", "mathlink", "svgxlink", "maplink"],
expectedInvokedMethods: ["urlSecurityCheck", "openLinkIn"],
preventDefault: true,
},
{
desc: "Middle mouse paste",
setup() {
Services.prefs.setBoolPref("middlemouse.contentLoadURL", true);
Services.prefs.setBoolPref("general.autoScroll", false);
},
clean() {
Services.prefs.clearUserPref("middlemouse.contentLoadURL");
Services.prefs.clearUserPref("general.autoScroll");
},
event: { button: 1 },
wantedEvent: "auxclick",
targets: ["emptylink"],
expectedInvokedMethods: ["middleMousePaste"],
preventDefault: true,
},
];
// Array of method names that will be replaced in the new window.
var gReplacedMethods = [
"middleMousePaste",
"urlSecurityCheck",
"loadURI",
"gatherTextUnder",
"saveURL",
"openLinkIn",
"getShortcutOrURIAndPostData",
];
// Returns the target object for the replaced method.
function getStub(replacedMethod) {
let targetObj =
replacedMethod == "getShortcutOrURIAndPostData" ? UrlbarUtils : gTestWin;
return targetObj[replacedMethod];
}
// Reference to the new window.
var gTestWin = null;
// The test currently running.
var gCurrentTest = null;
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
sinon.restore();
});
gTestWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
whenDelayedStartupFinished(gTestWin, function() {
info("Browser window opened");
waitForFocus(function() {
info("Browser window focused");
waitForFocus(
function() {
info("Setting up browser...");
setupTestBrowserWindow();
info("Running tests...");
executeSoon(runNextTest);
},
gTestWin.content,
true
);
}, gTestWin);
});
}
// Click handler used to steal click events.
var gClickHandler = {
handleEvent(event) {
if (event.type == "click" && event.button != 0) {
return;
}
let linkId = event.target.id || event.target.localName;
let wantedEvent = gCurrentTest.wantedEvent || "click";
is(
event.type,
wantedEvent,
`${
gCurrentTest.desc
}:Handler received a ${wantedEvent} event on ${linkId}`
);
let isPanelClick = linkId == "panellink";
gTestWin.contentAreaClick(event, isPanelClick);
let prevent = event.defaultPrevented;
is(
prevent,
gCurrentTest.preventDefault,
gCurrentTest.desc +
": event.defaultPrevented is correct (" +
prevent +
")"
);
// Check that all required methods have been called.
for (let expectedMethod of gCurrentTest.expectedInvokedMethods) {
ok(
getStub(expectedMethod).called,
`${gCurrentTest.desc}:${expectedMethod} should have been invoked`
);
}
for (let method of gReplacedMethods) {
if (
getStub(method).called &&
!gCurrentTest.expectedInvokedMethods.includes(method)
) {
ok(false, `Should have not called ${method}`);
}
}
event.preventDefault();
event.stopPropagation();
executeSoon(runNextTest);
},
};
function setupTestBrowserWindow() {
// Steal click events and don't propagate them.
gTestWin.addEventListener("click", gClickHandler, true);
gTestWin.addEventListener("auxclick", gClickHandler, true);
// Replace methods.
gReplacedMethods.forEach(function(methodName) {
let targetObj =
methodName == "getShortcutOrURIAndPostData" ? UrlbarUtils : gTestWin;
sinon.stub(targetObj, methodName).returnsArg(0);
});
// Inject links in content.
let doc = gTestWin.content.document;
let mainDiv = doc.createElement("div");
mainDiv.innerHTML =
'<p><a id="commonlink" href="http://mochi.test/moz/">Common link</a></p>' +
'<p><a id="panellink" href="http://mochi.test/moz/">Panel link</a></p>' +
'<p><a id="emptylink">Empty link</a></p>' +
'<p><math id="mathlink" xmlns="http://www.w3.org/1998/Math/MathML" href="http://mochi.test/moz/"><mtext>MathML XLink</mtext></math></p>' +
'<p><svg id="svgxlink" xmlns="http://www.w3.org/2000/svg" width="100px" height="50px" version="1.1"><a xlink:type="simple" xlink:href="http://mochi.test/moz/"><text transform="translate(10, 25)">SVG XLink</text></a></svg></p>' +
'<p><map name="map" id="map"><area href="http://mochi.test/moz/" shape="rect" coords="0,0,128,128" /></map><img id="maplink" usemap="#map" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAIAAABMXPacAAAABGdBTUEAALGPC%2FxhBQAAAOtJREFUeF7t0IEAAAAAgKD9qRcphAoDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGBgwIAAAT0N51AAAAAASUVORK5CYII%3D"/></p>';
doc.body.appendChild(mainDiv);
}
function runNextTest() {
if (!gCurrentTest) {
gCurrentTest = gTests.shift();
gCurrentTest.setup();
}
if (!gCurrentTest.targets.length) {
info(gCurrentTest.desc + ": cleaning up...");
gCurrentTest.clean();
if (gTests.length) {
gCurrentTest = gTests.shift();
gCurrentTest.setup();
} else {
finishTest();
return;
}
}
// Move to next target.
sinon.resetHistory();
let target = gCurrentTest.targets.shift();
info(gCurrentTest.desc + ": testing " + target);
// Fire (aux)click event.
let targetElt = gTestWin.content.document.getElementById(target);
ok(targetElt, gCurrentTest.desc + ": target is valid (" + targetElt.id + ")");
EventUtils.synthesizeMouseAtCenter(
targetElt,
gCurrentTest.event,
gTestWin.content
);
}
function finishTest() {
info("Restoring browser...");
gTestWin.removeEventListener("click", gClickHandler, true);
gTestWin.removeEventListener("auxclick", gClickHandler, true);
gTestWin.close();
finish();
}