diff options
Diffstat (limited to 'browser/base/content/content.js')
-rw-r--r-- | browser/base/content/content.js | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/browser/base/content/content.js b/browser/base/content/content.js new file mode 100644 index 000000000..33b774f90 --- /dev/null +++ b/browser/base/content/content.js @@ -0,0 +1,178 @@ +/* -*- Mode: javascript; 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/. */ + +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils", + "resource://gre/modules/BrowserUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerContent", + "resource://gre/modules/LoginManagerContent.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "LoginFormFactory", + "resource://gre/modules/LoginManagerContent.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "InsecurePasswordUtils", + "resource://gre/modules/InsecurePasswordUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "FormSubmitObserver", + "resource:///modules/FormSubmitObserver.jsm"); + +// Bug 671101 - directly using webNavigation in this context +// causes docshells to leak +this.__defineGetter__("webNavigation", function () { + return docShell.QueryInterface(Ci.nsIWebNavigation); +}); + +addMessageListener("WebNavigation:LoadURI", function (message) { + let flags = message.json.flags || webNavigation.LOAD_FLAGS_NONE; + + webNavigation.loadURI(message.json.uri, flags, null, null, null); +}); + +// TabChildGlobal +var global = this; + +// Load the form validation popup handler +var formSubmitObserver = new FormSubmitObserver(content, this); + +addMessageListener("Browser:HideSessionRestoreButton", function (message) { + // Hide session restore button on about:home + let doc = content.document; + let container; + if (doc.documentURI.toLowerCase() == "about:home" && + (container = doc.getElementById("sessionRestoreContainer"))) { + container.hidden = true; + } +}); + +addEventListener("DOMFormHasPassword", function(event) { + LoginManagerContent.onDOMFormHasPassword(event, content); + let formLike = LoginFormFactory.createFromForm(event.target); + InsecurePasswordUtils.reportInsecurePasswords(formLike); +}); +addEventListener("DOMAutoComplete", function(event) { + LoginManagerContent.onUsernameInput(event); +}); +addEventListener("blur", function(event) { + LoginManagerContent.onUsernameInput(event); +}); + +// Provide gContextMenuContentData for 'sdk/context-menu' +var handleContentContextMenu = function (event) { + let defaultPrevented = event.defaultPrevented; + if (!Services.prefs.getBoolPref("dom.event.contextmenu.enabled")) { + let plugin = null; + try { + plugin = event.target.QueryInterface(Ci.nsIObjectLoadingContent); + } catch(e) {} + if (plugin && plugin.displayedType == Ci.nsIObjectLoadingContent.TYPE_PLUGIN) { + // Don't open a context menu for plugins. + return; + } + + defaultPrevented = false; + } + + if (defaultPrevented) { + return; + } + + let addonInfo = {}; + let subject = { + event: event, + addonInfo: addonInfo, + }; + subject.wrappedJSObject = subject; + Services.obs.notifyObservers(subject, "content-contextmenu", null); + + let doc = event.target.ownerDocument; + let docLocation = doc.mozDocumentURIIfNotForErrorPages; + docLocation = docLocation && docLocation.spec; + let charSet = doc.characterSet; + let baseURI = doc.baseURI; + let referrer = doc.referrer; + let referrerPolicy = doc.referrerPolicy; + let frameOuterWindowID = doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .outerWindowID; + let loginFillInfo = LoginManagerContent.getFieldContext(event.target); + + // The same-origin check will be done in nsContextMenu.openLinkInTab. + let parentAllowsMixedContent = !!docShell.mixedContentChannel; + + // get referrer attribute from clicked link and parse it + // if per element referrer is enabled, the element referrer overrules + // the document wide referrer + if (Services.prefs.getBoolPref("network.http.enablePerElementReferrer")) { + let referrerAttrValue = Services.netUtils.parseAttributePolicyString( + event.target.getAttribute("referrerpolicy")); + if (referrerAttrValue !== Ci.nsIHttpChannel.REFERRER_POLICY_UNSET) { + referrerPolicy = referrerAttrValue; + } + } + + // Media related cache info parent needs for saving + let contentType = null; + let contentDisposition = null; + if (event.target.nodeType == Ci.nsIDOMNode.ELEMENT_NODE && + event.target instanceof Ci.nsIImageLoadingContent && + event.target.currentURI) { + + try { + let imageCache = + Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) + .getImgCacheForDocument(doc); + let props = + imageCache.findEntryProperties(event.target.currentURI, doc); + try { + contentType = props.get("type", Ci.nsISupportsCString).data; + } catch(e) {} + try { + contentDisposition = + props.get("content-disposition", Ci.nsISupportsCString).data; + } catch(e) {} + } catch(e) {} + } + + let selectionInfo = BrowserUtils.getSelectionDetails(content); + + let loadContext = docShell.QueryInterface(Ci.nsILoadContext); + + let browser = docShell.chromeEventHandler; + let mainWin = browser.ownerGlobal; + + mainWin.gContextMenuContentData = { + isRemote: false, + event: event, + popupNode: event.target, + browser: browser, + addonInfo: addonInfo, + documentURIObject: doc.documentURIObject, + docLocation: docLocation, + charSet: charSet, + referrer: referrer, + referrerPolicy: referrerPolicy, + contentType: contentType, + contentDisposition: contentDisposition, + selectionInfo: selectionInfo, + loginFillInfo, + parentAllowsMixedContent + }; +} + +Cc["@mozilla.org/eventlistenerservice;1"] + .getService(Ci.nsIEventListenerService) + .addSystemEventListener(global, "contextmenu", handleContentContextMenu, false); + +// Lazily load the finder code +addMessageListener("Finder:Initialize", function() { + let {RemoteFinderListener} = Cu.import("resource://gre/modules/RemoteFinder.jsm", {}); + new RemoteFinderListener(global); +}); + +addEventListener("DOMWebNotificationClicked", function(event) { + sendAsyncMessage("DOMWebNotificationClicked", {}); +}, false); |