diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 7f4706d710bb..ce8432090a31 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -312,8 +312,8 @@ BrowserGlue.prototype = { case "fxaccounts:device_disconnected": this._onDeviceDisconnected(); break; - case "weave:engine:clients:display-uris": - this._onDisplaySyncURIs(subject); + case "weave:engine:clients:display-uri": + this._onDisplaySyncURI(subject); break; case "session-save": this._setPrefToSaveSession(true); @@ -531,7 +531,7 @@ BrowserGlue.prototype = { os.addObserver(this, "weave:service:ready", false); os.addObserver(this, "fxaccounts:onverified", false); os.addObserver(this, "fxaccounts:device_disconnected", false); - os.addObserver(this, "weave:engine:clients:display-uris", false); + os.addObserver(this, "weave:engine:clients:display-uri", false); os.addObserver(this, "session-save", false); os.addObserver(this, "places-init-complete", false); this._isPlacesInitObserver = true; @@ -577,7 +577,7 @@ BrowserGlue.prototype = { os.removeObserver(this, "weave:service:ready"); os.removeObserver(this, "fxaccounts:onverified"); os.removeObserver(this, "fxaccounts:device_disconnected"); - os.removeObserver(this, "weave:engine:clients:display-uris"); + os.removeObserver(this, "weave:engine:clients:display-uri"); os.removeObserver(this, "session-save"); if (this._bookmarksBackupIdleTime) { this._idleService.removeIdleObserver(this, this._bookmarksBackupIdleTime); @@ -2410,59 +2410,24 @@ BrowserGlue.prototype = { }, /** - * Called as an observer when Sync's "display URIs" notification is fired. + * Called as an observer when Sync's "display URI" notification is fired. * - * We open the received URIs in background tabs. + * We open the received URI in a background tab. + * + * Eventually, this will likely be replaced by a more robust tab syncing + * feature. This functionality is considered somewhat evil by UX because it + * opens a new tab automatically without any prompting. However, it is a + * lesser evil than sending a tab to a specific device (from e.g. Fennec) + * and having nothing happen on the receiving end. */ - _onDisplaySyncURIs: function _onDisplaySyncURIs(data) { + _onDisplaySyncURI: function _onDisplaySyncURI(data) { try { + let tabbrowser = RecentWindow.getMostRecentBrowserWindow({private: false}).gBrowser; + // The payload is wrapped weirdly because of how Sync does notifications. - const URIs = data.wrappedJSObject.object; - - const findWindow = () => RecentWindow.getMostRecentBrowserWindow({private: false}); - - // win can be null, but it's ok, we'll assign it later in openTab() - let win = findWindow(); - - const openTab = URI => { - let tab; - if (!win) { - Services.appShell.hiddenDOMWindow.open(URI.uri); - win = findWindow(); - tab = win.gBrowser.tabs[0]; - } else { - tab = win.gBrowser.addTab(URI.uri); - } - tab.setAttribute("attention", true); - return tab; - }; - - const firstTab = openTab(URIs[0]); - URIs.slice(1).forEach(URI => openTab(URI)); - - let title, body; - const deviceName = Weave.Service.clientsEngine.getClientName(URIs[0].clientId); - const bundle = Services.strings.createBundle("chrome://browser/locale/accounts.properties"); - if (URIs.length == 1) { - title = bundle.GetStringFromName("tabArrivingNotification.title"); - const pageTitle = URIs[0].title || firstTab.linkedBrowser.contentTitle - || URIs[0].uri; - body = bundle.formatStringFromName("tabArrivingNotification.body", [pageTitle, deviceName], 2); - } else { - title = bundle.GetStringFromName("tabsArrivingNotification.title"); - const tabArrivingBody = URIs.every(URI => URI.clientId == URIs[0].clientId) ? - "tabsArrivingNotification.body" : "tabsArrivingNotificationMultiple.body"; - body = bundle.formatStringFromName(tabArrivingBody, [URIs.length, deviceName], 2); - } - - const clickCallback = (subject, topic, data) => { - if (topic == "alertclickcallback") { - win.gBrowser.selectedTab = firstTab; - } - } - AlertsService.showAlertNotification(null, title, body, true, null, clickCallback); + tabbrowser.addTab(data.wrappedJSObject.object.uri); } catch (ex) { - Cu.reportError("Error displaying tab(s) received by Sync: " + ex); + Cu.reportError("Error displaying tab received by Sync: " + ex); } }, diff --git a/browser/locales/en-US/chrome/browser/accounts.properties b/browser/locales/en-US/chrome/browser/accounts.properties index a08b7b8e6c78..99b29f3213a8 100644 --- a/browser/locales/en-US/chrome/browser/accounts.properties +++ b/browser/locales/en-US/chrome/browser/accounts.properties @@ -34,21 +34,6 @@ syncStartNotification.body = Firefox will begin syncing momentarily. deviceDisconnectedNotification.title = Sync disconnected deviceDisconnectedNotification.body = This computer has been successfully disconnected from Firefox Sync. -# LOCALIZATION NOTE (tabArrivingNotification.title, tabArrivingNotification.body, -# tabsArrivingNotification.title, tabsArrivingNotification.body) -# These strings are used in a notification shown when we're opening tab(s) another device sent us to display. -tabArrivingNotification.title = Tab received -# LOCALIZATION NOTE (tabArrivingNotification.body) %1 is the title of the tab and %2 is the device name. -tabArrivingNotification.body = "%1$S" has arrived from %2$S. - -tabsArrivingNotification.title = Multiple tabs received -# LOCALIZATION NOTE (tabsArrivingNotification.body) %1 is the number of tabs received and %2 is the device name. -tabsArrivingNotification.body = %1$S tabs have arrived from %2$S. -# LOCALIZATION NOTE (tabsArrivingNotificationMultiple.body) -# This string is used in a notification shown when we're opening tab(s) that several devices sent us to display. -# %S is the number of tabs received -tabsArrivingNotificationMultiple.body = %S tabs have arrived from your connected devices. - # LOCALIZATION NOTE (sendTabToAllDevices.menuitem) # Displayed in the Send Tabs context menu when right clicking a tab, a page or a link. sendTabToAllDevices.menuitem = All Devices diff --git a/services/sync/modules/engines/clients.js b/services/sync/modules/engines/clients.js index d1769d58d5b1..316116fcbafe 100644 --- a/services/sync/modules/engines/clients.js +++ b/services/sync/modules/engines/clients.js @@ -383,7 +383,6 @@ ClientEngine.prototype = { if (!commands) { return true; } - let URIsToDisplay = []; for (let key in commands) { let {command, args} = commands[key]; this._log.debug("Processing command: " + command + "(" + args + ")"); @@ -406,17 +405,13 @@ ClientEngine.prototype = { this.service.logout(); return false; case "displayURI": - let [uri, clientId, title] = args; - URIsToDisplay.push({ uri, clientId, title }); + this._handleDisplayURI.apply(this, args); break; default: this._log.debug("Received an unknown command: " + command); break; } } - if (URIsToDisplay.length) { - this._handleDisplayURIs(URIsToDisplay); - } return true; })(); @@ -486,11 +481,11 @@ ClientEngine.prototype = { }, /** - * Handle a bunch of received 'displayURI' commands. + * Handle a single received 'displayURI' command. * - * Interested parties should observe the "weave:engine:clients:display-uris" - * topic. The callback will receive an array as the subject parameter - * containing objects with the following keys: + * Interested parties should observe the "weave:engine:clients:display-uri" + * topic. The callback will receive an object as the subject parameter with + * the following keys: * * uri URI (string) that is requested for display. * clientId ID of client that sent the command. @@ -498,18 +493,20 @@ ClientEngine.prototype = { * * The 'data' parameter to the callback will not be defined. * - * @param uris - * An array containing URI objects to display - * @param uris[].uri + * @param uri * String URI that was received - * @param uris[].clientId + * @param clientId * ID of client that sent URI - * @param uris[].title + * @param title * String title of page that URI corresponds to. Older clients may not * send this. */ - _handleDisplayURIs: function _handleDisplayURIs(uris) { - Svc.Obs.notify("weave:engine:clients:display-uris", uris); + _handleDisplayURI: function _handleDisplayURI(uri, clientId, title) { + this._log.info("Received a URI for display: " + uri + " (" + title + + ") from " + clientId); + + let subject = {uri: uri, client: clientId, title: title}; + Svc.Obs.notify("weave:engine:clients:display-uri", subject); }, _removeRemoteClient(id) {