author | Dorel Luca <dluca@mozilla.com> |
Thu, 14 Nov 2019 19:14:27 +0200 | |
changeset 501928 | 173de3ea2a270d6dd2c117a291460093d4c168ec |
parent 501927 | a19a226a8c6aa2cb57765c13752057d42a177df9 |
child 501990 | 0fb79a3edf1bddd8532e6d98e7b0531b5155a6e4 |
push id | 36802 |
push user | dvarga@mozilla.com |
push date | Thu, 14 Nov 2019 17:36:16 +0000 |
treeherder | mozilla-central@173de3ea2a27 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | backout |
bugs | 1595155 |
milestone | 72.0a1 |
backs out | c4ff245706aba8e0dcbcabfadaf4cb752500b9c6 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/actors/ClickHandlerChild.jsm +++ b/browser/actors/ClickHandlerChild.jsm @@ -1,15 +1,18 @@ /* -*- indent-tabs-mode: nil; js-indent-level: 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 EXPORTED_SYMBOLS = ["ClickHandlerChild"]; +const { ActorChild } = ChromeUtils.import( + "resource://gre/modules/ActorChild.jsm" +); const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter( this, "BrowserUtils", "resource://gre/modules/BrowserUtils.jsm" ); ChromeUtils.defineModuleGetter( @@ -23,17 +26,17 @@ ChromeUtils.defineModuleGetter( "resource://gre/modules/WebNavigationFrames.jsm" ); ChromeUtils.defineModuleGetter( this, "E10SUtils", "resource://gre/modules/E10SUtils.jsm" ); -class ClickHandlerChild extends JSWindowActorChild { +class ClickHandlerChild extends ActorChild { handleEvent(event) { if ( !event.isTrusted || event.defaultPrevented || event.button == 2 || (event.type == "click" && event.button == 1) ) { return; @@ -114,17 +117,17 @@ class ClickHandlerChild extends JSWindow json.title = node.getAttribute("title"); } // Check if the link needs to be opened with mixed content allowed. // Only when the owner doc has |mixedContentChannel| and the same origin // should we allow mixed content. json.allowMixedContent = false; let docshell = ownerDoc.defaultView.docShell; - if (this.docShell.mixedContentChannel) { + if (this.mm.docShell.mixedContentChannel) { const sm = Services.scriptSecurityManager; try { let targetURI = Services.io.newURI(href); let isPrivateWin = ownerDoc.nodePrincipal.originAttributes.privateBrowsingId > 0; sm.checkSameOriginURI( docshell.mixedContentChannel.URI, targetURI, @@ -143,39 +146,39 @@ class ClickHandlerChild extends JSWindow // when it's clicked with middle button, we should prevent multiple // actions here to avoid leaking clipboard content unexpectedly. // Note that whether the link will work actually or not does not matter // because in this case, user does not intent to paste clipboard content. if (event.button === 1) { event.preventMultipleActions(); } - this.sendAsyncMessage("Content:Click", json); + this.mm.sendAsyncMessage("Content:Click", json); return; } // This might be middle mouse navigation. if (event.button == 1) { - this.sendAsyncMessage("Content:Click", json); + this.mm.sendAsyncMessage("Content:Click", json); } } /** * Extracts linkNode and href for the current click target. * * @param event * The click event. * @return [href, linkNode, linkPrincipal]. * * @note linkNode will be null if the click wasn't on an anchor * element. This includes SVG links, because callers expect |node| * to behave like an <a> element, which SVG links (XLink) don't. */ _hrefAndLinkNodeForClickEvent(event) { - let content = this.contentWindow; + let { content } = this.mm; function isHTMLLink(aNode) { // Be consistent with what nsContextMenu.js does. return ( (aNode instanceof content.HTMLAnchorElement && aNode.href) || (aNode instanceof content.HTMLAreaElement && aNode.href) || aNode instanceof content.HTMLLinkElement ); }
--- a/browser/actors/moz.build +++ b/browser/actors/moz.build @@ -23,17 +23,16 @@ with Files("WebRTCChild.jsm"): BUG_COMPONENT = ("Firefox", "Site Permissions") FINAL_TARGET_FILES.actors += [ 'AboutReaderChild.jsm', 'BlockedSiteChild.jsm', 'BrowserTabChild.jsm', 'BrowserTabParent.jsm', 'ClickHandlerChild.jsm', - 'ClickHandlerParent.jsm', 'ContentMetaChild.jsm', 'ContentMetaParent.jsm', 'ContentSearchChild.jsm', 'ContextMenuChild.jsm', 'ContextMenuParent.jsm', 'DOMFullscreenChild.jsm', 'DOMFullscreenParent.jsm', 'FormValidationChild.jsm',
--- a/browser/base/content/test/general/browser_contentAltClick.js +++ b/browser/base/content/test/general/browser_contentAltClick.js @@ -3,17 +3,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * Test for Bug 1109146. * The tests opens a new tab and alt + clicks to download files * and confirms those files are on the download list. * * The difference between this and the test "browser_contentAreaClick.js" is that - * the code path in e10s uses the ClickHandler actor instead of browser.js::contentAreaClick() util. + * the code path in e10s uses ContentClick.jsm instead of browser.js::contentAreaClick() util. */ "use strict"; ChromeUtils.defineModuleGetter( this, "Downloads", "resource://gre/modules/Downloads.jsm" ); @@ -21,18 +21,17 @@ ChromeUtils.defineModuleGetter( function setup() { Services.prefs.setBoolPref("browser.altClickSave", true); let testPage = "data:text/html," + '<p><a id="commonlink" href="http://mochi.test/moz/">Common 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><br>' + - '<span id="host"></span><script>document.getElementById("host").attachShadow({mode: "closed"}).appendChild(document.getElementById("commonlink").cloneNode(true));</script>' + - '<iframe id="frame" src="https://test2.example.com:443/browser/browser/base/content/test/general/file_with_link_to_http.html"></iframe>'; + '<span id="host"></span><script>document.getElementById("host").attachShadow({mode: "closed"}).appendChild(document.getElementById("commonlink").cloneNode(true));</script>'; return BrowserTestUtils.openNewForegroundTab(gBrowser, testPage); } async function clean_up() { // Remove downloads. let downloadList = await Downloads.getList(Downloads.ALL); let downloads = await downloadList.getAll(); @@ -161,46 +160,8 @@ add_task(async function test_alt_click_o is( downloads[1].source.url, "http://mochi.test/moz/", "Downloaded #svgxlink element" ); await clean_up(); }); - -// Alt+Click a link in a frame from another domain as the outer document. -add_task(async function test_alt_click_in_frame() { - await setup(); - - let downloadList = await Downloads.getList(Downloads.ALL); - let downloads = []; - let downloadView; - // When the download has been attempted, resolve the promise. - let finishedAllDownloads = new Promise(resolve => { - downloadView = { - onDownloadAdded(aDownload) { - downloads.push(aDownload); - resolve(); - }, - }; - }); - - await downloadList.addView(downloadView); - await BrowserTestUtils.synthesizeMouseAtCenter( - "#linkToExample", - { altKey: true }, - gBrowser.selectedBrowser.browsingContext.getChildren()[0] - ); - - // Wait for all downloads to be added to the download list. - await finishedAllDownloads; - await downloadList.removeView(downloadView); - - is(downloads.length, 1, "1 downloads"); - is( - downloads[0].source.url, - "http://example.org/", - "Downloaded link in iframe." - ); - - await clean_up(); -});
--- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -52,31 +52,16 @@ let ACTORS = { DOMWindowCreated: {}, MozAfterPaint: {}, "MozDOMPointerLock:Entered": {}, "MozDOMPointerLock:Exited": {}, }, }, }, - ClickHandler: { - parent: { - moduleURI: "resource:///actors/ClickHandlerParent.jsm", - }, - child: { - moduleURI: "resource:///actors/ClickHandlerChild.jsm", - events: { - click: { capture: true, mozSystemGroup: true }, - auxclick: { capture: true, mozSystemGroup: true }, - }, - }, - - allFrames: true, - }, - // Collects description and icon information from meta tags. ContentMeta: { parent: { moduleURI: "resource:///actors/ContentMetaParent.jsm", }, child: { moduleURI: "resource:///actors/ContentMetaChild.jsm", @@ -323,16 +308,26 @@ let LEGACY_ACTORS = { click: {}, }, matches: ["about:blocked?*"], allFrames: true, messages: ["DeceptiveBlockedDetails"], }, }, + ClickHandler: { + child: { + module: "resource:///actors/ClickHandlerChild.jsm", + events: { + click: { capture: true, mozSystemGroup: true }, + auxclick: { capture: true, mozSystemGroup: true }, + }, + }, + }, + ContentSearch: { child: { module: "resource:///actors/ContentSearchChild.jsm", group: "browsers", matches: [ "about:home", "about:newtab", "about:welcome", @@ -567,16 +562,17 @@ XPCOMUtils.defineLazyModuleGetters(this, WebChannel: "resource://gre/modules/WebChannel.jsm", WindowsRegistry: "resource://gre/modules/WindowsRegistry.jsm", }); // eslint-disable-next-line no-unused-vars XPCOMUtils.defineLazyModuleGetters(this, { AboutLoginsParent: "resource:///modules/AboutLoginsParent.jsm", AsyncPrefs: "resource://gre/modules/AsyncPrefs.jsm", + ContentClick: "resource:///modules/ContentClick.jsm", PluginManager: "resource:///actors/PluginParent.jsm", ReaderParent: "resource:///modules/ReaderParent.jsm", }); /** * IF YOU ADD OR REMOVE FROM THIS LIST, PLEASE UPDATE THE LIST ABOVE AS WELL. * XXX Bug 1325373 is for making eslint detect these automatically. */ @@ -665,16 +661,17 @@ const listeners = { "AboutLogins:OpenMobileAndroid": ["AboutLoginsParent"], "AboutLogins:OpenMobileIos": ["AboutLoginsParent"], "AboutLogins:OpenSite": ["AboutLoginsParent"], "AboutLogins:SortChanged": ["AboutLoginsParent"], "AboutLogins:Subscribe": ["AboutLoginsParent"], "AboutLogins:SyncEnable": ["AboutLoginsParent"], "AboutLogins:SyncOptions": ["AboutLoginsParent"], "AboutLogins:UpdateLogin": ["AboutLoginsParent"], + "Content:Click": ["ContentClick"], ContentSearch: ["ContentSearch"], "Reader:FaviconRequest": ["ReaderParent"], "Reader:UpdateReaderButton": ["ReaderParent"], "rtcpeer:CancelRequest": ["webrtcUI"], "rtcpeer:Request": ["webrtcUI"], "webrtc:CancelRequest": ["webrtcUI"], "webrtc:Request": ["webrtcUI"], "webrtc:StopRecording": ["webrtcUI"],
rename from browser/actors/ClickHandlerParent.jsm rename to browser/modules/ContentClick.jsm --- a/browser/actors/ClickHandlerParent.jsm +++ b/browser/modules/ContentClick.jsm @@ -1,16 +1,16 @@ /* -*- mode: js; indent-tabs-mode: nil; js-indent-level: 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/. */ "use strict"; -var EXPORTED_SYMBOLS = ["ClickHandlerParent"]; +var EXPORTED_SYMBOLS = ["ContentClick"]; const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter( this, "PlacesUIUtils", "resource:///modules/PlacesUIUtils.jsm" ); @@ -20,58 +20,44 @@ ChromeUtils.defineModuleGetter( "resource://gre/modules/PrivateBrowsingUtils.jsm" ); ChromeUtils.defineModuleGetter( this, "E10SUtils", "resource://gre/modules/E10SUtils.jsm" ); -let gContentClickListeners = new Set(); - -class ClickHandlerParent extends JSWindowActorParent { - static addContentClickListener(listener) { - gContentClickListeners.add(listener); - } - - static removeContentClickListener(listener) { - gContentClickListeners.delete(listener); - } - +var ContentClick = { + // Listeners are added in BrowserGlue.jsm receiveMessage(message) { switch (message.name) { case "Content:Click": - this.contentAreaClick(message.data); - this.notifyClickListeners(message.data); + this.contentAreaClick(message.json, message.target); break; } - } + }, /** * Handles clicks in the content area. * - * @param data {Object} object that looks like an Event + * @param json {Object} JSON object that looks like an Event * @param browser {Element<browser>} */ - contentAreaClick(data) { + contentAreaClick(json, browser) { // This is heavily based on contentAreaClick from browser.js (Bug 903016) - // The data is set up in a way to look like an Event. - let browser = this.manager.browsingContext.top.embedderElement; - if (browser.outerBrowser) { - browser = browser.outerBrowser; // handle RDM mode - } + // The json is set up in a way to look like an Event. let window = browser.ownerGlobal; - if (!data.href) { + if (!json.href) { // Might be middle mouse navigation. if ( Services.prefs.getBoolPref("middlemouse.contentLoadURL") && !Services.prefs.getBoolPref("general.autoScroll") ) { - window.middleMousePaste(data); + window.middleMousePaste(json); } return; } // If the browser is not in a place where we can open links, bail out. // This can happen in osx sheets, dialogs, etc. that are not browser // windows. Specifically the payments UI is in an osx sheet. if (window.openLinkIn === undefined) { @@ -79,59 +65,44 @@ class ClickHandlerParent extends JSWindo } // 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 { if (!PrivateBrowsingUtils.isWindowPrivate(window)) { - PlacesUIUtils.markPageAsFollowedLink(data.href); + PlacesUIUtils.markPageAsFollowedLink(json.href); } } catch (ex) { /* Skip invalid URIs. */ } // This part is based on handleLinkClick. - var where = window.whereToOpenLink(data); + var where = window.whereToOpenLink(json); if (where == "current") { return; } // Todo(903022): code for where == save let params = { charset: browser.characterSet, - referrerInfo: E10SUtils.deserializeReferrerInfo(data.referrerInfo), - allowMixedContent: data.allowMixedContent, - isContentWindowPrivate: data.isContentWindowPrivate, - originPrincipal: data.originPrincipal, - originStoragePrincipal: data.originStoragePrincipal, - triggeringPrincipal: data.triggeringPrincipal, - csp: data.csp ? E10SUtils.deserializeCSP(data.csp) : null, - frameOuterWindowID: data.frameOuterWindowID, + referrerInfo: E10SUtils.deserializeReferrerInfo(json.referrerInfo), + allowMixedContent: json.allowMixedContent, + isContentWindowPrivate: json.isContentWindowPrivate, + originPrincipal: json.originPrincipal, + originStoragePrincipal: json.originStoragePrincipal, + triggeringPrincipal: json.triggeringPrincipal, + csp: json.csp ? E10SUtils.deserializeCSP(json.csp) : null, + frameOuterWindowID: json.frameOuterWindowID, }; // The new tab/window must use the same userContextId. - if (data.originAttributes.userContextId) { - params.userContextId = data.originAttributes.userContextId; + if (json.originAttributes.userContextId) { + params.userContextId = json.originAttributes.userContextId; } params.allowInheritPrincipal = true; - window.openLinkIn(data.href, where, params); - } - - notifyClickListeners(data) { - for (let listener of gContentClickListeners) { - try { - let browser = this.browsingContext.top.embedderElement; - if (browser.outerBrowser) { - browser = browser.outerBrowser; // Special-case responsive design mode - } - - listener.onContentClick(browser, data); - } catch (ex) { - Cu.reportError(ex); - } - } - } -} + window.openLinkIn(json.href, where, params); + }, +};
--- a/browser/modules/moz.build +++ b/browser/modules/moz.build @@ -131,16 +131,17 @@ BROWSER_CHROME_MANIFESTS += [ ] XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini'] EXTRA_JS_MODULES += [ 'AboutNewTab.jsm', 'AsyncTabSwitcher.jsm', 'BrowserUsageTelemetry.jsm', 'BrowserWindowTracker.jsm', + 'ContentClick.jsm', 'ContentCrashHandlers.jsm', 'ContentObservers.js', 'ContentSearch.jsm', 'Discovery.jsm', 'EveryWindow.jsm', 'ExtensionsUI.jsm', 'FaviconLoader.jsm', 'HomePage.jsm',
--- a/devtools/client/responsive/browser/tunnel.js +++ b/devtools/client/responsive/browser/tunnel.js @@ -42,16 +42,20 @@ const SWAPPED_BROWSER_STATE = [ * When RDM is enabled, these bits of code instead reach the RDM tool's window instead of * the browser window, which won't have the properties they are looking for. At the * moment, we address this by exposing them from the browser window on RDM's window as * needed. */ const PROPERTIES_FROM_BROWSER_WINDOW = [ // This is used by PermissionUI.jsm for permission doorhangers. "PopupNotifications", + // These are used by ContentClick.jsm when opening links in ways other than just + // navigating the viewport, such as a new tab by pressing Cmd-Click. + "whereToOpenLink", + "openLinkIn", // This is used by various event handlers, typically to call `getTabForBrowser` to map // a browser back to a tab. "gBrowser", ]; /** * This module takes an "outer" <xul:browser> from a browser tab as described by * Firefox's tabbrowser.xml and wires it up to an "inner" <iframe mozbrowser>
--- a/toolkit/components/extensions/WebNavigation.jsm +++ b/toolkit/components/extensions/WebNavigation.jsm @@ -18,21 +18,16 @@ ChromeUtils.defineModuleGetter( "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm" ); ChromeUtils.defineModuleGetter( this, "UrlbarUtils", "resource:///modules/UrlbarUtils.jsm" ); -ChromeUtils.defineModuleGetter( - this, - "ClickHandlerParent", - "resource:///actors/ClickHandlerParent.jsm" -); // Maximum amount of time that can be passed and still consider // the data recent (similar to how is done in nsNavHistory, // e.g. nsNavHistory::CheckIsRecentEvent, but with a lower threshold value). const RECENT_DATA_THRESHOLD = 5 * 1000000; var Manager = { // Map[string -> Map[listener -> URLFilter]] @@ -47,18 +42,17 @@ var Manager = { // pair the message received from the source tab to the one received from // the new tab. this.createdNavigationTargetByOuterWindowId = new Map(); Services.obs.addObserver(this, "urlbar-user-start-navigation", true); Services.obs.addObserver(this, "webNavigation-createdNavigationTarget"); - ClickHandlerParent.addContentClickListener(this); - + Services.mm.addMessageListener("Content:Click", this); Services.mm.addMessageListener("Extension:DOMContentLoaded", this); Services.mm.addMessageListener("Extension:StateChange", this); Services.mm.addMessageListener("Extension:DocumentChange", this); Services.mm.addMessageListener("Extension:HistoryChange", this); Services.mm.addMessageListener("Extension:CreatedNavigationTarget", this); Services.mm.loadFrameScript( "resource://gre/modules/WebNavigationContent.js", @@ -66,18 +60,17 @@ var Manager = { ); }, uninit() { // Stop collecting recent tab transition data and reset the WeakMap. Services.obs.removeObserver(this, "urlbar-user-start-navigation"); Services.obs.removeObserver(this, "webNavigation-createdNavigationTarget"); - ClickHandlerParent.removeContentClickListener(this); - + Services.mm.removeMessageListener("Content:Click", this); Services.mm.removeMessageListener("Extension:StateChange", this); Services.mm.removeMessageListener("Extension:DocumentChange", this); Services.mm.removeMessageListener("Extension:HistoryChange", this); Services.mm.removeMessageListener("Extension:DOMContentLoaded", this); Services.mm.removeMessageListener( "Extension:CreatedNavigationTarget", this ); @@ -307,16 +300,20 @@ var Manager = { case "Extension:HistoryChange": this.onHistoryChange(target, data); break; case "Extension:DOMContentLoaded": this.onLoad(target, data); break; + case "Content:Click": + this.onContentClick(target, data); + break; + case "Extension:CreatedNavigationTarget": this.onCreatedNavigationTarget(target, data); break; } }, onContentClick(target, data) { // We are interested only on clicks to links which are not "add to bookmark" commands