summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/general/browser_contentAreaClick.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/general/browser_contentAreaClick.js')
-rw-r--r--browser/base/content/test/general/browser_contentAreaClick.js307
1 files changed, 307 insertions, 0 deletions
diff --git a/browser/base/content/test/general/browser_contentAreaClick.js b/browser/base/content/test/general/browser_contentAreaClick.js
new file mode 100644
index 000000000..facdfb498
--- /dev/null
+++ b/browser/base/content/test/general/browser_contentAreaClick.js
@@ -0,0 +1,307 @@
+/* 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.
+ */
+
+var gTests = [
+
+ {
+ desc: "Simple left click",
+ setup: function() {},
+ clean: function() {},
+ event: {},
+ targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
+ expectedInvokedMethods: [],
+ preventDefault: false,
+ },
+
+ {
+ desc: "Ctrl/Cmd left click",
+ setup: function() {},
+ clean: function() {},
+ event: { ctrlKey: true,
+ metaKey: true },
+ targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
+ expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
+ preventDefault: true,
+ },
+
+ // The next test was once handling feedService.forcePreview(). Now it should
+ // just be like Alt click.
+ {
+ desc: "Shift+Alt left click",
+ setup: function() {
+ gPrefService.setBoolPref("browser.altClickSave", true);
+ },
+ clean: function() {
+ gPrefService.clearUserPref("browser.altClickSave");
+ },
+ event: { shiftKey: true,
+ altKey: true },
+ targets: [ "commonlink", "maplink" ],
+ expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
+ preventDefault: true,
+ },
+
+ {
+ desc: "Shift+Alt left click on XLinks",
+ setup: function() {
+ gPrefService.setBoolPref("browser.altClickSave", true);
+ },
+ clean: function() {
+ gPrefService.clearUserPref("browser.altClickSave");
+ },
+ event: { shiftKey: true,
+ altKey: true },
+ targets: [ "mathxlink", "svgxlink"],
+ expectedInvokedMethods: [ "saveURL" ],
+ preventDefault: true,
+ },
+
+ {
+ desc: "Shift click",
+ setup: function() {},
+ clean: function() {},
+ event: { shiftKey: true },
+ targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
+ expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
+ preventDefault: true,
+ },
+
+ {
+ desc: "Alt click",
+ setup: function() {
+ gPrefService.setBoolPref("browser.altClickSave", true);
+ },
+ clean: function() {
+ gPrefService.clearUserPref("browser.altClickSave");
+ },
+ event: { altKey: true },
+ targets: [ "commonlink", "maplink" ],
+ expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
+ preventDefault: true,
+ },
+
+ {
+ desc: "Alt click on XLinks",
+ setup: function() {
+ gPrefService.setBoolPref("browser.altClickSave", true);
+ },
+ clean: function() {
+ gPrefService.clearUserPref("browser.altClickSave");
+ },
+ event: { altKey: true },
+ targets: [ "mathxlink", "svgxlink" ],
+ expectedInvokedMethods: [ "saveURL" ],
+ preventDefault: true,
+ },
+
+ {
+ desc: "Panel click",
+ setup: function() {},
+ clean: function() {},
+ event: {},
+ targets: [ "panellink" ],
+ expectedInvokedMethods: [ "urlSecurityCheck", "loadURI" ],
+ preventDefault: true,
+ },
+
+ {
+ desc: "Simple middle click opentab",
+ setup: function() {},
+ clean: function() {},
+ event: { button: 1 },
+ targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
+ expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
+ preventDefault: true,
+ },
+
+ {
+ desc: "Simple middle click openwin",
+ setup: function() {
+ gPrefService.setBoolPref("browser.tabs.opentabfor.middleclick", false);
+ },
+ clean: function() {
+ gPrefService.clearUserPref("browser.tabs.opentabfor.middleclick");
+ },
+ event: { button: 1 },
+ targets: [ "commonlink", "mathxlink", "svgxlink", "maplink" ],
+ expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
+ preventDefault: true,
+ },
+
+ {
+ desc: "Middle mouse paste",
+ setup: function() {
+ gPrefService.setBoolPref("middlemouse.contentLoadURL", true);
+ gPrefService.setBoolPref("general.autoScroll", false);
+ },
+ clean: function() {
+ gPrefService.clearUserPref("middlemouse.contentLoadURL");
+ gPrefService.clearUserPref("general.autoScroll");
+ },
+ event: { button: 1 },
+ 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",
+];
+
+// Reference to the new window.
+var gTestWin = null;
+
+// List of methods invoked by a specific call to contentAreaClick.
+var gInvokedMethods = [];
+
+// The test currently running.
+var gCurrentTest = null;
+
+function test() {
+ waitForExplicitFinish();
+
+ 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: function (event) {
+ let linkId = event.target.id || event.target.localName;
+ is(event.type, "click",
+ gCurrentTest.desc + ":Handler received a click 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.
+ gCurrentTest.expectedInvokedMethods.forEach(function(aExpectedMethodName) {
+ isnot(gInvokedMethods.indexOf(aExpectedMethodName), -1,
+ gCurrentTest.desc + ":" + aExpectedMethodName + " was invoked");
+ });
+
+ if (gInvokedMethods.length != gCurrentTest.expectedInvokedMethods.length) {
+ ok(false, "Wrong number of invoked methods");
+ gInvokedMethods.forEach(method => info(method + " was invoked"));
+ }
+
+ event.preventDefault();
+ event.stopPropagation();
+
+ executeSoon(runNextTest);
+ }
+}
+
+// Wraps around the methods' replacement mock function.
+function wrapperMethod(aInvokedMethods, aMethodName) {
+ return function () {
+ aInvokedMethods.push(aMethodName);
+ // At least getShortcutOrURIAndPostData requires to return url
+ return (aMethodName == "getShortcutOrURIAndPostData") ? arguments.url : arguments[0];
+ }
+}
+
+function setupTestBrowserWindow() {
+ // Steal click events and don't propagate them.
+ gTestWin.addEventListener("click", gClickHandler, true);
+
+ // Replace methods.
+ gReplacedMethods.forEach(function (aMethodName) {
+ gTestWin["old_" + aMethodName] = gTestWin[aMethodName];
+ gTestWin[aMethodName] = wrapperMethod(gInvokedMethods, aMethodName);
+ });
+
+ // 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="mathxlink" xmlns="http://www.w3.org/1998/Math/MathML" xlink:type="simple" xlink: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 == 0) {
+ info(gCurrentTest.desc + ": cleaning up...")
+ gCurrentTest.clean();
+
+ if (gTests.length > 0) {
+ gCurrentTest = gTests.shift();
+ gCurrentTest.setup();
+ }
+ else {
+ finishTest();
+ return;
+ }
+ }
+
+ // Move to next target.
+ gInvokedMethods.length = 0;
+ let target = gCurrentTest.targets.shift();
+
+ info(gCurrentTest.desc + ": testing " + target);
+
+ // Fire 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);
+
+ // Restore original methods.
+ gReplacedMethods.forEach(function (aMethodName) {
+ gTestWin[aMethodName] = gTestWin["old_" + aMethodName];
+ delete gTestWin["old_" + aMethodName];
+ });
+
+ gTestWin.close();
+ finish();
+}