author | Mark Banner <standard8@mozilla.com> |
Fri, 01 Apr 2016 13:54:08 +0100 | |
changeset 292109 | 1725b460c3e0de97590cb8764df9ace9115b813e |
parent 292108 | 163ec1ec0f25e482a9c5156581887744f1f3fbb7 |
child 292110 | 91fd28b61badff20e75856f09fc2eb84bb537570 |
push id | 74762 |
push user | cbook@mozilla.com |
push date | Thu, 07 Apr 2016 09:56:20 +0000 |
treeherder | mozilla-inbound@772253c53374 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mikedeboer |
bugs | 1257154 |
milestone | 48.0a1 |
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/extensions/loop/bootstrap.js +++ b/browser/extensions/loop/bootstrap.js @@ -8,16 +8,19 @@ const { interfaces: Ci, utils: Cu, classes: Cc } = Components; const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const kBrowserSharingNotificationId = "loop-sharing-notification"; const CURSOR_MIN_DELTA = 3; const CURSOR_MIN_INTERVAL = 100; const CURSOR_CLICK_DELAY = 1000; +// Due to bug 1051238 frame scripts are cached forever, so we can't update them +// as a restartless add-on. The Math.random() is the work around for this. +const FRAME_SCRIPT = "chrome://loop/content/modules/tabFrame.js?" + Math.random(); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/AppConstants.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI", @@ -52,16 +55,17 @@ var WindowListener = { */ setupBrowserUI: function(window) { let document = window.document; let gBrowser = window.gBrowser; let xhrClass = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]; let FileReader = window.FileReader; let menuItem = null; let isSlideshowOpen = false; + let titleChangedListener = null; // the "exported" symbols var LoopUI = { /** * @var {XULWidgetSingleWrapper} toolbarButton Getter for the Loop toolbarbutton * instance for this window. This should * not be used in the hidden window. */ @@ -110,16 +114,20 @@ var WindowListener = { }, result => { this._constants = result; }); } return this._constants; }, + get mm() { + return window.getGroupMessageManager("browsers"); + }, + /** * @return {Promise} */ promiseDocumentVisible(aDocument) { if (!aDocument.hidden) { return Promise.resolve(aDocument); } @@ -308,16 +316,20 @@ var WindowListener = { this.addMenuItem(); // Don't do the rest if this is for the hidden window - we don't // have a toolbar there. if (window == Services.appShell.hiddenDOMWindow) { return; } + // Load the frame script into any tab, plus any that get created in the + // future. + this.mm.loadFrameScript(FRAME_SCRIPT, true); + // Cleanup when the window unloads. window.addEventListener("unload", () => { Services.obs.removeObserver(this, "loop-status-changed"); }); Services.obs.addObserver(this, "loop-status-changed", false); this.updateToolbarState(); @@ -517,19 +529,23 @@ var WindowListener = { * Push message parameters: * - {Integer} windowId The new windowId for the browser. */ startBrowserSharing: function() { if (!this._listeningToTabSelect) { gBrowser.tabContainer.addEventListener("TabSelect", this); this._listeningToTabSelect = true; + titleChangedListener = this.handleDOMTitleChanged.bind(this); + // Watch for title changes as opposed to location changes as more // metadata about the page is available when this event fires. - gBrowser.addEventListener("DOMTitleChanged", this); + this.mm.addMessageListener("loop@mozilla.org:DOMTitleChanged", + titleChangedListener); + this._browserSharePaused = false; // Add this event to the parent gBrowser to avoid adding and removing // it for each individual tab's browsers. gBrowser.addEventListener("mousemove", this); gBrowser.addEventListener("click", this); } @@ -556,17 +572,22 @@ var WindowListener = { */ stopBrowserSharing: function() { if (!this._listeningToTabSelect) { return; } this._hideBrowserSharingInfoBar(); gBrowser.tabContainer.removeEventListener("TabSelect", this); - gBrowser.removeEventListener("DOMTitleChanged", this); + + if (titleChangedListener) { + this.mm.removeMessageListener("loop@mozilla.org:DOMTitleChanged", + titleChangedListener); + titleChangedListener = null; + } // Remove shared pointers related events gBrowser.removeEventListener("mousemove", this); gBrowser.removeEventListener("click", this); this.removeRemoteCursor(); this._listeningToTabSelect = false; this._browserSharePaused = false; @@ -795,24 +816,36 @@ var WindowListener = { */ _notifyBrowserSwitch: function() { // Get the first window Id for the listener. this.LoopAPI.broadcastPushMessage("BrowserSwitch", gBrowser.selectedBrowser.outerWindowID); }, /** + * Handles events from the frame script. + * + * @param {Object} message The message received from the frame script. + */ + handleDOMTitleChanged: function(message) { + if (!this._listeningToTabSelect || this._browserSharePaused) { + return; + } + + if (gBrowser.selectedBrowser == message.target) { + // Get the new title of the shared tab + this._notifyBrowserSwitch(); + } + }, + + /** * Handles events from gBrowser. */ handleEvent: function(event) { switch (event.type) { - case "DOMTitleChanged": - // Get the new title of the shared tab - this._notifyBrowserSwitch(); - break; case "TabSelect": let wasVisible = false; // Hide the infobar from the previous tab. if (event.detail.previousTab) { wasVisible = this._hideBrowserSharingInfoBar( event.detail.previousTab.linkedBrowser); // And remove the cursor. this.removeRemoteCursor(); @@ -945,16 +978,20 @@ var WindowListener = { * document.getElementById() etc. will work here. * * @param {Object} window The window to remove the integration from. */ tearDownBrowserUI: function(window) { if (window.LoopUI) { window.LoopUI.removeMenuItem(); + // This stops the frame script being loaded to new tabs, but doesn't + // remove it from existing tabs (there's no way to do that). + window.LoopUI.mm.removeDelayedFrameScript(FRAME_SCRIPT); + // XXX Bug 1229352 - Add in tear-down of the panel. } }, // nsIWindowMediatorListener functions. onOpenWindow: function(xulWindow) { // A new window has opened. let domWindow = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
new file mode 100644 --- /dev/null +++ b/browser/extensions/loop/chrome/content/modules/tabFrame.js @@ -0,0 +1,22 @@ +/* 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"; + +/* global sendAsyncMessage */ + +/** + * This script runs in the content process and is attached to browsers when + * they are created. + */ + +// Listen for when the title is changed and send a message back to the chrome +// process. +addEventListener("DOMTitleChanged", ({ target }) => { + sendAsyncMessage("loop@mozilla.org:DOMTitleChanged", { + details: "titleChanged" + }, { + target: target + }); +});
--- a/browser/extensions/loop/chrome/test/mochitest/browser.ini +++ b/browser/extensions/loop/chrome/test/mochitest/browser.ini @@ -10,9 +10,10 @@ support-files = [browser_LoopRooms_channel.js] [browser_menuitem.js] [browser_mozLoop_appVersionInfo.js] [browser_mozLoop_chat.js] [browser_mozLoop_context.js] [browser_mozLoop_socialShare.js] [browser_mozLoop_sharingListeners.js] [browser_mozLoop_telemetry.js] +[browser_sharingTitleListeners.js] [browser_toolbarbutton.js]
new file mode 100644 --- /dev/null +++ b/browser/extensions/loop/chrome/test/mochitest/browser_sharingTitleListeners.js @@ -0,0 +1,51 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* + * This file contains tests for the browser sharing document title listeners. + */ +"use strict"; + +var [, gHandlers] = LoopAPI.inspect(); + +function promiseBrowserSwitch() { + return new Promise(resolve => { + LoopAPI.stub([{ + sendAsyncMessage: function(messageName, data) { + if (data[0] == "BrowserSwitch") { + LoopAPI.restore(); + resolve(); + } + } + }]); + }); +} + +add_task(function* setup() { + Services.prefs.setBoolPref("loop.remote.autostart", true); + + gHandlers.AddBrowserSharingListener({ data: [42] }, () => {}); + + let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", true); + + registerCleanupFunction(function* () { + // Remove the listener. + gHandlers.RemoveBrowserSharingListener({ data: [42] }, function() {}); + + yield BrowserTestUtils.removeTab(newTab); + + Services.prefs.clearUserPref("loop.remote.autostart"); + }); +}); + +add_task(function* test_notifyOnTitleChanged() { + // Hook up the async listener and wait for the BrowserSwitch to happen. + let browserSwitchPromise = promiseBrowserSwitch(); + + BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:mozilla"); + + // Now check we get the notification of the browser switch. + yield browserSwitchPromise; + + Assert.ok(true, "We got notification of the browser switch"); +});