summaryrefslogtreecommitdiffstats
path: root/comm/suite/base/content/contentAreaClick.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/suite/base/content/contentAreaClick.js')
-rw-r--r--comm/suite/base/content/contentAreaClick.js260
1 files changed, 260 insertions, 0 deletions
diff --git a/comm/suite/base/content/contentAreaClick.js b/comm/suite/base/content/contentAreaClick.js
new file mode 100644
index 0000000000..b4c83e991e
--- /dev/null
+++ b/comm/suite/base/content/contentAreaClick.js
@@ -0,0 +1,260 @@
+// /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+/*
+ * - [ Dependencies ] ---------------------------------------------------------
+ * utilityOverlay.js:
+ * - gatherTextUnder
+ */
+
+ function hrefAndLinkNodeForClickEvent(event)
+ {
+ var href = "";
+ var isKeyCommand = (event.type == "command");
+ var linkNode = isKeyCommand ? document.commandDispatcher.focusedElement
+ : event.originalTarget;
+
+ while (linkNode instanceof Element) {
+ if (linkNode instanceof HTMLAnchorElement ||
+ linkNode instanceof HTMLAreaElement ||
+ linkNode instanceof HTMLLinkElement) {
+ href = linkNode.href;
+ if (href)
+ break;
+ }
+ // Try MathML href
+ else if (linkNode.namespaceURI == "http://www.w3.org/1998/Math/MathML" &&
+ linkNode.hasAttribute("href")) {
+ href = linkNode.getAttribute("href");
+ href = makeURLAbsolute(linkNode.baseURI, href);
+ break;
+ }
+ // Try simple XLink
+ else if (linkNode.hasAttributeNS("http://www.w3.org/1999/xlink", "href")) {
+ href = linkNode.getAttributeNS("http://www.w3.org/1999/xlink", "href");
+ href = makeURLAbsolute(linkNode.baseURI, href);
+ break;
+ }
+ linkNode = linkNode.parentNode;
+ }
+
+ return href ? {href: href, linkNode: linkNode} : null;
+ }
+
+ // Called whenever the user clicks in the content area,
+ // except when left-clicking on links (special case)
+ // should always return true for click to go through
+ function contentAreaClick(event)
+ {
+ if (!event.isTrusted || event.defaultPrevented) {
+ return true;
+ }
+
+ var isKeyCommand = (event.type == "command");
+ var ceParams = hrefAndLinkNodeForClickEvent(event);
+ if (ceParams) {
+ var href = ceParams.href;
+ if (isKeyCommand) {
+ var doc = event.target.ownerDocument;
+ urlSecurityCheck(href, doc.nodePrincipal);
+ openLinkIn(href, event && event.altKey ? "tabshifted" : "tab",
+ { charset: doc.characterSet,
+ referrerURI: doc.documentURIObject });
+ event.stopPropagation();
+ }
+ else {
+ // if in mailnews block the link left click if we determine
+ // that this URL is phishy (i.e. a potential email scam)
+ if ("gMessengerBundle" in this && event.button < 2 &&
+ isPhishingURL(ceParams.linkNode, false, href))
+ return false;
+ handleLinkClick(event, href, ceParams.linkNode);
+
+ // Mark the page as a user followed link. This is done so that history can
+ // distinguish automatic embed visits from user activated ones. For example
+ // pages loaded in frames are embed visits and lost with the session, while
+ // visits across frames should be preserved.
+ try {
+ PlacesUIUtils.markPageAsFollowedLink(href);
+ } catch (ex) { /* Skip invalid URIs. */ }
+ }
+ return true;
+ }
+
+ if (!isKeyCommand && event.button == 1 &&
+ Services.prefs.getBoolPref("middlemouse.contentLoadURL") &&
+ !Services.prefs.getBoolPref("general.autoScroll")) {
+ middleMousePaste(event);
+ }
+
+ return true;
+ }
+
+function handleLinkClick(event, href, linkNode) {
+ if (event.button == 2) // right click
+ return false;
+
+ var where = whereToOpenLink(event);
+ if (where == "current")
+ return false;
+
+ var doc = event.target.ownerDocument;
+
+ if (where == "save") {
+ saveURL(href, linkNode ? gatherTextUnder(linkNode) : "", null, false,
+ true, doc.documentURIObject, doc);
+ event.preventDefault();
+ return true;
+ }
+
+ var referrerURI = doc.documentURIObject;
+ // if the mixedContentChannel is present and the referring URI passes
+ // a same origin check with the target URI, we can preserve the users
+ // decision of disabling MCB on a page for it's child tabs.
+ var persistAllowMixedContentInChildTab = false;
+
+ if (where == "tab" && getBrowser().docShell.mixedContentChannel) {
+ const sm = Services.scriptSecurityManager;
+ try {
+ var targetURI = makeURI(href);
+ sm.checkSameOriginURI(referrerURI, targetURI, false);
+ persistAllowMixedContentInChildTab = true;
+ }
+ catch (e) { }
+ }
+
+ urlSecurityCheck(href, doc.nodePrincipal);
+ let params = {
+ charset: doc.characterSet,
+ private: gPrivate ? true : false,
+ allowMixedContent: persistAllowMixedContentInChildTab,
+ referrerURI: referrerURI,
+ noReferrer: BrowserUtils.linkHasNoReferrer(linkNode),
+ originPrincipal: doc.nodePrincipal,
+ triggeringPrincipal: doc.nodePrincipal,
+ };
+
+ // The new tab/window must use the same userContextId
+ if (doc.nodePrincipal.originAttributes.userContextId) {
+ params.userContextId = doc.nodePrincipal.originAttributes.userContextId;
+ }
+
+ openLinkIn(href, where, params);
+ event.preventDefault();
+ return true;
+}
+
+ function middleMousePaste(event) {
+
+ let clipboard = readFromClipboard();
+
+ if (!clipboard)
+ return;
+
+ // Strip embedded newlines and surrounding whitespace, to match the URL
+ // bar's behavior (stripsurroundingwhitespace).
+ clipboard = clipboard.replace(/\s*\n\s*/g, "");
+
+ clipboard = stripUnsafeProtocolOnPaste(clipboard);
+
+ // If its not the current tab, we don't need to do anything because the
+ // browser doesn't exist.
+ let where = whereToOpenLink(event, true, false);
+ let lastLocationChange;
+ if (where == "current") {
+ lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
+ }
+
+ getShortcutOrURIAndPostData(clipboard).then(data => {
+ try {
+ makeURI(data.url);
+ } catch (ex) {
+ // Not a valid URI.
+ return;
+ }
+
+ try {
+ addToUrlbarHistory(data.url);
+ } catch (ex) {
+ // Things may go wrong when adding url to session history,
+ // but don't let that interfere with the loading of the url.
+ Cu.reportError(ex);
+ }
+
+ if (where != "current" ||
+ lastLocationChange == gBrowser.selectedBrowser.lastLocationChange) {
+ openUILink(data.url, event,
+ { ignoreButton: true,
+ disallowInheritPrincipal: !data.mayInheritPrincipal });
+ }
+ });
+
+ event.stopPropagation();
+ }
+
+ function stripUnsafeProtocolOnPaste(pasteData) {
+ // Don't allow pasting javascript URIs since we don't support
+ // LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL for those.
+ let changed = false;
+ let pasteDataNoJS = pasteData.replace(/\r?\n/g, "")
+ .replace(/^(?:\s*javascript:)+/i,
+ () => { changed = true;
+ return ""; });
+ return changed ? pasteDataNoJS : pasteData;
+ }
+
+ function addToUrlbarHistory(aUrlToAdd)
+ {
+ if (gPrivate)
+ return;
+
+ if (!Services.prefs.getBoolPref("browser.urlbar.historyEnabled"))
+ return;
+
+ // Remove leading and trailing spaces first.
+ aUrlToAdd = aUrlToAdd.trim();
+
+ if (!aUrlToAdd)
+ return;
+ // Don't store bad URLs.
+ if (aUrlToAdd.search(/[\x00-\x1F]/) != -1)
+ return;
+
+ getShortcutOrURIAndPostData(aUrlToAdd).then(data => {
+ var fixedUpURI = Services.uriFixup.createFixupURI(data.url, 0);
+ if (!fixedUpURI.schemeIs("data"))
+ PlacesUtils.history.markPageAsTyped(fixedUpURI);
+ }).catch(() => {});
+
+ // Open or create the urlbar history database.
+ var file = GetUrlbarHistoryFile();
+ var connection = Services.storage.openDatabase(file);
+ connection.beginTransaction();
+ if (!connection.tableExists("urlbarhistory"))
+ connection.createTable("urlbarhistory", "url TEXT");
+
+ // If the URL is already present in the database then remove it from
+ // its current position. It is then reinserted at the top of the list.
+ var statement = connection.createStatement(
+ "DELETE FROM urlbarhistory WHERE LOWER(url) = LOWER(?1)");
+ statement.bindByIndex(0, aUrlToAdd);
+ statement.execute();
+ statement.finalize();
+
+ // Put the value as it was typed by the user in to urlbar history.
+ statement = connection.createStatement(
+ "INSERT INTO urlbarhistory (url) VALUES (?1)");
+ statement.bindByIndex(0, aUrlToAdd);
+ statement.execute();
+ statement.finalize();
+
+ // Remove any expired history items so that we don't let
+ // this grow without bound.
+ connection.executeSimpleSQL(
+ "DELETE FROM urlbarhistory WHERE ROWID NOT IN " +
+ "(SELECT ROWID FROM urlbarhistory ORDER BY ROWID DESC LIMIT 30)");
+ connection.commitTransaction();
+ connection.close();
+ }