diff options
Diffstat (limited to 'application/basilisk')
92 files changed, 1127 insertions, 5848 deletions
diff --git a/application/basilisk/base/content/aboutaccounts/aboutaccounts.css b/application/basilisk/base/content/aboutaccounts/aboutaccounts.css deleted file mode 100644 index a2c5cb8f0..000000000 --- a/application/basilisk/base/content/aboutaccounts/aboutaccounts.css +++ /dev/null @@ -1,24 +0,0 @@ -html, body { - height: 100%; -} - -#remote { - width: 100%; - height: 100%; - border: 0; - display: none; -} - -#networkError, #manage, #intro, #stage, #configError { - display: none; -} - -#oldsync { - background: none; - border: 0; - color: #0095dd; -} - -#oldsync:focus { - outline: 1px dotted #0095dd; -} diff --git a/application/basilisk/base/content/aboutaccounts/aboutaccounts.js b/application/basilisk/base/content/aboutaccounts/aboutaccounts.js deleted file mode 100644 index a05c1ea75..000000000 --- a/application/basilisk/base/content/aboutaccounts/aboutaccounts.js +++ /dev/null @@ -1,543 +0,0 @@ -/* 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 {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/FxAccounts.jsm"); - -var fxAccountsCommon = {}; -Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon); - -// for master-password utilities -Cu.import("resource://services-sync/util.js"); - -const PREF_LAST_FXA_USER = "identity.fxaccounts.lastSignedInUserHash"; -const PREF_SYNC_SHOW_CUSTOMIZATION = "services.sync-setup.ui.showCustomizationDialog"; - -const ACTION_URL_PARAM = "action"; - -const OBSERVER_TOPICS = [ - fxAccountsCommon.ONVERIFIED_NOTIFICATION, - fxAccountsCommon.ONLOGOUT_NOTIFICATION, -]; - -function log(msg) { - // dump("FXA: " + msg + "\n"); -} - -function error(msg) { - console.log("Firefox Account Error: " + msg + "\n"); -} - -function getPreviousAccountNameHash() { - try { - return Services.prefs.getComplexValue(PREF_LAST_FXA_USER, Ci.nsISupportsString).data; - } catch (_) { - return ""; - } -} - -function setPreviousAccountNameHash(acctName) { - let string = Cc["@mozilla.org/supports-string;1"] - .createInstance(Ci.nsISupportsString); - string.data = sha256(acctName); - Services.prefs.setComplexValue(PREF_LAST_FXA_USER, Ci.nsISupportsString, string); -} - -function needRelinkWarning(acctName) { - let prevAcctHash = getPreviousAccountNameHash(); - return prevAcctHash && prevAcctHash != sha256(acctName); -} - -// Given a string, returns the SHA265 hash in base64 -function sha256(str) { - let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] - .createInstance(Ci.nsIScriptableUnicodeConverter); - converter.charset = "UTF-8"; - // Data is an array of bytes. - let data = converter.convertToByteArray(str, {}); - let hasher = Cc["@mozilla.org/security/hash;1"] - .createInstance(Ci.nsICryptoHash); - hasher.init(hasher.SHA256); - hasher.update(data, data.length); - - return hasher.finish(true); -} - -function promptForRelink(acctName) { - let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); - let continueLabel = sb.GetStringFromName("continue.label"); - let title = sb.GetStringFromName("relinkVerify.title"); - let description = sb.formatStringFromName("relinkVerify.description", - [acctName], 1); - let body = sb.GetStringFromName("relinkVerify.heading") + - "\n\n" + description; - let ps = Services.prompt; - let buttonFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING) + - (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL) + - ps.BUTTON_POS_1_DEFAULT; - let pressed = Services.prompt.confirmEx(window, title, body, buttonFlags, - continueLabel, null, null, null, - {}); - return pressed == 0; // 0 is the "continue" button -} - -// If the last fxa account used for sync isn't this account, we display -// a modal dialog checking they really really want to do this... -// (This is sync-specific, so ideally would be in sync's identity module, -// but it's a little more seamless to do here, and sync is currently the -// only fxa consumer, so... -function shouldAllowRelink(acctName) { - return !needRelinkWarning(acctName) || promptForRelink(acctName); -} - -function updateDisplayedEmail(user) { - let emailDiv = document.getElementById("email"); - if (emailDiv && user) { - emailDiv.textContent = user.email; - } -} - -var wrapper = { - iframe: null, - - init: function (url, urlParams) { - // If a master-password is enabled, we want to encourage the user to - // unlock it. Things still work if not, but the user will probably need - // to re-auth next startup (in which case we will get here again and - // re-prompt) - Utils.ensureMPUnlocked(); - - let iframe = document.getElementById("remote"); - this.iframe = iframe; - this.iframe.QueryInterface(Ci.nsIFrameLoaderOwner); - let docShell = this.iframe.frameLoader.docShell; - docShell.QueryInterface(Ci.nsIWebProgress); - docShell.addProgressListener(this.iframeListener, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); - iframe.addEventListener("load", this); - - // Ideally we'd just merge urlParams with new URL(url).searchParams, but our - // URLSearchParams implementation doesn't support iteration (bug 1085284). - let urlParamStr = urlParams.toString(); - if (urlParamStr) { - url += (url.includes("?") ? "&" : "?") + urlParamStr; - } - this.url = url; - // Set the iframe's location with loadURI/LOAD_FLAGS_REPLACE_HISTORY to - // avoid having a new history entry being added. REPLACE_HISTORY is used - // to replace the current entry, which is `about:blank`. - let webNav = iframe.frameLoader.docShell.QueryInterface(Ci.nsIWebNavigation); - webNav.loadURI(url, Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY, null, null, null); - }, - - retry: function () { - let webNav = this.iframe.frameLoader.docShell.QueryInterface(Ci.nsIWebNavigation); - webNav.loadURI(this.url, Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY, null, null, null); - }, - - iframeListener: { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, - Ci.nsISupportsWeakReference, - Ci.nsISupports]), - - onStateChange: function(aWebProgress, aRequest, aState, aStatus) { - let failure = false; - - // Captive portals sometimes redirect users - if ((aState & Ci.nsIWebProgressListener.STATE_REDIRECTING)) { - failure = true; - } else if ((aState & Ci.nsIWebProgressListener.STATE_STOP)) { - if (aRequest instanceof Ci.nsIHttpChannel) { - try { - failure = aRequest.responseStatus != 200; - } catch (e) { - failure = aStatus != Components.results.NS_OK; - } - } - } - - // Calling cancel() will raise some OnStateChange notifications by itself, - // so avoid doing that more than once - if (failure && aStatus != Components.results.NS_BINDING_ABORTED) { - aRequest.cancel(Components.results.NS_BINDING_ABORTED); - setErrorPage("networkError"); - } - }, - - onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) { - if (aRequest && aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) { - aRequest.cancel(Components.results.NS_BINDING_ABORTED); - setErrorPage("networkError"); - } - }, - - onProgressChange: function() {}, - onStatusChange: function() {}, - onSecurityChange: function() {}, - }, - - handleEvent: function (evt) { - switch (evt.type) { - case "load": - this.iframe.contentWindow.addEventListener("FirefoxAccountsCommand", this); - this.iframe.removeEventListener("load", this); - break; - case "FirefoxAccountsCommand": - this.handleRemoteCommand(evt); - break; - } - }, - - /** - * onLogin handler receives user credentials from the jelly after a - * sucessful login and stores it in the fxaccounts service - * - * @param accountData the user's account data and credentials - */ - onLogin: function (accountData) { - log("Received: 'login'. Data:" + JSON.stringify(accountData)); - - if (accountData.customizeSync) { - Services.prefs.setBoolPref(PREF_SYNC_SHOW_CUSTOMIZATION, true); - } - delete accountData.customizeSync; - // sessionTokenContext is erroneously sent by the content server. - // https://github.com/mozilla/fxa-content-server/issues/2766 - // To avoid having the FxA storage manager not knowing what to do with - // it we delete it here. - delete accountData.sessionTokenContext; - - // We need to confirm a relink - see shouldAllowRelink for more - let newAccountEmail = accountData.email; - // The hosted code may have already checked for the relink situation - // by sending the can_link_account command. If it did, then - // it will indicate we don't need to ask twice. - if (!accountData.verifiedCanLinkAccount && !shouldAllowRelink(newAccountEmail)) { - // we need to tell the page we successfully received the message, but - // then bail without telling fxAccounts - this.injectData("message", { status: "login" }); - // after a successful login we return to preferences - openPrefs(); - return; - } - delete accountData.verifiedCanLinkAccount; - - // Remember who it was so we can log out next time. - setPreviousAccountNameHash(newAccountEmail); - - // A sync-specific hack - we want to ensure sync has been initialized - // before we set the signed-in user. - let xps = Cc["@mozilla.org/weave/service;1"] - .getService(Ci.nsISupports) - .wrappedJSObject; - xps.whenLoaded().then(() => { - updateDisplayedEmail(accountData); - return fxAccounts.setSignedInUser(accountData); - }).then(() => { - // If the user data is verified, we want it to immediately look like - // they are signed in without waiting for messages to bounce around. - if (accountData.verified) { - openPrefs(); - } - this.injectData("message", { status: "login" }); - // until we sort out a better UX, just leave the jelly page in place. - // If the account email is not yet verified, it will tell the user to - // go check their email, but then it will *not* change state after - // the verification completes (the browser will begin syncing, but - // won't notify the user). If the email has already been verified, - // the jelly will say "Welcome! You are successfully signed in as - // EMAIL", but it won't then say "syncing started". - }, (err) => this.injectData("message", { status: "error", error: err }) - ); - }, - - onCanLinkAccount: function(accountData) { - // We need to confirm a relink - see shouldAllowRelink for more - let ok = shouldAllowRelink(accountData.email); - this.injectData("message", { status: "can_link_account", data: { ok: ok } }); - }, - - /** - * onSignOut handler erases the current user's session from the fxaccounts service - */ - onSignOut: function () { - log("Received: 'sign_out'."); - - fxAccounts.signOut().then( - () => this.injectData("message", { status: "sign_out" }), - (err) => this.injectData("message", { status: "error", error: err }) - ); - }, - - handleRemoteCommand: function (evt) { - log('command: ' + evt.detail.command); - let data = evt.detail.data; - - switch (evt.detail.command) { - case "login": - this.onLogin(data); - break; - case "can_link_account": - this.onCanLinkAccount(data); - break; - case "sign_out": - this.onSignOut(data); - break; - default: - log("Unexpected remote command received: " + evt.detail.command + ". Ignoring command."); - break; - } - }, - - injectData: function (type, content) { - return fxAccounts.promiseAccountsSignUpURI().then(authUrl => { - let data = { - type: type, - content: content - }; - this.iframe.contentWindow.postMessage(data, authUrl); - }) - .catch(e => { - console.log("Failed to inject data", e); - setErrorPage("configError"); - }); - }, -}; - - -// Button onclick handlers -function handleOldSync() { - let chromeWin = window - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow) - .QueryInterface(Ci.nsIDOMChromeWindow); - let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "old-sync"; - chromeWin.switchToTabHavingURI(url, true); -} - -function getStarted() { - show("remote"); -} - -function retry() { - show("remote"); - wrapper.retry(); -} - -function openPrefs() { - // Bug 1199303 calls for this tab to always be replaced with Preferences - // rather than it opening in a different tab. - window.location = "about:preferences#sync"; -} - -function init() { - fxAccounts.getSignedInUser().then(user => { - // tests in particular might cause the window to start closing before - // getSignedInUser has returned. - if (window.closed) { - return Promise.resolve(); - } - - updateDisplayedEmail(user); - - // Ideally we'd use new URL(document.URL).searchParams, but for about: URIs, - // searchParams is empty. - let urlParams = new URLSearchParams(document.URL.split("?")[1] || ""); - let action = urlParams.get(ACTION_URL_PARAM); - urlParams.delete(ACTION_URL_PARAM); - - switch (action) { - case "signin": - if (user) { - // asking to sign-in when already signed in just shows manage. - show("stage", "manage"); - } else { - return fxAccounts.promiseAccountsSignInURI().then(url => { - show("remote"); - wrapper.init(url, urlParams); - }); - } - break; - case "signup": - if (user) { - // asking to sign-up when already signed in just shows manage. - show("stage", "manage"); - } else { - return fxAccounts.promiseAccountsSignUpURI().then(url => { - show("remote"); - wrapper.init(url, urlParams); - }); - } - break; - case "reauth": - // ideally we would only show this when we know the user is in a - // "must reauthenticate" state - but we don't. - // As the email address will be included in the URL returned from - // promiseAccountsForceSigninURI, just always show it. - return fxAccounts.promiseAccountsForceSigninURI().then(url => { - show("remote"); - wrapper.init(url, urlParams); - }); - default: - // No action specified. - if (user) { - show("stage", "manage"); - } else { - // Attempt a migration if enabled or show the introductory page - // otherwise. - return migrateToDevEdition(urlParams).then(migrated => { - if (!migrated) { - show("stage", "intro"); - // load the remote frame in the background - return fxAccounts.promiseAccountsSignUpURI().then(uri => - wrapper.init(uri, urlParams)); - } - return Promise.resolve(); - }); - } - break; - } - return Promise.resolve(); - }).catch(err => { - console.log("Configuration or sign in error", err); - setErrorPage("configError"); - }); -} - -function setErrorPage(errorType) { - show("stage", errorType); -} - -// Causes the "top-level" element with |id| to be shown - all other top-level -// elements are hidden. Optionally, ensures that only 1 "second-level" element -// inside the top-level one is shown. -function show(id, childId) { - // top-level items are either <div> or <iframe> - let allTop = document.querySelectorAll("body > div, iframe"); - for (let elt of allTop) { - if (elt.getAttribute("id") == id) { - elt.style.display = 'block'; - } else { - elt.style.display = 'none'; - } - } - if (childId) { - // child items are all <div> - let allSecond = document.querySelectorAll("#" + id + " > div"); - for (let elt of allSecond) { - if (elt.getAttribute("id") == childId) { - elt.style.display = 'block'; - } else { - elt.style.display = 'none'; - } - } - } -} - -// Migrate sync data from the default profile to the dev-edition profile. -// Returns a promise of a true value if migration succeeded, or false if it -// failed. -function migrateToDevEdition(urlParams) { - let defaultProfilePath; - try { - defaultProfilePath = window.getDefaultProfilePath(); - } catch (e) {} // no default profile. - let migrateSyncCreds = false; - if (defaultProfilePath) { - try { - migrateSyncCreds = Services.prefs.getBoolPref("identity.fxaccounts.migrateToDevEdition"); - } catch (e) {} - } - - if (!migrateSyncCreds) { - return Promise.resolve(false); - } - - Cu.import("resource://gre/modules/osfile.jsm"); - let fxAccountsStorage = OS.Path.join(defaultProfilePath, fxAccountsCommon.DEFAULT_STORAGE_FILENAME); - return OS.File.read(fxAccountsStorage, { encoding: "utf-8" }).then(text => { - let accountData = JSON.parse(text).accountData; - updateDisplayedEmail(accountData); - return fxAccounts.setSignedInUser(accountData); - }).then(() => { - return fxAccounts.promiseAccountsForceSigninURI().then(url => { - show("remote"); - wrapper.init(url, urlParams); - }); - }).then(null, error => { - log("Failed to migrate FX Account: " + error); - show("stage", "intro"); - // load the remote frame in the background - fxAccounts.promiseAccountsSignUpURI().then(uri => { - wrapper.init(uri, urlParams) - }).catch(e => { - console.log("Failed to load signup page", e); - setErrorPage("configError"); - }); - }).then(() => { - // Reset the pref after migration. - Services.prefs.setBoolPref("identity.fxaccounts.migrateToDevEdition", false); - return true; - }).then(null, err => { - Cu.reportError("Failed to reset the migrateToDevEdition pref: " + err); - return false; - }); -} - -// Helper function that returns the path of the default profile on disk. Will be -// overridden in tests. -function getDefaultProfilePath() { - let defaultProfile = Cc["@mozilla.org/toolkit/profile-service;1"] - .getService(Ci.nsIToolkitProfileService) - .defaultProfile; - return defaultProfile.rootDir.path; -} - -document.addEventListener("DOMContentLoaded", function onload() { - document.removeEventListener("DOMContentLoaded", onload, true); - init(); - var buttonGetStarted = document.getElementById('buttonGetStarted'); - buttonGetStarted.addEventListener('click', getStarted); - - var buttonRetry = document.getElementById('buttonRetry'); - buttonRetry.addEventListener('click', retry); - - var oldsync = document.getElementById('oldsync'); - oldsync.addEventListener('click', handleOldSync); - - var buttonOpenPrefs = document.getElementById('buttonOpenPrefs') - buttonOpenPrefs.addEventListener('click', openPrefs); -}, true); - -function initObservers() { - function observe(subject, topic, data) { - log("about:accounts observed " + topic); - if (topic == fxAccountsCommon.ONLOGOUT_NOTIFICATION) { - // All about:account windows get changed to action=signin on logout. - window.location = "about:accounts?action=signin"; - return; - } - - // must be onverified - we want to open preferences. - openPrefs(); - } - - for (let topic of OBSERVER_TOPICS) { - Services.obs.addObserver(observe, topic, false); - } - window.addEventListener("unload", function(event) { - log("about:accounts unloading") - for (let topic of OBSERVER_TOPICS) { - Services.obs.removeObserver(observe, topic); - } - }); -} -initObservers(); diff --git a/application/basilisk/base/content/aboutaccounts/aboutaccounts.xhtml b/application/basilisk/base/content/aboutaccounts/aboutaccounts.xhtml deleted file mode 100644 index 475f0e86f..000000000 --- a/application/basilisk/base/content/aboutaccounts/aboutaccounts.xhtml +++ /dev/null @@ -1,112 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- 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/. --> -<!DOCTYPE html [ - <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> - %htmlDTD; - <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> - %brandDTD; - <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd"> - %globalDTD; - <!ENTITY % aboutAccountsDTD SYSTEM "chrome://browser/locale/aboutAccounts.dtd"> - %aboutAccountsDTD; - <!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> - %syncBrandDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml" dir="&locale.dir;"> - <head> - <title>&syncBrand.fullName.label;</title> - <meta name="viewport" content="width=device-width"/> - - - <link rel="icon" type="image/png" id="favicon" - href="chrome://branding/content/icon32.png"/> - <link rel="stylesheet" - href="chrome://browser/content/aboutaccounts/normalize.css" - type="text/css" /> - <link rel="stylesheet" - href="chrome://browser/content/aboutaccounts/main.css" - type="text/css" /> - <link rel="stylesheet" - href="chrome://browser/content/aboutaccounts/aboutaccounts.css" - type="text/css" /> - </head> - <body> - <div id="stage"> - - <div id="manage"> - <header> - <h1>&aboutAccounts.connected;</h1> - <div id="email"></div> - </header> - - <section> - <div class="graphic graphic-sync-intro"> </div> - - <div class="button-row"> - <button id="buttonOpenPrefs" class="button" href="#" tabindex="0">&aboutAccountsConfig.syncPreferences.label;</button> - </div> - </section> - </div> - - <div id="intro"> - <header> - <h1>&aboutAccounts.welcome;</h1> - </header> - - <section> - <div class="graphic graphic-sync-intro"> </div> - - <div class="description">&aboutAccountsConfig.description;</div> - - <div class="button-row"> - <button id="buttonGetStarted" class="button" tabindex="1">&aboutAccountsConfig.startButton.label;</button> - </div> - - <div class="links"> - <button id="oldsync" tabindex="2">&aboutAccountsConfig.useOldSync.label;</button> - </div> - </section> - </div> - - <div id="networkError"> - <header> - <h1>&aboutAccounts.noConnection.title;</h1> - </header> - - <section> - <div class="graphic graphic-sync-intro"> </div> - - <div class="description">&aboutAccounts.noConnection.description;</div> - - <div class="button-row"> - <button id="buttonRetry" class="button" tabindex="3">&aboutAccounts.noConnection.retry;</button> - </div> - </section> - </div> - - <div id="configError"> - <header> - <h1>&aboutAccounts.badConfig.title;</h1> - </header> - - <section> - <div class="graphic graphic-sync-intro"> </div> - - <div class="description">&aboutAccounts.badConfig.description;</div> - - </section> - </div> - - </div> - - <iframe mozframetype="content" id="remote" /> - - <script type="application/javascript;version=1.8" - src="chrome://browser/content/utilityOverlay.js"/> - <script type="text/javascript;version=1.8" - src="chrome://browser/content/aboutaccounts/aboutaccounts.js" /> - </body> -</html> diff --git a/application/basilisk/base/content/aboutaccounts/images/fox.png b/application/basilisk/base/content/aboutaccounts/images/fox.png Binary files differdeleted file mode 100644 index 83af78d6c..000000000 --- a/application/basilisk/base/content/aboutaccounts/images/fox.png +++ /dev/null diff --git a/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro.png b/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro.png Binary files differdeleted file mode 100644 index ff5f482f0..000000000 --- a/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro.png +++ /dev/null diff --git a/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro@2x.png b/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro@2x.png Binary files differdeleted file mode 100644 index 89fda0681..000000000 --- a/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro@2x.png +++ /dev/null diff --git a/application/basilisk/base/content/aboutaccounts/main.css b/application/basilisk/base/content/aboutaccounts/main.css deleted file mode 100644 index 8f4c3b34e..000000000 --- a/application/basilisk/base/content/aboutaccounts/main.css +++ /dev/null @@ -1,166 +0,0 @@ -*, -*:before, -*:after { - box-sizing: border-box; -} - -html { - background-color: #F2F2F2; - height: 100%; -} - -body { - color: #424f59; - font: message-box; - font-size: 14px; - height: 100%; -} - -a { - color: #0095dd; - cursor: pointer; /* Use the correct cursor for anchors without an href */ -} - -a:active { - outline: none; -} - -a:focus { - outline: 1px dotted #0095dd; -} - - -a.no-underline { - text-decoration: none; -} - -#stage { - background:#fff; - border-radius: 5px; - box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.25); - margin: 0 auto; - min-height: 300px; - padding: 60px 40px 40px 40px; - position: relative; - text-align: center; - top: 80px; - width: 420px; -} - -header h1 -{ - font-size: 24px; - font-weight: 200; - line-height: 1em; -} - -#intro header h1 { - margin: 0 0 32px 0; -} - -#manage header h1 { - margin: 0 0 12px 0; -} - -#manage header #email { - margin-bottom: 23px; - color: rgb(138, 155, 168); - font-size: 19px; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -.description { - font-size: 18px; -} - -.button-row { - margin-top: 45px; - margin-bottom:20px; -} - -.button-row button, -.button-row a.button { - background: #0095dd; - border: none; - border-radius: 5px; - color: #FFFFFF; - cursor: pointer; - font-size: 24px; - padding: 15px 0; - transition-duration: 150ms; - transition-property: background-color; - width: 100%; -} - -.button-row a.button { - display: inline-block; - text-decoration: none; -} - -.button-row a.button:active, -.button-row a.button:hover, -.button-row a.button:focus, -.button-row button:active, -.button-row button:hover, -.button-row button:focus { - background: #08c; -} - - -.graphic-sync-intro { - background-image: url(images/graphic_sync_intro.png); - background-repeat: no-repeat; - background-size: 150px 195px; - height: 195px; - margin: 0 auto; - overflow: hidden; - text-indent: 100%; - white-space: nowrap; - width: 150px; -} - -.description, -.button-row { - margin-top: 30px; -} - -.links { - margin: 20px 0; -} - -@media only screen and (max-width: 500px) { - html { - background: #fff; - } - - #stage { - box-shadow: none; - margin: 30px auto 0 auto; - min-height: none; - min-width: 320px; - padding: 0 10px; - width: 100%; - } - - .button-row { - margin-top: 20px; - } - - .button-row button, - .button-row a.button { - padding: 10px 0; - } - -} - -/* Retina */ -@media -only screen and (min-device-pixel-ratio: 2), -only screen and ( min-resolution: 192dpi), -only screen and ( min-resolution: 2dppx) { - .graphic-sync-intro { - background-image: url(images/graphic_sync_intro@2x.png); - } -} diff --git a/application/basilisk/base/content/aboutaccounts/normalize.css b/application/basilisk/base/content/aboutaccounts/normalize.css deleted file mode 100644 index c02ab25de..000000000 --- a/application/basilisk/base/content/aboutaccounts/normalize.css +++ /dev/null @@ -1,402 +0,0 @@ -/*! normalize.css v2.1.3 | MIT License | git.io/normalize */
-
-/* ==========================================================================
- HTML5 display definitions
- ========================================================================== */
-
-/**
- * Correct `block` display not defined in IE 8/9.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-nav,
-section,
-summary {
- display: block;
-}
-
-/**
- * Correct `inline-block` display not defined in IE 8/9.
- */
-
-audio,
-canvas,
-video {
- display: inline-block;
-}
-
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-
-/**
- * Address `[hidden]` styling not present in IE 8/9.
- * Hide the `template` element in IE, Safari, and Firefox < 22.
- */
-
-[hidden],
-template {
- display: none;
-}
-
-/* ==========================================================================
- Base
- ========================================================================== */
-
-/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS text size adjust after orientation change, without disabling
- * user zoom.
- */
-
-html {
- font-family: sans-serif; /* 1 */
- -ms-text-size-adjust: 100%; /* 2 */
- -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/**
- * Remove default margin.
- */
-
-body {
- margin: 0;
-}
-
-/* ==========================================================================
- Links
- ========================================================================== */
-
-/**
- * Remove the gray background color from active links in IE 10.
- */
-
-a {
- background: transparent;
-}
-
-/**
- * Address `outline` inconsistency between Chrome and other browsers.
- */
-
-a:focus {
- outline: thin dotted;
-}
-
-/**
- * Improve readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
- outline: 0;
-}
-
-/* ==========================================================================
- Typography
- ========================================================================== */
-
-/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari 5, and Chrome.
- */
-
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-
-/**
- * Address styling not present in IE 8/9, Safari 5, and Chrome.
- */
-
-abbr[title] {
- border-bottom: 1px dotted;
-}
-
-/**
- * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
- */
-
-b,
-strong {
- font-weight: bold;
-}
-
-/**
- * Address styling not present in Safari 5 and Chrome.
- */
-
-dfn {
- font-style: italic;
-}
-
-/**
- * Address differences between Firefox and other browsers.
- */
-
-hr {
- box-sizing: content-box;
- height: 0;
-}
-
-/**
- * Address styling not present in IE 8/9.
- */
-
-mark {
- background: #ff0;
- color: #000;
-}
-
-/**
- * Correct font family set oddly in Safari 5 and Chrome.
- */
-
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, serif;
- font-size: 1em;
-}
-
-/**
- * Improve readability of pre-formatted text in all browsers.
- */
-
-pre {
- white-space: pre-wrap;
-}
-
-/**
- * Set consistent quote types.
- */
-
-q {
- quotes: "\201C" "\201D" "\2018" "\2019";
-}
-
-/**
- * Address inconsistent and variable font size in all browsers.
- */
-
-small {
- font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sup {
- top: -0.5em;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-/* ==========================================================================
- Embedded content
- ========================================================================== */
-
-/**
- * Remove border when inside `a` element in IE 8/9.
- */
-
-img {
- border: 0;
-}
-
-/**
- * Correct overflow displayed oddly in IE 9.
- */
-
-svg:not(:root) {
- overflow: hidden;
-}
-
-/* ==========================================================================
- Figures
- ========================================================================== */
-
-/**
- * Address margin not present in IE 8/9 and Safari 5.
- */
-
-figure {
- margin: 0;
-}
-
-/* ==========================================================================
- Forms
- ========================================================================== */
-
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct `color` not being inherited in IE 8/9.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
- border: 0; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * 1. Correct font family not being inherited in all browsers.
- * 2. Correct font size not being inherited in all browsers.
- * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
- */
-
-button,
-input,
-select,
-textarea {
- font-family: inherit; /* 1 */
- font-size: 100%; /* 2 */
- margin: 0; /* 3 */
-}
-
-/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-button,
-input {
- line-height: normal;
-}
-
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
- * Correct `select` style inheritance in Firefox 4+ and Opera.
- */
-
-button,
-select {
- text-transform: none;
-}
-
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- * `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
- -webkit-appearance: button; /* 2 */
- cursor: pointer; /* 3 */
-}
-
-/**
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-html input[disabled] {
- cursor: default;
-}
-
-/**
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
- box-sizing: border-box; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome.
- */
-
-input[type="search"] {
- -webkit-appearance: textfield; /* 1 */
- box-sizing: content-box; /* 2 */
-}
-
-/**
- * Remove inner padding and search cancel button in Safari 5 and Chrome
- * on OS X.
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/**
- * Remove inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-/**
- * 1. Remove default vertical scrollbar in IE 8/9.
- * 2. Improve readability and alignment in all browsers.
- */
-
-textarea {
- overflow: auto; /* 1 */
- vertical-align: top; /* 2 */
-}
-
-/* ==========================================================================
- Tables
- ========================================================================== */
-
-/**
- * Remove most spacing between table cells.
- */
-
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
diff --git a/application/basilisk/base/content/browser-fxaccounts.js b/application/basilisk/base/content/browser-fxaccounts.js deleted file mode 100644 index e1d556bff..000000000 --- a/application/basilisk/base/content/browser-fxaccounts.js +++ /dev/null @@ -1,314 +0,0 @@ -/* 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 gFxAccounts = { - - _initialized: false, - _inCustomizationMode: false, - _cachedProfile: null, - - get weave() { - delete this.weave; - return this.weave = Cc["@mozilla.org/weave/service;1"] - .getService(Ci.nsISupports) - .wrappedJSObject; - }, - - get topics() { - // Do all this dance to lazy-load FxAccountsCommon. - delete this.topics; - return this.topics = [ - "weave:service:ready", - "weave:service:login:change", - "weave:service:setup-complete", - "weave:service:sync:error", - "weave:ui:login:error", - this.FxAccountsCommon.ONLOGIN_NOTIFICATION, - this.FxAccountsCommon.ONLOGOUT_NOTIFICATION, - this.FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION, - ]; - }, - - get panelUIFooter() { - delete this.panelUIFooter; - return this.panelUIFooter = document.getElementById("PanelUI-footer-fxa"); - }, - - get panelUIStatus() { - delete this.panelUIStatus; - return this.panelUIStatus = document.getElementById("PanelUI-fxa-status"); - }, - - get panelUIAvatar() { - delete this.panelUIAvatar; - return this.panelUIAvatar = document.getElementById("PanelUI-fxa-avatar"); - }, - - get panelUILabel() { - delete this.panelUILabel; - return this.panelUILabel = document.getElementById("PanelUI-fxa-label"); - }, - - get panelUIIcon() { - delete this.panelUIIcon; - return this.panelUIIcon = document.getElementById("PanelUI-fxa-icon"); - }, - - get strings() { - delete this.strings; - return this.strings = Services.strings.createBundle( - "chrome://browser/locale/accounts.properties" - ); - }, - - get loginFailed() { - // Referencing Weave.Service will implicitly initialize sync, and we don't - // want to force that - so first check if it is ready. - let service = Cc["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; - if (!service.ready) { - return false; - } - // LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in". - // All other login failures are assumed to be transient and should go - // away by themselves, so aren't reflected here. - return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED; - }, - - init: function () { - // Bail out if we're already initialized and for pop-up windows. - if (this._initialized || !window.toolbar.visible) { - return; - } - - for (let topic of this.topics) { - Services.obs.addObserver(this, topic, false); - } - - gNavToolbox.addEventListener("customizationstarting", this); - gNavToolbox.addEventListener("customizationending", this); - - EnsureFxAccountsWebChannel(); - this._initialized = true; - - this.updateUI(); - }, - - uninit: function () { - if (!this._initialized) { - return; - } - - for (let topic of this.topics) { - Services.obs.removeObserver(this, topic); - } - - this._initialized = false; - }, - - observe: function (subject, topic, data) { - switch (topic) { - case this.FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION: - this._cachedProfile = null; - // Fallthrough intended - default: - this.updateUI(); - break; - } - }, - - handleEvent: function (event) { - this._inCustomizationMode = event.type == "customizationstarting"; - this.updateAppMenuItem(); - }, - - updateUI: function () { - // It's possible someone signed in to FxA after seeing our notification - // about "Legacy Sync migration" (which now is actually "Legacy Sync - // auto-disconnect") so kill that notification if it still exists. - let nb = window.document.getElementById("global-notificationbox"); - let n = nb.getNotificationWithValue(this.SYNC_MIGRATION_NOTIFICATION_TITLE); - if (n) { - nb.removeNotification(n, true); - } - - this.updateAppMenuItem(); - }, - - // Note that updateAppMenuItem() returns a Promise that's only used by tests. - updateAppMenuItem: function () { - let profileInfoEnabled = false; - try { - profileInfoEnabled = Services.prefs.getBoolPref("identity.fxaccounts.profile_image.enabled"); - } catch (e) { } - - this.panelUIFooter.hidden = false; - - // Make sure the button is disabled in customization mode. - if (this._inCustomizationMode) { - this.panelUIStatus.setAttribute("disabled", "true"); - this.panelUILabel.setAttribute("disabled", "true"); - this.panelUIAvatar.setAttribute("disabled", "true"); - this.panelUIIcon.setAttribute("disabled", "true"); - } else { - this.panelUIStatus.removeAttribute("disabled"); - this.panelUILabel.removeAttribute("disabled"); - this.panelUIAvatar.removeAttribute("disabled"); - this.panelUIIcon.removeAttribute("disabled"); - } - - let defaultLabel = this.panelUIStatus.getAttribute("defaultlabel"); - let errorLabel = this.panelUIStatus.getAttribute("errorlabel"); - let unverifiedLabel = this.panelUIStatus.getAttribute("unverifiedlabel"); - let settingslabel = this.panelUIStatus.getAttribute("settingslabel"); - // The localization string is for the signed in text, but it's the default text as well - let defaultTooltiptext = this.panelUIStatus.getAttribute("signedinTooltiptext"); - - let updateWithUserData = (userData) => { - // Window might have been closed while fetching data. - if (window.closed) { - return; - } - - // Reset the button to its original state. - this.panelUILabel.setAttribute("label", defaultLabel); - this.panelUIStatus.setAttribute("tooltiptext", defaultTooltiptext); - this.panelUIFooter.removeAttribute("fxastatus"); - this.panelUIFooter.removeAttribute("fxaprofileimage"); - this.panelUIAvatar.style.removeProperty("list-style-image"); - - if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED) { - // Leave the default state - return; - } - - if (this.loginFailed) { - this.panelUIFooter.setAttribute("fxastatus", "error"); - this.panelUILabel.setAttribute("label", errorLabel); - } else { - this.panelUIFooter.setAttribute("fxastatus", "signedin"); - this.panelUILabel.setAttribute("label", settingslabel); - this.panelUIStatus.setAttribute("tooltiptext", ""); - } - } - - let updateWithProfile = (profile) => { - if (profileInfoEnabled) { - if (profile.displayName) { - this.panelUILabel.setAttribute("label", profile.displayName); - } - if (profile.avatar) { - this.panelUIFooter.setAttribute("fxaprofileimage", "set"); - let bgImage = "url(\"" + profile.avatar + "\")"; - this.panelUIAvatar.style.listStyleImage = bgImage; - - let img = new Image(); - img.onerror = () => { - // Clear the image if it has trouble loading. Since this callback is asynchronous - // we check to make sure the image is still the same before we clear it. - if (this.panelUIAvatar.style.listStyleImage === bgImage) { - this.panelUIFooter.removeAttribute("fxaprofileimage"); - this.panelUIAvatar.style.removeProperty("list-style-image"); - } - }; - img.src = profile.avatar; - } - } - } - - return fxAccounts.getSignedInUser().then(userData => { - // userData may be null here when the user is not signed-in, but that's expected - updateWithUserData(userData); - // unverified users cause us to spew log errors fetching an OAuth token - // to fetch the profile, so don't even try in that case. - if (!userData || !userData.verified || !profileInfoEnabled) { - return null; // don't even try to grab the profile. - } - if (this._cachedProfile) { - return this._cachedProfile; - } - return fxAccounts.getSignedInUserProfile().catch(err => { - // Not fetching the profile is sad but the FxA logs will already have noise. - return null; - }); - }).then(profile => { - if (!profile) { - return; - } - updateWithProfile(profile); - this._cachedProfile = profile; // Try to avoid fetching the profile on every UI update - }).catch(error => { - // This is most likely in tests, were we quickly log users in and out. - // The most likely scenario is a user logged out, so reflect that. - // Bug 995134 calls for better errors so we could retry if we were - // sure this was the failure reason. - this.FxAccountsCommon.log.error("Error updating FxA account info", error); - updateWithUserData(null); - }); - }, - - onMenuPanelCommand: function () { - - switch (this.panelUIFooter.getAttribute("fxastatus")) { - case "signedin": - this.openPreferences(); - break; - case "error": - if (this.panelUIFooter.getAttribute("unverified")) { - this.openPreferences(); - } else { - this.openSignInAgainPage("menupanel"); - } - break; - default: - this.openPreferences(); - break; - } - - PanelUI.hide(); - }, - - openPreferences: function () { - openPreferences("paneSync", { urlParams: { entrypoint: "menupanel" } }); - }, - - openAccountsPage: function (action, urlParams={}) { - let params = new URLSearchParams(); - if (action) { - params.set("action", action); - } - for (let name in urlParams) { - if (urlParams[name] !== undefined) { - params.set(name, urlParams[name]); - } - } - let url = "about:accounts?" + params; - switchToTabHavingURI(url, true, { - replaceQueryString: true - }); - }, - - openSignInAgainPage: function (entryPoint) { - this.openAccountsPage("reauth", { entrypoint: entryPoint }); - }, - - updateTabContextMenu: function (aPopupMenu) { - // STUB - }, - - initPageContextMenu: function (contextMenu) { - // STUB - } -}; - -XPCOMUtils.defineLazyGetter(gFxAccounts, "FxAccountsCommon", function () { - return Cu.import("resource://gre/modules/FxAccountsCommon.js", {}); -}); - -XPCOMUtils.defineLazyModuleGetter(gFxAccounts, "fxaMigrator", - "resource://services-sync/FxaMigrator.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "EnsureFxAccountsWebChannel", - "resource://gre/modules/FxAccountsWebChannel.jsm"); diff --git a/application/basilisk/base/content/browser-menubar.inc b/application/basilisk/base/content/browser-menubar.inc index 0549ad915..b6ab23be5 100644 --- a/application/basilisk/base/content/browser-menubar.inc +++ b/application/basilisk/base/content/browser-menubar.inc @@ -195,9 +195,6 @@ key="key_gotoHistory" observes="viewHistorySidebar" label="&historyButton.label;"/> - <menuitem id="menu_tabsSidebar" - observes="viewTabsSidebar" - label="&syncedTabs.sidebar.label;"/> </menupopup> </menu> <menuseparator/> @@ -317,11 +314,13 @@ key="key_sanitize" command="Tools:Sanitize"/> <menuseparator id="sanitizeSeparator"/> +#ifdef MOZ_SERVICES_SYNC <menuitem id="sync-tabs-menuitem" class="syncTabsMenuItem" - label="&syncTabsMenu3.label;" + label="&syncTabsMenu2.label;" oncommand="BrowserOpenSyncTabs();" - hidden="true"/> + disabled="true"/> +#endif <menuitem id="historyRestoreLastSession" label="&historyRestoreLastSession.label;" command="Browser:RestoreLastSession"/> @@ -440,11 +439,10 @@ accesskey="&toolsMenu.accesskey;" onpopupshowing="mirrorShow(this)"> <menupopup id="menu_ToolsPopup" -# We have to use setTimeout() here to avoid a flickering menu bar when opening -# the Tools menu, see bug 970769. This can be removed once we got rid of the -# event loop spinning in Weave.Status._authManager. - onpopupshowing="setTimeout(() => gSyncUI.updateUI());" - > +#ifdef MOZ_SERVICES_SYNC + onpopupshowing="gSyncUI.updateUI();" +#endif + > <menuitem id="menu_openDownloads" label="&downloads.label;" accesskey="&downloads.accesskey;" @@ -455,23 +453,19 @@ accesskey="&addons.accesskey;" key="key_openAddons" command="Tools:Addons"/> - - <!-- only one of sync-setup, sync-syncnowitem or sync-reauthitem will be showing at once --> +#ifdef MOZ_SERVICES_SYNC + <!-- only one of sync-setup or sync-menu will be showing at once --> <menuitem id="sync-setup" - label="&syncSignIn.label;" - accesskey="&syncSignIn.accesskey;" + label="&syncSetup.label;" + accesskey="&syncSetup.accesskey;" observes="sync-setup-state" - oncommand="gSyncUI.openSetup(null, 'menubar')"/> + oncommand="gSyncUI.openSetup()"/> <menuitem id="sync-syncnowitem" label="&syncSyncNowItem.label;" accesskey="&syncSyncNowItem.accesskey;" observes="sync-syncnow-state" oncommand="gSyncUI.doSync(event);"/> - <menuitem id="sync-reauthitem" - label="&syncReAuthItem.label;" - accesskey="&syncReAuthItem.accesskey;" - observes="sync-reauth-state" - oncommand="gSyncUI.openSignInAgainPage('menubar');"/> +#endif <menuseparator id="devToolsSeparator"/> <menu id="webDeveloperMenu" label="&webDeveloperMenu.label;" diff --git a/application/basilisk/base/content/browser-places.js b/application/basilisk/base/content/browser-places.js index 83c737977..87734140f 100644 --- a/application/basilisk/base/content/browser-places.js +++ b/application/basilisk/base/content/browser-places.js @@ -804,18 +804,29 @@ HistoryMenu.prototype = { }, toggleTabsFromOtherComputers: function PHM_toggleTabsFromOtherComputers() { + // This is a no-op if MOZ_SERVICES_SYNC isn't defined +#ifdef MOZ_SERVICES_SYNC // Enable/disable the Tabs From Other Computers menu. Some of the menus handled // by HistoryMenu do not have this menuitem. let menuitem = this._rootElt.getElementsByClassName("syncTabsMenuItem")[0]; if (!menuitem) return; - if (!PlacesUIUtils.shouldShowTabsFromOtherComputersMenuitem()) { + // If Sync isn't configured yet, then don't show the menuitem. + if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED || + Weave.Svc.Prefs.get("firstSync", "") == "notReady") { menuitem.setAttribute("hidden", true); return; } + // The tabs engine might never be inited (if services.sync.registerEngines + // is modified), so make sure we avoid undefined errors. + let enabled = Weave.Service.isLoggedIn && + Weave.Service.engineManager.get("tabs") && + Weave.Service.engineManager.get("tabs").enabled; + menuitem.setAttribute("disabled", !enabled); menuitem.setAttribute("hidden", false); +#endif }, _onPopupShowing: function HM__onPopupShowing(aEvent) { diff --git a/application/basilisk/base/content/browser-sets.inc b/application/basilisk/base/content/browser-sets.inc index 6ea057d93..d6a9310ed 100644 --- a/application/basilisk/base/content/browser-sets.inc +++ b/application/basilisk/base/content/browser-sets.inc @@ -163,16 +163,13 @@ <!-- A broadcaster of a number of attributes suitable for "sync now" UI - A 'syncstatus' attribute is set while actively syncing, and the label attribute which changes from "sync now" to "syncing" etc. --> +#ifdef MOZ_SERVICES_SYNC <broadcaster id="sync-status"/> <!-- broadcasters of the "hidden" attribute to reflect setup state for menus --> <broadcaster id="sync-setup-state"/> <broadcaster id="sync-syncnow-state" hidden="true"/> - <broadcaster id="sync-reauth-state" hidden="true"/> - <broadcaster id="viewTabsSidebar" autoCheck="false" sidebartitle="&syncedTabs.sidebar.label;" - type="checkbox" group="sidebar" - sidebarurl="chrome://browser/content/syncedtabs/sidebar.xhtml" - oncommand="SidebarUI.toggle('viewTabsSidebar');"/> +#endif <broadcaster id="workOfflineMenuitemState"/> <broadcaster id="devtoolsMenuBroadcaster_ErrorConsole" diff --git a/application/basilisk/base/content/browser-syncui.js b/application/basilisk/base/content/browser-syncui.js index 3a57140f2..67056e221 100644 --- a/application/basilisk/base/content/browser-syncui.js +++ b/application/basilisk/base/content/browser-syncui.js @@ -1,63 +1,37 @@ -/* 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/. */ +# 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/. -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -#ifdef MOZ_SERVICES_CLOUDSYNC -XPCOMUtils.defineLazyModuleGetter(this, "CloudSync", - "resource://gre/modules/CloudSync.jsm"); -#endif - -XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", - "resource://gre/modules/FxAccounts.jsm"); - -const MIN_STATUS_ANIMATION_DURATION = 1600; - -// gSyncUI handles updating the tools menu and displaying notifications. +// gSyncUI handles updating the tools menu var gSyncUI = { _obs: ["weave:service:sync:start", - "weave:service:sync:finish", - "weave:service:sync:error", + "weave:service:sync:delayed", "weave:service:quota:remaining", "weave:service:setup-complete", "weave:service:login:start", "weave:service:login:finish", - "weave:service:login:error", "weave:service:logout:finish", "weave:service:start-over", - "weave:service:start-over:finish", "weave:ui:login:error", "weave:ui:sync:error", "weave:ui:sync:finish", "weave:ui:clear-error", - "weave:engine:sync:finish" ], _unloaded: false, - // The last sync start time. Used to calculate the leftover animation time - // once syncing completes (bug 1239042). - _syncStartTime: 0, - _syncAnimationTimer: 0, - - init: function () { - Cu.import("resource://services-common/stringbundle.js"); + init: function SUI_init() { // Proceed to set up the UI if Sync has already started up. // Otherwise we'll do it when Sync is firing up. - if (this.weaveService.ready) { + let xps = Components.classes["@mozilla.org/weave/service;1"] + .getService(Components.interfaces.nsISupports) + .wrappedJSObject; + if (xps.ready) { this.initUI(); return; } - // Sync isn't ready yet, but we can still update the UI with an initial - // state - we haven't called initUI() yet, but that's OK - that's more - // about observers for state changes, and will be called once Sync is - // ready to start sending notifications. - this.updateUI(); - Services.obs.addObserver(this, "weave:service:ready", true); - Services.obs.addObserver(this, "quit-application", true); // Remove the observer if the window is closed before the observer // was triggered. @@ -65,7 +39,6 @@ var gSyncUI = { gSyncUI._unloaded = true; window.removeEventListener("unload", onUnload, false); Services.obs.removeObserver(gSyncUI, "weave:service:ready"); - Services.obs.removeObserver(gSyncUI, "quit-application"); if (Weave.Status.ready) { gSyncUI._obs.forEach(function(topic) { @@ -85,161 +58,130 @@ var gSyncUI = { Services.obs.addObserver(this, topic, true); }, this); - // initial label for the sync buttons. - let broadcaster = document.getElementById("sync-status"); - broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label")); + if (gBrowser && Weave.Notifications.notifications.length) { + this.initNotifications(); + } + this.updateUI(); + }, + + initNotifications: function SUI_initNotifications() { + const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + let notificationbox = document.createElementNS(XULNS, "notificationbox"); + notificationbox.id = "sync-notifications"; + notificationbox.setAttribute("flex", "1"); - this.maybeMoveSyncedTabsButton(); + let bottombox = document.getElementById("browser-bottombox"); + bottombox.insertBefore(notificationbox, bottombox.firstChild); - this.updateUI(); + // Force a style flush to ensure that our binding is attached. + notificationbox.clientTop; + + // notificationbox will listen to observers from now on. + Services.obs.removeObserver(this, "weave:notification:added"); }, + _wasDelayed: false, - // Returns a promise that resolves with true if Sync needs to be configured, - // false otherwise. - _needsSetup() { - // If Sync is configured for FxAccounts then we do that promise-dance. - if (this.weaveService.fxAccountsEnabled) { - return fxAccounts.getSignedInUser().then(user => { - // We want to treat "account needs verification" as "needs setup". - return !(user && user.verified); - }); - } - // We are using legacy sync - check that. + _needsSetup: function SUI__needsSetup() { let firstSync = ""; try { firstSync = Services.prefs.getCharPref("services.sync.firstSync"); } catch (e) { } - - return Promise.resolve(Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED || - firstSync == "notReady"); + return Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED || + firstSync == "notReady"; }, - // Returns a promise that resolves with true if the user currently signed in - // to Sync needs to be verified, false otherwise. - _needsVerification() { - // For callers who care about the distinction between "needs setup" and - // "needs verification" - if (this.weaveService.fxAccountsEnabled) { - return fxAccounts.getSignedInUser().then(user => { - // If there is no user, they can't be in a "needs verification" state. - if (!user) { - return false; - } - return !user.verified; - }); - } + updateUI: function SUI_updateUI() { + let needsSetup = this._needsSetup(); + document.getElementById("sync-setup-state").hidden = !needsSetup; + document.getElementById("sync-syncnow-state").hidden = needsSetup; - // Otherwise we are configured for legacy Sync, which has no verification - // concept. - return Promise.resolve(false); - }, + if (!gBrowser) + return; - // Note that we don't show login errors in a notification bar here, but do - // still need to track a login-failed state so the "Tools" menu updates - // with the correct state. - _loginFailed: function () { - // If Sync isn't already ready, we don't want to force it to initialize - // by referencing Weave.Status - and it isn't going to be accurate before - // Sync is ready anyway. - if (!this.weaveService.ready) { - this.log.debug("_loginFailed has sync not ready, so returning false"); - return false; - } - this.log.debug("_loginFailed has sync state=${sync}", - { sync: Weave.Status.login}); - return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED; - }, + let button = document.getElementById("sync-button"); + if (!button) + return; - // Kick off an update of the UI - does *not* return a promise. - updateUI() { - this._promiseUpdateUI().catch(err => { - this.log.error("updateUI failed", err); - }) + button.removeAttribute("status"); + this._updateLastSyncTime(); + if (needsSetup) + button.removeAttribute("tooltiptext"); }, - // Updates the UI - returns a promise. - _promiseUpdateUI() { - return this._needsSetup().then(needsSetup => { - if (!gBrowser) - return Promise.resolve(); - - let loginFailed = this._loginFailed(); - - // Start off with a clean slate - document.getElementById("sync-reauth-state").hidden = true; - document.getElementById("sync-setup-state").hidden = true; - document.getElementById("sync-syncnow-state").hidden = true; - -#ifdef MOZ_SERVICES_CLOUDSYNC - if (CloudSync && CloudSync.ready && CloudSync().adapters.count) { - document.getElementById("sync-syncnow-state").hidden = false; - } else if (loginFailed) { -#else - if (loginFailed) { -#endif - // unhiding this element makes the menubar show the login failure state. - document.getElementById("sync-reauth-state").hidden = false; - } else if (needsSetup) { - document.getElementById("sync-setup-state").hidden = false; - } else { - document.getElementById("sync-syncnow-state").hidden = false; - } - - return this._updateSyncButtonsTooltip(); - }); - }, // Functions called by observers - onActivityStart() { + onActivityStart: function SUI_onActivityStart() { if (!gBrowser) return; - this.log.debug("onActivityStart"); + let button = document.getElementById("sync-button"); + if (!button) + return; - clearTimeout(this._syncAnimationTimer); - this._syncStartTime = Date.now(); + button.setAttribute("status", "active"); + }, - let broadcaster = document.getElementById("sync-status"); - broadcaster.setAttribute("syncstatus", "active"); - broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label")); - broadcaster.setAttribute("disabled", "true"); + onSyncDelay: function SUI_onSyncDelay() { + // basically, we want to just inform users that stuff is going to take a while + let title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title"); + let description = this._stringBundle.GetStringFromName("error.sync.no_node_found"); + let buttons = [new Weave.NotificationButton( + this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"), + this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"), + function() { gSyncUI.openServerStatus(); return true; } + )]; + let notification = new Weave.Notification( + title, description, null, Weave.Notifications.PRIORITY_INFO, buttons); + Weave.Notifications.replaceTitle(notification); + this._wasDelayed = true; + }, - this.updateUI(); + onLoginFinish: function SUI_onLoginFinish() { + // Clear out any login failure notifications + let title = this._stringBundle.GetStringFromName("error.login.title"); + this.clearError(title); }, - _updateSyncStatus() { - if (!gBrowser) - return; - let broadcaster = document.getElementById("sync-status"); - broadcaster.removeAttribute("syncstatus"); - broadcaster.removeAttribute("disabled"); - broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label")); - this.updateUI(); + onSetupComplete: function SUI_onSetupComplete() { + this.onLoginFinish(); }, - onActivityStop() { - if (!gBrowser) + onLoginError: function SUI_onLoginError() { + // if login fails, any other notifications are essentially moot + Weave.Notifications.removeAll(); + + // if we haven't set up the client, don't show errors + if (this._needsSetup()) { + this.updateUI(); return; - this.log.debug("onActivityStop"); + } - let now = Date.now(); - let syncDuration = now - this._syncStartTime; + let title = this._stringBundle.GetStringFromName("error.login.title"); - if (syncDuration < MIN_STATUS_ANIMATION_DURATION) { - let animationTime = MIN_STATUS_ANIMATION_DURATION - syncDuration; - clearTimeout(this._syncAnimationTimer); - this._syncAnimationTimer = setTimeout(() => this._updateSyncStatus(), animationTime); + let description; + if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) { + // Convert to days + let lastSync = + Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400; + description = + this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1); } else { - this._updateSyncStatus(); + let reason = Weave.Utils.getErrorString(Weave.Status.login); + description = + this._stringBundle.formatStringFromName("error.sync.description", [reason], 1); } - }, - onLoginError: function SUI_onLoginError() { - this.log.debug("onLoginError: login=${login}, sync=${sync}", Weave.Status); + let buttons = []; + buttons.push(new Weave.NotificationButton( + this._stringBundle.GetStringFromName("error.login.prefs.label"), + this._stringBundle.GetStringFromName("error.login.prefs.accesskey"), + function() { gSyncUI.openPrefs(); return true; } + )); - // We don't show any login errors here; browser-fxaccounts shows them in - // the hamburger menu. + let notification = new Weave.Notification(title, description, null, + Weave.Notifications.PRIORITY_WARNING, buttons); + Weave.Notifications.replaceTitle(notification); this.updateUI(); }, @@ -247,6 +189,10 @@ var gSyncUI = { this.updateUI(); }, + onStartOver: function SUI_onStartOver() { + this.clearError(); + }, + onQuotaNotice: function onQuotaNotice(subject, data) { let title = this._stringBundle.GetStringFromName("warning.sync.quota.label"); let description = this._stringBundle.GetStringFromName("warning.sync.quota.description"); @@ -262,40 +208,26 @@ var gSyncUI = { Weave.Notifications.replaceTitle(notification); }, - _getAppName: function () { - let brand = new StringBundle("chrome://branding/locale/brand.properties"); - return brand.get("brandShortName"); + openServerStatus: function () { + let statusURL = Services.prefs.getCharPref("services.sync.statusURL"); + window.openUILinkIn(statusURL, "tab"); }, // Commands - // doSync forces a sync - it *does not* return a promise as it is called - // via the various UI components. - doSync() { - this._needsSetup().then(needsSetup => { - if (!needsSetup) { - setTimeout(() => Weave.Service.errorHandler.syncAndReportErrors(), 0); - } - Services.obs.notifyObservers(null, "cloudsync:user-sync", null); - }).catch(err => { - this.log.error("Failed to force a sync", err); - }); + doSync: function SUI_doSync() { + setTimeout(function() Weave.Service.errorHandler.syncAndReportErrors(), 0); }, - // Handle clicking the toolbar button - which either opens the Sync setup - // pages or forces a sync now. Does *not* return a promise as it is called - // via the UI. - handleToolbarButton() { - this._needsSetup().then(needsSetup => { - if (needsSetup || this._loginFailed()) { - this.openSetup(); - } else { - this.doSync(); - } - }).catch(err => { - this.log.error("Failed to handle toolbar button command", err); - }); + handleToolbarButton: function SUI_handleStatusbarButton() { + if (this._needsSetup()) + this.openSetup(); + else + this.doSync(); }, + //XXXzpao should be part of syncCommon.js - which we might want to make a module... + // To be fixed in a followup (bug 583366) + /** * Invoke the Sync setup wizard. * @@ -304,11 +236,9 @@ var gSyncUI = { * null -- regular set up wizard * "pair" -- pair a device first * "reset" -- reset sync - * @param entryPoint - * Indicates the entrypoint from where this method was called. */ - openSetup: function SUI_openSetup(wizardType, entryPoint = "syncbutton") { + openSetup: function SUI_openSetup(wizardType) { let win = Services.wm.getMostRecentWindow("Weave:AccountSetup"); if (win) win.focus(); @@ -319,7 +249,6 @@ var gSyncUI = { } }, - // Open the legacy-sync device pairing UI. Note used for FxA Sync. openAddDevice: function () { if (!Weave.Utils.ensureMPUnlocked()) return; @@ -332,202 +261,186 @@ var gSyncUI = { "syncAddDevice", "centerscreen,chrome,resizable=no"); }, - openPrefs: function (entryPoint) { - openPreferences("paneSync", { urlParams: { entrypoint: entryPoint } }); + openQuotaDialog: function SUI_openQuotaDialog() { + let win = Services.wm.getMostRecentWindow("Sync:ViewQuota"); + if (win) + win.focus(); + else + Services.ww.activeWindow.openDialog( + "chrome://browser/content/sync/quota.xul", "", + "centerscreen,chrome,dialog,modal"); }, - openSignInAgainPage: function (entryPoint = "syncbutton") { - gFxAccounts.openSignInAgainPage(entryPoint); + openPrefs: function SUI_openPrefs() { + openPreferences("paneSync"); }, - /* After Sync is initialized we perform a once-only check for the sync - button being in "customize purgatory" and if so, move it to the panel. - This is done primarily for profiles created before SyncedTabs landed, - where the button defaulted to being in that purgatory. - We use a preference to ensure we only do it once, so people can still - customize it away and have it stick. - */ - maybeMoveSyncedTabsButton() { - const prefName = "browser.migrated-sync-button"; - let migrated = false; - try { - migrated = Services.prefs.getBoolPref(prefName); - } catch (_) {} - if (migrated) { - return; - } - if (!CustomizableUI.getPlacementOfWidget("sync-button")) { - CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL); - } - Services.prefs.setBoolPref(prefName, true); - }, - /* Update the tooltip for the sync-status broadcaster (which will update the - Sync Toolbar button and the Sync spinner in the FxA hamburger area.) - If Sync is configured, the tooltip is when the last sync occurred, - otherwise the tooltip reflects the fact that Sync needs to be - (re-)configured. - */ - _updateSyncButtonsTooltip: Task.async(function* () { + // Helpers + _updateLastSyncTime: function SUI__updateLastSyncTime() { if (!gBrowser) return; - let email; - try { - email = Services.prefs.getCharPref("services.sync.username"); - } catch (ex) {} - - let needsSetup = yield this._needsSetup(); - let needsVerification = yield this._needsVerification(); - let loginFailed = this._loginFailed(); - // This is a little messy as the Sync buttons are 1/2 Sync related and - // 1/2 FxA related - so for some strings we use Sync strings, but for - // others we reach into gFxAccounts for strings. - let tooltiptext; - if (needsVerification) { - // "needs verification" - tooltiptext = gFxAccounts.strings.formatStringFromName("verifyDescription", [email], 1); - } else if (needsSetup) { - // "needs setup". - tooltiptext = this._stringBundle.GetStringFromName("signInToSync.description"); - } else if (loginFailed) { - // "need to reconnect/re-enter your password" - tooltiptext = gFxAccounts.strings.formatStringFromName("reconnectDescription", [email], 1); - } else { - // Sync appears configured - format the "last synced at" time. - try { - let lastSync = new Date(Services.prefs.getCharPref("services.sync.lastSync")); - tooltiptext = this.formatLastSyncDate(lastSync); - } - catch (e) { - // pref doesn't exist (which will be the case until we've seen the - // first successful sync) or is invalid (which should be impossible!) - // Just leave tooltiptext as the empty string in these cases, which - // will cause the tooltip to be removed below. - } - } - - // We've done all our promise-y work and ready to update the UI - make - // sure it hasn't been torn down since we started. - if (!gBrowser) + let syncButton = document.getElementById("sync-button"); + if (!syncButton) return; - let broadcaster = document.getElementById("sync-status"); - if (broadcaster) { - if (tooltiptext) { - broadcaster.setAttribute("tooltiptext", tooltiptext); - } else { - broadcaster.removeAttribute("tooltiptext"); - } + let lastSync; + try { + lastSync = Services.prefs.getCharPref("services.sync.lastSync"); } - }), - - formatLastSyncDate: function(date) { - let dateFormat; - let sixDaysAgo = (() => { - let date = new Date(); - date.setDate(date.getDate() - 6); - date.setHours(0, 0, 0, 0); - return date; - })(); - // It may be confusing for the user to see "Last Sync: Monday" when the last sync was a indeed a Monday but 3 weeks ago - if (date < sixDaysAgo) { - dateFormat = {month: 'long', day: 'numeric'}; - } else { - dateFormat = {weekday: 'long', hour: 'numeric', minute: 'numeric'}; + catch (e) { }; + if (!lastSync || this._needsSetup()) { + syncButton.removeAttribute("tooltiptext"); + return; } - let lastSyncDateString = date.toLocaleDateString(undefined, dateFormat); - return this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDateString], 1); + + // Show the day-of-week and time (HH:MM) of last sync + let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M"); + let lastSyncLabel = + this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDate], 1); + + syncButton.setAttribute("tooltiptext", lastSyncLabel); }, - onClientsSynced: function() { - let broadcaster = document.getElementById("sync-syncnow-state"); - if (broadcaster) { - if (Weave.Service.clientsEngine.stats.numClients > 1) { - broadcaster.setAttribute("devices-status", "multi"); - } else { - broadcaster.setAttribute("devices-status", "single"); - } + clearError: function SUI_clearError(errorString) { + Weave.Notifications.removeAll(errorString); + this.updateUI(); + }, + + onSyncFinish: function SUI_onSyncFinish() { + let title = this._stringBundle.GetStringFromName("error.sync.title"); + + // Clear out sync failures on a successful sync + this.clearError(title); + + if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) { + title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title"); + this.clearError(title); + this._wasDelayed = false; } }, onSyncError: function SUI_onSyncError() { - this.log.debug("onSyncError: login=${login}, sync=${sync}", Weave.Status); let title = this._stringBundle.GetStringFromName("error.sync.title"); - let error = Weave.Utils.getErrorString(Weave.Status.sync); - let description = + + if (Weave.Status.login != Weave.LOGIN_SUCCEEDED) { + this.onLoginError(); + return; + } + + let description; + if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) { + // Convert to days + let lastSync = + Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400; + description = + this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1); + } else { + let error = Weave.Utils.getErrorString(Weave.Status.sync); + description = this._stringBundle.formatStringFromName("error.sync.description", [error], 1); + } let priority = Weave.Notifications.PRIORITY_WARNING; let buttons = []; - if (Weave.Status.sync == Weave.OVER_QUOTA) { - description = this._stringBundle.GetStringFromName("error.sync.quota.description"); + // Check if the client is outdated in some way + let outdated = Weave.Status.sync == Weave.VERSION_OUT_OF_DATE; + for (let [engine, reason] in Iterator(Weave.Status.engines)) + outdated = outdated || reason == Weave.VERSION_OUT_OF_DATE; + + if (outdated) { + description = this._stringBundle.GetStringFromName( + "error.sync.needUpdate.description"); buttons.push(new Weave.NotificationButton( - this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.label"), - this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.accesskey"), + this._stringBundle.GetStringFromName("error.sync.needUpdate.label"), + this._stringBundle.GetStringFromName("error.sync.needUpdate.accesskey"), + function() { + window.openUILinkIn(Services.prefs.getCharPref("services.sync.outdated.url"), "tab"); + return true; + } + )); + } + else if (Weave.Status.sync == Weave.OVER_QUOTA) { + description = this._stringBundle.GetStringFromName( + "error.sync.quota.description"); + buttons.push(new Weave.NotificationButton( + this._stringBundle.GetStringFromName( + "error.sync.viewQuotaButton.label"), + this._stringBundle.GetStringFromName( + "error.sync.viewQuotaButton.accesskey"), function() { gSyncUI.openQuotaDialog(); return true; } ) ); - // Only show the notification bar on Quota error. the panel will show the rest. - let notification = - new Weave.Notification(title, description, null, priority, buttons); - Weave.Notifications.replaceTitle(notification); + } + else if (Weave.Status.enforceBackoff) { + priority = Weave.Notifications.PRIORITY_INFO; + buttons.push(new Weave.NotificationButton( + this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"), + this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"), + function() { gSyncUI.openServerStatus(); return true; } + )); + } + else { + priority = Weave.Notifications.PRIORITY_INFO; + buttons.push(new Weave.NotificationButton( + this._stringBundle.GetStringFromName("error.sync.tryAgainButton.label"), + this._stringBundle.GetStringFromName("error.sync.tryAgainButton.accesskey"), + function() { gSyncUI.doSync(); return true; } + )); + } + + let notification = + new Weave.Notification(title, description, null, priority, buttons); + Weave.Notifications.replaceTitle(notification); + + if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) { + title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title"); + Weave.Notifications.removeAll(title); + this._wasDelayed = false; } this.updateUI(); }, - observe: function SUI_observe(subject, topic, data) { - this.log.debug("observed", topic); if (this._unloaded) { Cu.reportError("SyncUI observer called after unload: " + topic); return; } - // Unwrap, just like Svc.Obs, but without pulling in that dependency. - if (subject && typeof subject == "object" && - ("wrappedJSObject" in subject) && - ("observersModuleSubjectWrapper" in subject.wrappedJSObject)) { - subject = subject.wrappedJSObject.object; - } - - // First handle "activity" only. switch (topic) { case "weave:service:sync:start": this.onActivityStart(); break; - case "weave:service:sync:finish": - case "weave:service:sync:error": - this.onActivityStop(); - break; - } - // Now non-activity state (eg, enabled, errors, etc) - // Note that sync uses the ":ui:" notifications for errors because sync. - switch (topic) { case "weave:ui:sync:finish": - // Do nothing. + this.onSyncFinish(); break; case "weave:ui:sync:error": this.onSyncError(); break; - case "weave:service:setup-complete": - case "weave:service:login:finish": - case "weave:service:login:start": - case "weave:service:start-over": - this.updateUI(); + case "weave:service:sync:delayed": + this.onSyncDelay(); break; case "weave:service:quota:remaining": this.onQuotaNotice(); break; + case "weave:service:setup-complete": + this.onSetupComplete(); + break; + case "weave:service:login:start": + this.onActivityStart(); + break; + case "weave:service:login:finish": + this.onLoginFinish(); + break; case "weave:ui:login:error": - case "weave:service:login:error": this.onLoginError(); break; case "weave:service:logout:finish": this.onLogout(); break; - case "weave:service:start-over:finish": - this.updateUI(); + case "weave:service:start-over": + this.onStartOver(); break; case "weave:service:ready": this.initUI(); @@ -535,16 +448,8 @@ var gSyncUI = { case "weave:notification:added": this.initNotifications(); break; - case "weave:engine:sync:finish": - if (data != "clients") { - return; - } - this.onClientsSynced(); - break; - case "quit-application": - // Stop the animation timer on shutdown, since we can't update the UI - // after this. - clearTimeout(this._syncAnimationTimer); + case "weave:ui:clear-error": + this.clearError(); break; } }, @@ -556,19 +461,10 @@ var gSyncUI = { }; XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() { - // XXXzpao these strings should probably be moved from /services to /browser... (bug 583381) + //XXXzpao these strings should probably be moved from /services to /browser... (bug 583381) // but for now just make it work return Cc["@mozilla.org/intl/stringbundle;1"]. getService(Ci.nsIStringBundleService). createBundle("chrome://weave/locale/services/sync.properties"); }); -XPCOMUtils.defineLazyGetter(gSyncUI, "log", function() { - return Log.repository.getLogger("browserwindow.syncui"); -}); - -XPCOMUtils.defineLazyGetter(gSyncUI, "weaveService", function() { - return Components.classes["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; -}); diff --git a/application/basilisk/base/content/browser.css b/application/basilisk/base/content/browser.css index 517c1c5eb..a2c2559d6 100644 --- a/application/basilisk/base/content/browser.css +++ b/application/basilisk/base/content/browser.css @@ -687,6 +687,18 @@ window[chromehidden~="toolbar"] toolbar:not(#nav-bar):not(#TabsToolbar):not(#pri min-width: 1px; } +%ifdef MOZ_SERVICES_SYNC +/* Sync notification UI */ +#sync-notifications { + -moz-binding: url("chrome://browser/content/sync/notification.xml#notificationbox"); + overflow-y: visible !important; +} + +#sync-notifications notification { + -moz-binding: url("chrome://browser/content/sync/notification.xml#notification"); +} +%endif + /* History Swipe Animation */ #historySwipeAnimationContainer { diff --git a/application/basilisk/base/content/browser.js b/application/basilisk/base/content/browser.js index ddbe11a9d..a752f4cd9 100644 --- a/application/basilisk/base/content/browser.js +++ b/application/basilisk/base/content/browser.js @@ -46,7 +46,6 @@ Cu.import("resource://gre/modules/NotificationDB.jsm"); ["Task", "resource://gre/modules/Task.jsm"], ["UpdateUtils", "resource://gre/modules/UpdateUtils.jsm"], ["Weave", "resource://services-sync/main.js"], - ["fxAccounts", "resource://gre/modules/FxAccounts.jsm"], #ifdef MOZ_DEVTOOLS // Note: Do not delete! It is used for: base/content/nsContextMenu.js ["gDevTools", "resource://devtools/client/framework/gDevTools.jsm"], @@ -103,6 +102,12 @@ XPCOMUtils.defineLazyGetter(this, "PageMenuParent", function() { return new tmp.PageMenuParent(); }); +#ifdef MOZ_SERVICES_SYNC +XPCOMUtils.defineLazyModuleGetter(this, "Weave", + "resource://services-sync/main.js"); +#endif + + XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () { let tmp = {}; Cu.import("resource://gre/modules/PopupNotifications.jsm", tmp); @@ -208,6 +213,10 @@ var gInitialPages = [ "about:logopage" ]; +#ifdef MOZ_SERVICES_SYNC +#include browser-syncui.js +#endif + function* browserWindows() { let windows = Services.wm.getEnumerator("navigator:browser"); while (windows.hasMoreElements()) @@ -1305,13 +1314,14 @@ var gBrowserInit = { FullScreen.init(); PointerLock.init(); - // initialize the sync UI - gSyncUI.init(); - gFxAccounts.init(); - if (AppConstants.MOZ_DATA_REPORTING) gDataNotificationInfoBar.init(); +#ifdef MOZ_SERVICES_SYNC + // initialize the sync UI + gSyncUI.init(); +#endif + gBrowserThumbnails.init(); gMenuButtonBadgeManager.init(); @@ -1445,8 +1455,6 @@ var gBrowserInit = { FullScreen.uninit(); - gFxAccounts.uninit(); - Services.obs.removeObserver(gPluginHandler.NPAPIPluginCrashed, "plugin-crashed"); try { @@ -1607,8 +1615,10 @@ if (AppConstants.platform == "macosx") { // initialize the private browsing UI gPrivateBrowsingUI.init(); +#ifdef MOZ_SERVICES_SYNC // initialize the sync UI gSyncUI.init(); +#endif }; gBrowserInit.nonBrowserWindowShutdown = function() { @@ -3181,12 +3191,14 @@ var PrintPreviewListener = { this._chromeState.globalNotificationsOpen = !globalNotificationBox.notificationsHidden; globalNotificationBox.notificationsHidden = true; +#ifdef MOZ_SERVICES_SYNC this._chromeState.syncNotificationsOpen = false; var syncNotifications = document.getElementById("sync-notifications"); if (syncNotifications) { this._chromeState.syncNotificationsOpen = !syncNotifications.notificationsHidden; syncNotifications.notificationsHidden = true; } +#endif }, _showChrome: function () { if (this._chromeState.notificationsOpen) @@ -3198,8 +3210,10 @@ var PrintPreviewListener = { if (this._chromeState.globalNotificationsOpen) document.getElementById("global-notificationbox").notificationsHidden = false; +#ifdef MOZ_SERVICES_SYNC if (this._chromeState.syncNotificationsOpen) document.getElementById("sync-notifications").notificationsHidden = false; +#endif if (this._chromeState.sidebarOpen) SidebarUI.show(this._sidebarCommand); @@ -6238,9 +6252,14 @@ function checkEmptyPageOrigin(browser = gBrowser.selectedBrowser, return ssm.isSystemPrincipal(contentPrincipal); } +#ifdef MOZ_SERVICES_SYNC function BrowserOpenSyncTabs() { - switchToTabHavingURI("about:sync-tabs", true); + if (gSyncUI._needsSetup()) + gSyncUI.openSetup(); + else + switchToTabHavingURI("about:sync-tabs", true); } +#endif /** * Format a URL @@ -7540,8 +7559,6 @@ var TabContextMenu = { this.contextTab.addEventListener("TabAttrModified", this, false); aPopupMenu.addEventListener("popuphiding", this, false); - - gFxAccounts.updateTabContextMenu(aPopupMenu); }, handleEvent(aEvent) { switch (aEvent.type) { diff --git a/application/basilisk/base/content/browser.xul b/application/basilisk/base/content/browser.xul index 0cc4c982a..d99ac9bc8 100644 --- a/application/basilisk/base/content/browser.xul +++ b/application/basilisk/base/content/browser.xul @@ -390,59 +390,6 @@ <tooltip id="dynamic-shortcut-tooltip" onpopupshowing="UpdateDynamicShortcutTooltipText(this);"/> - - <menupopup id="SyncedTabsSidebarContext"> - <menuitem label="&syncedTabs.context.open.label;" - accesskey="&syncedTabs.context.open.accesskey;" - id="syncedTabsOpenSelected" where="current"/> - <menuitem label="&syncedTabs.context.openInNewTab.label;" - accesskey="&syncedTabs.context.openInNewTab.accesskey;" - id="syncedTabsOpenSelectedInTab" where="tab"/> - <menuitem label="&syncedTabs.context.openInNewWindow.label;" - accesskey="&syncedTabs.context.openInNewWindow.accesskey;" - id="syncedTabsOpenSelectedInWindow" where="window"/> - <menuitem label="&syncedTabs.context.openInNewPrivateWindow.label;" - accesskey="&syncedTabs.context.openInNewPrivateWindow.accesskey;" - id="syncedTabsOpenSelectedInPrivateWindow" where="window" private="true"/> - <menuseparator/> - <menuitem label="&syncedTabs.context.bookmarkSingleTab.label;" - accesskey="&syncedTabs.context.bookmarkSingleTab.accesskey;" - id="syncedTabsBookmarkSelected"/> - <menuitem label="&syncedTabs.context.copy.label;" - accesskey="&syncedTabs.context.copy.accesskey;" - id="syncedTabsCopySelected"/> - <menuseparator/> - <menuitem label="&syncSyncNowItem.label;" - accesskey="&syncSyncNowItem.accesskey;" - id="syncedTabsRefresh"/> - </menupopup> - <menupopup id="SyncedTabsSidebarTabsFilterContext" - class="textbox-contextmenu"> - <menuitem label="&undoCmd.label;" - accesskey="&undoCmd.accesskey;" - cmd="cmd_undo"/> - <menuseparator/> - <menuitem label="&cutCmd.label;" - accesskey="&cutCmd.accesskey;" - cmd="cmd_cut"/> - <menuitem label="©Cmd.label;" - accesskey="©Cmd.accesskey;" - cmd="cmd_copy"/> - <menuitem label="&pasteCmd.label;" - accesskey="&pasteCmd.accesskey;" - cmd="cmd_paste"/> - <menuitem label="&deleteCmd.label;" - accesskey="&deleteCmd.accesskey;" - cmd="cmd_delete"/> - <menuseparator/> - <menuitem label="&selectAllCmd.label;" - accesskey="&selectAllCmd.accesskey;" - cmd="cmd_selectAll"/> - <menuseparator/> - <menuitem label="&syncSyncNowItem.label;" - accesskey="&syncSyncNowItem.accesskey;" - id="syncedTabsRefreshFilter"/> - </menupopup> </popupset> #ifdef CAN_DRAW_IN_TITLEBAR @@ -964,6 +911,18 @@ type="checkbox" label="&fullScreenCmd.label;" tooltip="dynamic-shortcut-tooltip"/> + +#ifdef MOZ_SERVICES_SYNC + <toolbarbutton id="sync-button" + class="toolbarbutton-1 chromeclass-toolbar-additional" + label="&syncToolbarButton.label;" + oncommand="gSyncUI.handleToolbarButton();"/>> + + <toolbarbutton id="sync-tabs-button" + class="toolbarbutton-1 chromeclass-toolbar-additional" + label="&syncTabsToolbarButton.label;" + oncommand="BrowserOpenSyncTabs();"/> +#endif </toolbarpalette> </toolbox> diff --git a/application/basilisk/base/content/global-scripts.inc b/application/basilisk/base/content/global-scripts.inc index eef21e15e..6417a1d95 100644 --- a/application/basilisk/base/content/global-scripts.inc +++ b/application/basilisk/base/content/global-scripts.inc @@ -27,7 +27,6 @@ <script type="application/javascript" src="chrome://browser/content/browser-safebrowsing.js"/> #endif <script type="application/javascript" src="chrome://browser/content/browser-sidebar.js"/> -<script type="application/javascript" src="chrome://browser/content/browser-syncui.js"/> <script type="application/javascript" src="chrome://browser/content/browser-tabsintitlebar.js"/> <script type="application/javascript" src="chrome://browser/content/browser-thumbnails.js"/> <script type="application/javascript" src="chrome://browser/content/browser-trackingprotection.js"/> diff --git a/application/basilisk/base/content/nsContextMenu.js b/application/basilisk/base/content/nsContextMenu.js index 74a2e7a8e..370e5ba60 100644 --- a/application/basilisk/base/content/nsContextMenu.js +++ b/application/basilisk/base/content/nsContextMenu.js @@ -112,7 +112,6 @@ nsContextMenu.prototype = { this.initLeaveDOMFullScreenItems(); this.initClickToPlayItems(); this.initPasswordManagerItems(); - this.initSyncItems(); }, initPageMenuSeparator: function CM_initPageMenuSeparator() { @@ -522,10 +521,6 @@ nsContextMenu.prototype = { popup.insertBefore(fragment, insertBeforeElement); }, - initSyncItems: function() { - gFxAccounts.initPageContextMenu(this); - }, - openPasswordManager: function() { LoginHelper.openPasswordManager(window, gContextMenuContentData.documentURIObject.host); }, diff --git a/application/basilisk/base/content/sync/customize.css b/application/basilisk/base/content/sync/customize.css deleted file mode 100644 index 2bb62595d..000000000 --- a/application/basilisk/base/content/sync/customize.css +++ /dev/null @@ -1,28 +0,0 @@ -/* 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/. */ - -:root { - font-size: 80%; -} - -#sync-customize-pane { - padding-inline-start: 74px; - background: top left url(chrome://browser/skin/sync-128.png) no-repeat; - background-size: 64px; -} - -#sync-customize-title { - margin-inline-start: 0; - padding-bottom: 0.5em; - font-weight: bold; -} - -#sync-customize-subtitle { - font-size: 90%; -} - -checkbox { - margin: 0; - padding: 0.5em 0 0; -} diff --git a/application/basilisk/base/content/sync/customize.js b/application/basilisk/base/content/sync/customize.js deleted file mode 100644 index f431ac58c..000000000 --- a/application/basilisk/base/content/sync/customize.js +++ /dev/null @@ -1,25 +0,0 @@ -/* 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"; - -Components.utils.import("resource://gre/modules/Services.jsm"); - -addEventListener("dialogaccept", function () { - let pane = document.getElementById("sync-customize-pane"); - // First determine what the preference for the "global" sync enabled pref - // should be based on the engines selected. - let prefElts = pane.querySelectorAll("preferences > preference"); - let syncEnabled = false; - for (let elt of prefElts) { - if (elt.name.startsWith("services.sync.") && elt.value) { - syncEnabled = true; - break; - } - } - Services.prefs.setBoolPref("services.sync.enabled", syncEnabled); - // and write the individual prefs. - pane.writePreferences(true); - window.arguments[0].accepted = true; -}); diff --git a/application/basilisk/base/content/sync/customize.xul b/application/basilisk/base/content/sync/customize.xul deleted file mode 100644 index 827edf565..000000000 --- a/application/basilisk/base/content/sync/customize.xul +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0"?> - -<!-- 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/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/content/sync/customize.css" type="text/css"?> - -<!DOCTYPE dialog [ -<!ENTITY % syncCustomizeDTD SYSTEM "chrome://browser/locale/syncCustomize.dtd"> -%syncCustomizeDTD; -]> -<dialog id="sync-customize" - windowtype="Sync:Customize" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - title="&syncCustomize.dialog.title;" - buttonlabelaccept="&syncCustomize.acceptButton.label;" - buttons="accept"> - - <prefpane id="sync-customize-pane"> - <preferences> - <preference id="engine.bookmarks" name="services.sync.engine.bookmarks" type="bool"/> - <preference id="engine.history" name="services.sync.engine.history" type="bool"/> - <preference id="engine.tabs" name="services.sync.engine.tabs" type="bool"/> - <preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/> - <preference id="engine.addons" name="services.sync.engine.addons" type="bool"/> - <preference id="engine.prefs" name="services.sync.engine.prefs" type="bool"/> - </preferences> - - <label id="sync-customize-title" value="&syncCustomize.title;"/> - <description id="sync-customize-subtitle" - value="&syncCustomize.description;"/> - - <vbox align="start"> - <checkbox label="&engine.tabs.label;" - accesskey="&engine.tabs.accesskey;" - preference="engine.tabs"/> - <checkbox label="&engine.bookmarks.label;" - accesskey="&engine.bookmarks.accesskey;" - preference="engine.bookmarks"/> - <checkbox label="&engine.passwords.label;" - accesskey="&engine.passwords.accesskey;" - preference="engine.passwords"/> - <checkbox label="&engine.history.label;" - accesskey="&engine.history.accesskey;" - preference="engine.history"/> - <checkbox label="&engine.addons.label;" - accesskey="&engine.addons.accesskey;" - preference="engine.addons"/> - <checkbox label="&engine.prefs.label;" - accesskey="&engine.prefs.accesskey;" - preference="engine.prefs"/> - </vbox> - - </prefpane> - - <script type="application/javascript" - src="chrome://browser/content/sync/customize.js" /> - -</dialog> diff --git a/application/basilisk/base/jar.mn b/application/basilisk/base/jar.mn index 3b51e9555..126312cd5 100644 --- a/application/basilisk/base/jar.mn +++ b/application/basilisk/base/jar.mn @@ -48,16 +48,6 @@ browser.jar: content/browser/abouthealthreport/abouthealth.js (content/abouthealthreport/abouthealth.js) content/browser/abouthealthreport/abouthealth.css (content/abouthealthreport/abouthealth.css) #endif - content/browser/aboutaccounts/aboutaccounts.xhtml (content/aboutaccounts/aboutaccounts.xhtml) - content/browser/aboutaccounts/aboutaccounts.js (content/aboutaccounts/aboutaccounts.js) - content/browser/aboutaccounts/aboutaccounts.css (content/aboutaccounts/aboutaccounts.css) - content/browser/aboutaccounts/main.css (content/aboutaccounts/main.css) - content/browser/aboutaccounts/normalize.css (content/aboutaccounts/normalize.css) - content/browser/aboutaccounts/images/fox.png (content/aboutaccounts/images/fox.png) - content/browser/aboutaccounts/images/graphic_sync_intro.png (content/aboutaccounts/images/graphic_sync_intro.png) - content/browser/aboutaccounts/images/graphic_sync_intro@2x.png (content/aboutaccounts/images/graphic_sync_intro@2x.png) - - content/browser/aboutTabCrashed.css (content/aboutTabCrashed.css) content/browser/aboutTabCrashed.js (content/aboutTabCrashed.js) content/browser/aboutTabCrashed.xhtml (content/aboutTabCrashed.xhtml) @@ -73,17 +63,15 @@ browser.jar: content/browser/browser-feeds.js (content/browser-feeds.js) content/browser/browser-fullScreenAndPointerLock.js (content/browser-fullScreenAndPointerLock.js) content/browser/browser-fullZoom.js (content/browser-fullZoom.js) - content/browser/browser-fxaccounts.js (content/browser-fxaccounts.js) content/browser/browser-gestureSupport.js (content/browser-gestureSupport.js) * content/browser/browser-media.js (content/browser-media.js) - content/browser/browser-places.js (content/browser-places.js) +* content/browser/browser-places.js (content/browser-places.js) content/browser/browser-plugins.js (content/browser-plugins.js) content/browser/browser-refreshblocker.js (content/browser-refreshblocker.js) #ifdef MOZ_SAFE_BROWSING content/browser/browser-safebrowsing.js (content/browser-safebrowsing.js) #endif content/browser/browser-sidebar.js (content/browser-sidebar.js) -* content/browser/browser-syncui.js (content/browser-syncui.js) * content/browser/browser-tabPreviews.xml (content/browser-tabPreviews.xml) #ifdef CAN_DRAW_IN_TITLEBAR content/browser/browser-tabsintitlebar.js (content/browser-tabsintitlebar.js) @@ -132,23 +120,6 @@ browser.jar: content/browser/pageinfo/feeds.xml (content/pageinfo/feeds.xml) content/browser/pageinfo/permissions.js (content/pageinfo/permissions.js) content/browser/pageinfo/security.js (content/pageinfo/security.js) - content/browser/sync/aboutSyncTabs.xul (content/sync/aboutSyncTabs.xul) -* content/browser/sync/aboutSyncTabs.js (content/sync/aboutSyncTabs.js) - content/browser/sync/aboutSyncTabs.css (content/sync/aboutSyncTabs.css) - content/browser/sync/aboutSyncTabs-bindings.xml (content/sync/aboutSyncTabs-bindings.xml) - content/browser/sync/setup.xul (content/sync/setup.xul) - content/browser/sync/addDevice.js (content/sync/addDevice.js) - content/browser/sync/addDevice.xul (content/sync/addDevice.xul) - content/browser/sync/setup.js (content/sync/setup.js) - content/browser/sync/genericChange.xul (content/sync/genericChange.xul) - content/browser/sync/genericChange.js (content/sync/genericChange.js) - content/browser/sync/key.xhtml (content/sync/key.xhtml) - content/browser/sync/utils.js (content/sync/utils.js) - content/browser/sync/customize.xul (content/sync/customize.xul) - content/browser/sync/customize.js (content/sync/customize.js) - content/browser/sync/customize.css (content/sync/customize.css) - content/browser/sync/quota.xul (content/sync/quota.xul) - content/browser/sync/quota.js (content/sync/quota.js) content/browser/safeMode.css (content/safeMode.css) content/browser/safeMode.js (content/safeMode.js) content/browser/safeMode.xul (content/safeMode.xul) diff --git a/application/basilisk/components/about/AboutRedirector.cpp b/application/basilisk/components/about/AboutRedirector.cpp index 2b8608484..d52b063e2 100644 --- a/application/basilisk/components/about/AboutRedirector.cpp +++ b/application/basilisk/components/about/AboutRedirector.cpp @@ -92,10 +92,16 @@ static RedirEntry kRedirMap[] = { "welcomeback", "chrome://browser/content/aboutWelcomeBack.xhtml", nsIAboutModule::ALLOW_SCRIPT }, +#ifdef MOZ_SERVICES_SYNC + { + "sync-progress", "chrome://browser/content/sync/progress.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, { "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul", nsIAboutModule::ALLOW_SCRIPT }, +#endif { "home", "chrome://browser/content/abouthome/aboutHome.xhtml", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::URI_MUST_LOAD_IN_CHILD | @@ -123,10 +129,6 @@ static RedirEntry kRedirMap[] = { }, #endif { - "accounts", "chrome://browser/content/aboutaccounts/aboutaccounts.xhtml", - nsIAboutModule::ALLOW_SCRIPT - }, - { "reader", "chrome://global/content/reader/aboutReader.html", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::ALLOW_SCRIPT | diff --git a/application/basilisk/components/build/nsModule.cpp b/application/basilisk/components/build/nsModule.cpp index 4e082ab6c..3fdde8823 100644 --- a/application/basilisk/components/build/nsModule.cpp +++ b/application/basilisk/components/build/nsModule.cpp @@ -97,12 +97,14 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = { { NS_ABOUT_MODULE_CONTRACTID_PREFIX "searchreset", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "welcomeback", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, +#ifdef MOZ_SERVICES_SYNC { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, + { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-progress", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, +#endif { NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "preferences", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "downloads", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, - { NS_ABOUT_MODULE_CONTRACTID_PREFIX "accounts", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, #ifdef MOZ_SERVICES_HEALTHREPORT { NS_ABOUT_MODULE_CONTRACTID_PREFIX "healthreport", &kNS_BROWSER_ABOUT_REDIRECTOR_CID }, #endif diff --git a/application/basilisk/components/customizableui/CustomizableUI.jsm b/application/basilisk/components/customizableui/CustomizableUI.jsm index cb0f519b2..31126b37c 100644 --- a/application/basilisk/components/customizableui/CustomizableUI.jsm +++ b/application/basilisk/components/customizableui/CustomizableUI.jsm @@ -200,7 +200,6 @@ var CustomizableUIInternal = { "find-button", "preferences-button", "add-ons-button", - "sync-button", ]; if (!AppConstants.MOZ_DEV_EDITION) { diff --git a/application/basilisk/components/customizableui/CustomizableWidgets.jsm b/application/basilisk/components/customizableui/CustomizableWidgets.jsm index 401b7ca74..9e8f0ec78 100644 --- a/application/basilisk/components/customizableui/CustomizableWidgets.jsm +++ b/application/basilisk/components/customizableui/CustomizableWidgets.jsm @@ -286,144 +286,6 @@ const CustomizableWidgets = [ log.debug("History view is being hidden!"); } }, { - id: "sync-button", - label: "remotetabs-panelmenu.label", - tooltiptext: "remotetabs-panelmenu.tooltiptext2", - type: "view", - viewId: "PanelUI-remotetabs", - defaultArea: CustomizableUI.AREA_PANEL, - deckIndices: { - DECKINDEX_TABS: 0, - DECKINDEX_TABSDISABLED: 1, - DECKINDEX_FETCHING: 2, - DECKINDEX_NOCLIENTS: 3, - }, - onCreated(aNode) { - // Add an observer to the button so we get the animation during sync. - // (Note the observer sets many attributes, including label and - // tooltiptext, but we only want the 'syncstatus' attribute for the - // animation) - let doc = aNode.ownerDocument; - let obnode = doc.createElementNS(kNSXUL, "observes"); - obnode.setAttribute("element", "sync-status"); - obnode.setAttribute("attribute", "syncstatus"); - aNode.appendChild(obnode); - }, - setDeckIndex(index) { - let deck = this._tabsList.ownerDocument.getElementById("PanelUI-remotetabs-deck"); - // We call setAttribute instead of relying on the XBL property setter due - // to things going wrong when we try and set the index before the XBL - // binding has been created - see bug 1241851 for the gory details. - deck.setAttribute("selectedIndex", index); - }, - - _showTabsPromise: Promise.resolve(), - // Update the tab list after any existing in-flight updates are complete. - _showTabs() { - this._showTabsPromise = this._showTabsPromise.then(() => { - return this.__showTabs(); - }); - }, - // Return a new promise to update the tab list. - __showTabs() { - let doc = this._tabsList.ownerDocument; - return SyncedTabs.getTabClients().then(clients => { - // The view may have been hidden while the promise was resolving. - if (!this._tabsList) { - return; - } - if (clients.length === 0 && !SyncedTabs.hasSyncedThisSession) { - // the "fetching tabs" deck is being shown - let's leave it there. - // When that first sync completes we'll be notified and update. - return; - } - - if (clients.length === 0) { - this.setDeckIndex(this.deckIndices.DECKINDEX_NOCLIENTS); - return; - } - - this.setDeckIndex(this.deckIndices.DECKINDEX_TABS); - this._clearTabList(); - SyncedTabs.sortTabClientsByLastUsed(clients, 50 /* maxTabs */); - let fragment = doc.createDocumentFragment(); - - for (let client of clients) { - // add a menu separator for all clients other than the first. - if (fragment.lastChild) { - let separator = doc.createElementNS(kNSXUL, "menuseparator"); - fragment.appendChild(separator); - } - this._appendClient(client, fragment); - } - this._tabsList.appendChild(fragment); - }).catch(err => { - Cu.reportError(err); - }).then(() => { - // an observer for tests. - Services.obs.notifyObservers(null, "synced-tabs-menu:test:tabs-updated", null); - }); - }, - _clearTabList () { - let list = this._tabsList; - while (list.lastChild) { - list.lastChild.remove(); - } - }, - _showNoClientMessage() { - this._appendMessageLabel("notabslabel"); - }, - _appendMessageLabel(messageAttr, appendTo = null) { - if (!appendTo) { - appendTo = this._tabsList; - } - let message = this._tabsList.getAttribute(messageAttr); - let doc = this._tabsList.ownerDocument; - let messageLabel = doc.createElementNS(kNSXUL, "label"); - messageLabel.textContent = message; - appendTo.appendChild(messageLabel); - return messageLabel; - }, - _appendClient: function (client, attachFragment) { - let doc = attachFragment.ownerDocument; - // Create the element for the remote client. - let clientItem = doc.createElementNS(kNSXUL, "label"); - clientItem.setAttribute("itemtype", "client"); - let window = doc.defaultView; - clientItem.setAttribute("tooltiptext", - window.gSyncUI.formatLastSyncDate(new Date(client.lastModified))); - clientItem.textContent = client.name; - - attachFragment.appendChild(clientItem); - - if (client.tabs.length == 0) { - let label = this._appendMessageLabel("notabsforclientlabel", attachFragment); - label.setAttribute("class", "PanelUI-remotetabs-notabsforclient-label"); - } else { - for (let tab of client.tabs) { - let tabEnt = this._createTabElement(doc, tab); - attachFragment.appendChild(tabEnt); - } - } - }, - _createTabElement(doc, tabInfo) { - let item = doc.createElementNS(kNSXUL, "toolbarbutton"); - let tooltipText = (tabInfo.title ? tabInfo.title + "\n" : "") + tabInfo.url; - item.setAttribute("itemtype", "tab"); - item.setAttribute("class", "subviewbutton"); - item.setAttribute("targetURI", tabInfo.url); - item.setAttribute("label", tabInfo.title != "" ? tabInfo.title : tabInfo.url); - item.setAttribute("image", tabInfo.icon); - item.setAttribute("tooltiptext", tooltipText); - // We need to use "click" instead of "command" here so openUILink - // respects different buttons (eg, to open in a new tab). - item.addEventListener("click", e => { - doc.defaultView.openUILink(tabInfo.url, e); - CustomizableUI.hidePanelForNode(item); - }); - return item; - }, - }, { id: "privatebrowsing-button", shortcutId: "key_privatebrowsing", defaultArea: CustomizableUI.AREA_PANEL, diff --git a/application/basilisk/components/customizableui/content/panelUI.inc.xul b/application/basilisk/components/customizableui/content/panelUI.inc.xul index 8ebd93327..da8077554 100644 --- a/application/basilisk/components/customizableui/content/panelUI.inc.xul +++ b/application/basilisk/components/customizableui/content/panelUI.inc.xul @@ -20,27 +20,6 @@ oncommand="gMenuButtonUpdateBadge.onMenuPanelCommand(event);" wrap="true" hidden="true"/> - <hbox id="PanelUI-footer-fxa"> - <hbox id="PanelUI-fxa-status" - defaultlabel="&fxaSignIn.label;" - signedinTooltiptext="&syncSettings.label;" - tooltiptext="&syncSettings.label;" - errorlabel="&fxaSignInError.label;" - unverifiedlabel="&fxaUnverified.label;" - settingslabel="&syncSettings.label;" - onclick="if (event.which == 1) gFxAccounts.onMenuPanelCommand();"> - <image id="PanelUI-fxa-avatar"/> - <toolbarbutton id="PanelUI-fxa-label" - fxabrandname="&syncBrand.fxAccount.label;"/> - </hbox> - <toolbarseparator/> - <toolbarbutton id="PanelUI-fxa-icon" - oncommand="gSyncUI.doSync();" - closemenu="none"> - <observes element="sync-status" attribute="syncstatus"/> - <observes element="sync-status" attribute="tooltiptext"/> - </toolbarbutton> - </hbox> <hbox id="PanelUI-footer-inner"> <toolbarbutton id="PanelUI-customize" label="&appMenuCustomize.label;" @@ -103,95 +82,6 @@ oncommand="PlacesCommandHook.showPlacesOrganizer('History'); CustomizableUI.hidePanelForNode(this);"/> </panelview> - <panelview id="PanelUI-remotetabs" flex="1" class="PanelUI-subView"> - <label value="&appMenuRemoteTabs.label;" class="panel-subview-header"/> - <vbox class="panel-subview-body"> - <!-- this widget has 3 boxes in the body, but only 1 is ever visible --> - <!-- When Sync is ready to sync --> - <vbox id="PanelUI-remotetabs-main" observes="sync-syncnow-state"> - <vbox id="PanelUI-remotetabs-buttons"> - <toolbarbutton id="PanelUI-remotetabs-view-sidebar" - class="subviewbutton" - oncommand="BrowserOpenSyncTabs();" - label="&appMenuRemoteTabs.sidebar.label;"/> - <toolbarbutton id="PanelUI-remotetabs-syncnow" - observes="sync-status" - class="subviewbutton" - oncommand="gSyncUI.doSync();" - closemenu="none"/> - <menuseparator id="PanelUI-remotetabs-separator"/> - </vbox> - <deck id="PanelUI-remotetabs-deck"> - <!-- Sync is ready to Sync and the "tabs" engine is enabled --> - <vbox id="PanelUI-remotetabs-tabspane"> - <vbox id="PanelUI-remotetabs-tabslist" - notabsforclientlabel="&appMenuRemoteTabs.notabs.label;" - /> - </vbox> - <!-- Sync is ready to Sync but the "tabs" engine isn't enabled--> - <hbox id="PanelUI-remotetabs-tabsdisabledpane" pack="center" flex="1"> - <vbox class="PanelUI-remotetabs-instruction-box"> - <hbox pack="center"> - <image class="fxaSyncIllustration" alt=""/> - </hbox> - <label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.tabsnotsyncing.label;</label> - <hbox pack="center"> - <toolbarbutton class="PanelUI-remotetabs-prefs-button" - label="&appMenuRemoteTabs.openprefs.label;" - oncommand="gSyncUI.openSetup(null, 'synced-tabs');"/> - </hbox> - </vbox> - </hbox> - <!-- Sync is ready to Sync but we are still fetching the tabs to show --> - <vbox id="PanelUI-remotetabs-fetching"> - <!-- Show intentionally blank panel, see bug 1239845 --> - </vbox> - <!-- Sync has only 1 (ie, this) device connected --> - <hbox id="PanelUI-remotetabs-nodevicespane" pack="center" flex="1"> - <vbox class="PanelUI-remotetabs-instruction-box"> - <hbox pack="center"> - <image class="fxaSyncIllustration" alt=""/> - </hbox> - <label class="PanelUI-remotetabs-instruction-title">&appMenuRemoteTabs.noclients.title;</label> - <label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.noclients.subtitle;</label> - <!-- The inner HTML for PanelUI-remotetabs-mobile-promo is built at runtime --> - <label id="PanelUI-remotetabs-mobile-promo" fxAccountsBrand="&syncBrand.fxAccount.label;"/> - </vbox> - </hbox> - </deck> - </vbox> - <!-- a box to ensure contained boxes are centered horizonally --> - <hbox pack="center" flex="1"> - <!-- When Sync is not configured --> - <vbox id="PanelUI-remotetabs-setupsync" - flex="1" - align="center" - class="PanelUI-remotetabs-instruction-box" - observes="sync-setup-state"> - <image class="fxaSyncIllustration" alt=""/> - <label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.notsignedin.label;</label> - <toolbarbutton class="PanelUI-remotetabs-prefs-button" - label="&appMenuRemoteTabs.signin.label;" - oncommand="gSyncUI.openSetup(null, 'synced-tabs');"/> - </vbox> - <!-- When Sync needs re-authentication. This uses the exact same messaging - as "Sync is not configured" but remains a separate box so we get - the goodness of observing broadcasters to manage the hidden states --> - <vbox id="PanelUI-remotetabs-reauthsync" - flex="1" - align="center" - class="PanelUI-remotetabs-instruction-box" - observes="sync-reauth-state"> - <image class="fxaSyncIllustration" alt=""/> - <label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.notsignedin.label;</label> - <toolbarbutton class="PanelUI-remotetabs-prefs-button" - label="&appMenuRemoteTabs.signin.label;" - oncommand="gSyncUI.openSetup(null, 'synced-tabs');"/> - </vbox> - </hbox> - </vbox> - </panelview> - <panelview id="PanelUI-bookmarks" flex="1" class="PanelUI-subView"> <label value="&bookmarksMenu.label;" class="panel-subview-header"/> <vbox class="panel-subview-body"> diff --git a/application/basilisk/components/customizableui/moz.build b/application/basilisk/components/customizableui/moz.build index 034630dc9..5797a03b0 100644 --- a/application/basilisk/components/customizableui/moz.build +++ b/application/basilisk/components/customizableui/moz.build @@ -9,7 +9,6 @@ DIRS += [ ] EXTRA_JS_MODULES += [ - 'CustomizableUI.jsm', 'CustomizableWidgets.jsm', 'CustomizeMode.jsm', 'DragPositionManager.jsm', @@ -17,5 +16,9 @@ EXTRA_JS_MODULES += [ 'ScrollbarSampler.jsm', ] +EXTRA_PP_JS_MODULES += [ + 'CustomizableUI.jsm', +] + if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'): DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1 diff --git a/application/basilisk/components/moz.build b/application/basilisk/components/moz.build index 65e8beb76..6c6cca9df 100644 --- a/application/basilisk/components/moz.build +++ b/application/basilisk/components/moz.build @@ -19,7 +19,7 @@ DIRS += [ 'sessionstore', 'shell', 'selfsupport', - 'syncedtabs', + 'sync', 'translation', ] @@ -35,6 +35,9 @@ XPIDL_MODULE = 'browsercompsbase' EXTRA_COMPONENTS += [ 'BrowserComponents.manifest', 'nsBrowserContentHandler.js', +] + +EXTRA_PP_COMPONENTS += [ 'nsBrowserGlue.js', ] diff --git a/application/basilisk/components/nsBrowserGlue.js b/application/basilisk/components/nsBrowserGlue.js index d77e97f87..82de33240 100644 --- a/application/basilisk/components/nsBrowserGlue.js +++ b/application/basilisk/components/nsBrowserGlue.js @@ -143,6 +143,7 @@ BrowserGlue.prototype = { Services.prefs.savePrefFile(null); }, +#ifdef MOZ_SERVICES_SYNC _setSyncAutoconnectDelay: function BG__setSyncAutoconnectDelay() { // Assume that a non-zero value for services.sync.autoconnectDelay should override if (Services.prefs.prefHasUserValue("services.sync.autoconnectDelay")) { @@ -164,6 +165,7 @@ BrowserGlue.prototype = { Cu.import("resource://services-sync/main.js"); Weave.Service.scheduler.delayedAutoConnect(delay); }, +#endif // nsIObserver implementation observe: function BG_observe(subject, topic, data) { @@ -210,18 +212,14 @@ BrowserGlue.prototype = { this._setPrefToSaveSession(); } break; +#ifdef MOZ_SERVICES_SYNC case "weave:service:ready": this._setSyncAutoconnectDelay(); break; - case "fxaccounts:onverified": - this._showSyncStartedDoorhanger(); - break; - case "fxaccounts:device_disconnected": - this._onDeviceDisconnected(); - break; - case "weave:engine:clients:display-uris": - this._onDisplaySyncURIs(subject); - break; + case "weave:engine:clients:display-uri": + this._onDisplaySyncURI(subject); + break; +#endif case "session-save": this._setPrefToSaveSession(true); subject.QueryInterface(Ci.nsISupportsPRBool); @@ -428,10 +426,10 @@ BrowserGlue.prototype = { os.addObserver(this, "browser-lastwindow-close-requested", false); os.addObserver(this, "browser-lastwindow-close-granted", false); } +#ifdef MOZ_SERVICES_SYNC 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); +#endif os.addObserver(this, "session-save", false); os.addObserver(this, "places-init-complete", false); this._isPlacesInitObserver = true; @@ -479,10 +477,10 @@ BrowserGlue.prototype = { os.removeObserver(this, "browser-lastwindow-close-requested"); os.removeObserver(this, "browser-lastwindow-close-granted"); } +#ifdef MOZ_SERVICES_SYNC 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"); +#endif os.removeObserver(this, "session-save"); if (this._bookmarksBackupIdleTime) { this._idleService.removeIdleObserver(this, this._bookmarksBackupIdleTime); @@ -2274,90 +2272,29 @@ BrowserGlue.prototype = { chromeWindow.openPreferences(...args); }, +#ifdef MOZ_SERVICES_SYNC /** - * 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 URI in a background tab. * - * We open the received URIs in background tabs. + * 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 { - // 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(); + let tabbrowser = RecentWindow.getMostRecentBrowserWindow({private: false}).gBrowser; - 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) { - // Due to bug 1305895, tabs from iOS may not have device information, so - // we have separate strings to handle those cases. (See Also - // unnamedTabsArrivingNotificationNoDevice.body below) - if (deviceName) { - title = bundle.formatStringFromName("tabArrivingNotificationWithDevice.title", [deviceName], 1); - } else { - title = bundle.GetStringFromName("tabArrivingNotification.title"); - } - // Use the page URL as the body. We strip the fragment and query to - // reduce size, and also format it the same way that the url bar would. - body = URIs[0].uri.replace(/[?#].*$/, ""); - if (win.gURLBar) { - body = win.gURLBar.trimValue(body); - } - } else { - title = bundle.GetStringFromName("tabsArrivingNotification.title"); - const allSameDevice = URIs.every(URI => URI.clientId == URIs[0].clientId); - const unknownDevice = allSameDevice && !deviceName; - let tabArrivingBody; - if (unknownDevice) { - tabArrivingBody = "unnamedTabsArrivingNotificationNoDevice.body"; - } else if (allSameDevice) { - tabArrivingBody = "unnamedTabsArrivingNotification2.body"; - } else { - tabArrivingBody = "unnamedTabsArrivingNotificationMultiple2.body" - } - - body = bundle.GetStringFromName(tabArrivingBody); - body = PluralForm.get(URIs.length, body); - body = body.replace("#1", URIs.length); - body = body.replace("#2", deviceName); - } - - const clickCallback = (subject, topic, data) => { - if (topic == "alertclickcallback") { - win.gBrowser.selectedTab = firstTab; - } - } - - // Specify an icon because on Windows no icon is shown at the moment - let imageURL; - if (AppConstants.platform == "win") { - imageURL = "chrome://branding/content/icon64.png"; - } - AlertsService.showAlertNotification(imageURL, title, body, true, null, clickCallback); + // The payload is wrapped weirdly because of how Sync does notifications. + 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); } }, +#endif _onDeviceDisconnected() { let bundle = Services.strings.createBundle("chrome://browser/locale/accounts.properties"); diff --git a/application/basilisk/components/places/PlacesUIUtils.jsm b/application/basilisk/components/places/PlacesUIUtils.jsm index 17fa276aa..035fc12c2 100644 --- a/application/basilisk/components/places/PlacesUIUtils.jsm +++ b/application/basilisk/components/places/PlacesUIUtils.jsm @@ -1418,9 +1418,9 @@ this.PlacesUIUtils = { }, shouldShowTabsFromOtherComputersMenuitem: function() { - let weaveOK = Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED && - Weave.Svc.Prefs.get("firstSync", "") != "notReady"; - return weaveOK; +#ifdef MOZ_SERVICES_SYNC + // Weave code to enable menu item +#endif }, /** diff --git a/application/basilisk/components/places/moz.build b/application/basilisk/components/places/moz.build index 9e5a2c074..ea6d43538 100644 --- a/application/basilisk/components/places/moz.build +++ b/application/basilisk/components/places/moz.build @@ -6,6 +6,6 @@ JAR_MANIFESTS += ['jar.mn'] -EXTRA_JS_MODULES += [ +EXTRA_PP_JS_MODULES += [ 'PlacesUIUtils.jsm', ] diff --git a/application/basilisk/components/preferences/in-content/jar.mn b/application/basilisk/components/preferences/in-content/jar.mn index 70544f332..21f5ccf38 100644 --- a/application/basilisk/components/preferences/in-content/jar.mn +++ b/application/basilisk/components/preferences/in-content/jar.mn @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. browser.jar: - content/browser/preferences/in-content/preferences.js +* content/browser/preferences/in-content/preferences.js * content/browser/preferences/in-content/preferences.xul content/browser/preferences/in-content/subdialogs.js @@ -12,6 +12,8 @@ browser.jar: content/browser/preferences/in-content/advanced.js content/browser/preferences/in-content/applications.js * content/browser/preferences/in-content/content.js +#ifdef MOZ_SERVICES_SYNC content/browser/preferences/in-content/sync.js +#endif * content/browser/preferences/in-content/security.js content/browser/preferences/in-content/search.js diff --git a/application/basilisk/components/preferences/in-content/preferences.js b/application/basilisk/components/preferences/in-content/preferences.js index 35e10c58d..69cb180d5 100644 --- a/application/basilisk/components/preferences/in-content/preferences.js +++ b/application/basilisk/components/preferences/in-content/preferences.js @@ -64,7 +64,9 @@ function init_all() { register_module("paneAdvanced", gAdvancedPane); register_module("paneApplications", gApplicationsPane); register_module("paneContent", gContentPane); +#ifdef MOZ_SERVICES_SYNC register_module("paneSync", gSyncPane); +#endif register_module("paneSecurity", gSecurityPane); let categories = document.getElementById("categories"); diff --git a/application/basilisk/components/preferences/in-content/preferences.xul b/application/basilisk/components/preferences/in-content/preferences.xul index 093516140..61639aa19 100644 --- a/application/basilisk/components/preferences/in-content/preferences.xul +++ b/application/basilisk/components/preferences/in-content/preferences.xul @@ -22,8 +22,10 @@ <!ENTITY % privacyDTD SYSTEM "chrome://browser/locale/preferences/privacy.dtd"> <!ENTITY % tabsDTD SYSTEM "chrome://browser/locale/preferences/tabs.dtd"> <!ENTITY % searchDTD SYSTEM "chrome://browser/locale/preferences/search.dtd"> +#ifdef MOZ_SERVICES_SYNC <!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> <!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd"> +#endif <!ENTITY % securityDTD SYSTEM "chrome://browser/locale/preferences/security.dtd"> <!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd"> @@ -40,8 +42,10 @@ %privacyDTD; %tabsDTD; %searchDTD; +#ifdef MOZ_SERVICES_SYNC %syncBrandDTD; %syncDTD; +#endif %securityDTD; %sanitizeDTD; %mainDTD; @@ -140,6 +144,7 @@ <label class="category-name" flex="1">&paneSecurity.title;</label> </richlistitem> +#ifdef MOZ_SERVICES_SYNC <richlistitem id="category-sync" class="category" value="paneSync" @@ -149,6 +154,7 @@ <image class="category-icon"/> <label class="category-name" flex="1">&paneSync.title;</label> </richlistitem> +#endif <richlistitem id="category-advanced" class="category" @@ -177,7 +183,9 @@ #include applications.xul #include content.xul #include security.xul +#ifdef MOZ_SERVICES_SYNC #include sync.xul +#endif </prefpane> </vbox> diff --git a/application/basilisk/components/preferences/in-content/sync.js b/application/basilisk/components/preferences/in-content/sync.js index 2600677a8..917b5f123 100644 --- a/application/basilisk/components/preferences/in-content/sync.js +++ b/application/basilisk/components/preferences/in-content/sync.js @@ -1,32 +1,16 @@ /* 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/. */ + * 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/. */ Components.utils.import("resource://services-sync/main.js"); Components.utils.import("resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () { - return Components.utils.import("resource://gre/modules/FxAccountsCommon.js", {}); -}); - -XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", - "resource://gre/modules/FxAccounts.jsm"); - const PAGE_NO_ACCOUNT = 0; const PAGE_HAS_ACCOUNT = 1; const PAGE_NEEDS_UPDATE = 2; -const FXA_PAGE_LOGGED_OUT = 3; -const FXA_PAGE_LOGGED_IN = 4; - -// Indexes into the "login status" deck. -// We are in a successful verified state - everything should work! -const FXA_LOGIN_VERIFIED = 0; -// We have logged in to an unverified account. -const FXA_LOGIN_UNVERIFIED = 1; -// We are logged in locally, but the server rejected our credentials. -const FXA_LOGIN_FAILED = 2; var gSyncPane = { + _stringBundle: null, prefArray: ["engine.bookmarks", "engine.passwords", "engine.prefs", "engine.tabs", "engine.history"], @@ -45,13 +29,11 @@ var gSyncPane = { needsUpdate: function () { this.page = PAGE_NEEDS_UPDATE; let label = document.getElementById("loginError"); - label.textContent = Weave.Utils.getErrorString(Weave.Status.login); + label.value = Weave.Utils.getErrorString(Weave.Status.login); label.className = "error"; }, init: function () { - this._setupEventListeners(); - // If the Service hasn't finished initializing, wait for it. let xps = Components.classes["@mozilla.org/weave/service;1"] .getService(Components.interfaces.nsISupports) @@ -62,10 +44,6 @@ var gSyncPane = { return; } - // it may take some time before we can determine what provider to use - // and the state of that provider, so show the "please wait" page. - this._showLoadPage(xps); - let onUnload = function () { window.removeEventListener("unload", onUnload, false); try { @@ -85,247 +63,50 @@ var gSyncPane = { xps.ensureLoaded(); }, - _showLoadPage: function (xps) { - let username; - try { - username = Services.prefs.getCharPref("services.sync.username"); - } catch (e) {} - if (!username) { - this.page = FXA_PAGE_LOGGED_OUT; - } else if (xps.fxAccountsEnabled) { - // Use cached values while we wait for the up-to-date values - let cachedComputerName; - try { - cachedComputerName = Services.prefs.getCharPref("services.sync.client.name"); - } - catch (e) { - cachedComputerName = ""; - } - document.getElementById("fxaEmailAddress1").textContent = username; - this._populateComputerName(cachedComputerName); - this.page = FXA_PAGE_LOGGED_IN; - } else { // Old Sync - this.page = PAGE_HAS_ACCOUNT; - } - }, - _init: function () { let topics = ["weave:service:login:error", "weave:service:login:finish", - "weave:service:start-over:finish", + "weave:service:start-over", "weave:service:setup-complete", - "weave:service:logout:finish", - FxAccountsCommon.ONVERIFIED_NOTIFICATION, - FxAccountsCommon.ONLOGIN_NOTIFICATION, - FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION, - ]; + "weave:service:logout:finish"]; + // Add the observers now and remove them on unload - // XXXzpao This should use Services.obs.* but Weave's Obs does nice handling + //XXXzpao This should use Services.obs.* but Weave's Obs does nice handling // of `this`. Fix in a followup. (bug 583347) topics.forEach(function (topic) { Weave.Svc.Obs.add(topic, this.updateWeavePrefs, this); }, this); - window.addEventListener("unload", function() { topics.forEach(function (topic) { Weave.Svc.Obs.remove(topic, this.updateWeavePrefs, this); }, gSyncPane); }, false); - XPCOMUtils.defineLazyGetter(this, '_stringBundle', () => { - return Services.strings.createBundle("chrome://browser/locale/preferences/preferences.properties"); - }); - - XPCOMUtils.defineLazyGetter(this, '_accountsStringBundle', () => { - return Services.strings.createBundle("chrome://browser/locale/accounts.properties"); - }); - - let url = Services.prefs.getCharPref("identity.mobilepromo.android") + "sync-preferences"; - document.getElementById("fxaMobilePromo-android").setAttribute("href", url); - document.getElementById("fxaMobilePromo-android-hasFxaAccount").setAttribute("href", url); - url = Services.prefs.getCharPref("identity.mobilepromo.ios") + "sync-preferences"; - document.getElementById("fxaMobilePromo-ios").setAttribute("href", url); - document.getElementById("fxaMobilePromo-ios-hasFxaAccount").setAttribute("href", url); - - document.getElementById("tosPP-small-ToS").setAttribute("href", gSyncUtils.tosURL); - document.getElementById("tosPP-normal-ToS").setAttribute("href", gSyncUtils.tosURL); - document.getElementById("tosPP-small-PP").setAttribute("href", gSyncUtils.privacyPolicyURL); - document.getElementById("tosPP-normal-PP").setAttribute("href", gSyncUtils.privacyPolicyURL); - - fxAccounts.promiseAccountsManageURI(this._getEntryPoint()).then(url => { - document.getElementById("verifiedManage").setAttribute("href", url); - }); - + this._stringBundle = + Services.strings.createBundle("chrome://browser/locale/preferences/preferences.properties"); this.updateWeavePrefs(); - - this._initProfileImageUI(); - }, - - _toggleComputerNameControls: function(editMode) { - let textbox = document.getElementById("fxaSyncComputerName"); - textbox.disabled = !editMode; - document.getElementById("fxaChangeDeviceName").hidden = editMode; - document.getElementById("fxaCancelChangeDeviceName").hidden = !editMode; - document.getElementById("fxaSaveChangeDeviceName").hidden = !editMode; - }, - - _focusComputerNameTextbox: function() { - let textbox = document.getElementById("fxaSyncComputerName"); - let valLength = textbox.value.length; - textbox.focus(); - textbox.setSelectionRange(valLength, valLength); - }, - - _blurComputerNameTextbox: function() { - document.getElementById("fxaSyncComputerName").blur(); - }, - - _focusAfterComputerNameTextbox: function() { - // Focus the most appropriate element that's *not* the "computer name" box. - Services.focus.moveFocus(window, - document.getElementById("fxaSyncComputerName"), - Services.focus.MOVEFOCUS_FORWARD, 0); - }, - - _updateComputerNameValue: function(save) { - if (save) { - let textbox = document.getElementById("fxaSyncComputerName"); - Weave.Service.clientsEngine.localName = textbox.value; - } - this._populateComputerName(Weave.Service.clientsEngine.localName); - }, - - _setupEventListeners: function() { - function setEventListener(aId, aEventType, aCallback) - { - document.getElementById(aId) - .addEventListener(aEventType, aCallback.bind(gSyncPane)); - } - - setEventListener("noAccountSetup", "click", function (aEvent) { - aEvent.stopPropagation(); - gSyncPane.openSetup(null); - }); - setEventListener("noAccountPair", "click", function (aEvent) { - aEvent.stopPropagation(); - gSyncPane.openSetup('pair'); - }); - setEventListener("syncChangePassword", "command", - () => gSyncUtils.changePassword()); - setEventListener("syncResetPassphrase", "command", - () => gSyncUtils.resetPassphrase()); - setEventListener("syncReset", "command", gSyncPane.resetSync); - setEventListener("syncAddDeviceLabel", "click", function () { - gSyncPane.openAddDevice(); - return false; - }); - setEventListener("syncEnginesList", "select", function () { - if (this.selectedCount) - this.clearSelection(); - }); - setEventListener("syncComputerName", "change", function (e) { - gSyncUtils.changeName(e.target); - }); - setEventListener("fxaChangeDeviceName", "command", function () { - this._toggleComputerNameControls(true); - this._focusComputerNameTextbox(); - }); - setEventListener("fxaCancelChangeDeviceName", "command", function () { - // We explicitly blur the textbox because of bug 75324, then after - // changing the state of the buttons, force focus to whatever the focus - // manager thinks should be next (which on the mac, depends on an OSX - // keyboard access preference) - this._blurComputerNameTextbox(); - this._toggleComputerNameControls(false); - this._updateComputerNameValue(false); - this._focusAfterComputerNameTextbox(); - }); - setEventListener("fxaSaveChangeDeviceName", "command", function () { - // Work around bug 75324 - see above. - this._blurComputerNameTextbox(); - this._toggleComputerNameControls(false); - this._updateComputerNameValue(true); - this._focusAfterComputerNameTextbox(); - }); - setEventListener("unlinkDevice", "click", function () { - gSyncPane.startOver(true); - return false; - }); - setEventListener("loginErrorUpdatePass", "click", function () { - gSyncPane.updatePass(); - return false; - }); - setEventListener("loginErrorResetPass", "click", function () { - gSyncPane.resetPass(); - return false; - }); - setEventListener("loginErrorStartOver", "click", function () { - gSyncPane.startOver(true); - return false; - }); - setEventListener("noFxaSignUp", "command", function () { - gSyncPane.signUp(); - return false; - }); - setEventListener("noFxaSignIn", "command", function () { - gSyncPane.signIn(); - return false; - }); - setEventListener("fxaUnlinkButton", "command", function () { - gSyncPane.unlinkFirefoxAccount(true); - }); - setEventListener("verifyFxaAccount", "command", - gSyncPane.verifyFirefoxAccount); - setEventListener("unverifiedUnlinkFxaAccount", "command", function () { - /* no warning as account can't have previously synced */ - gSyncPane.unlinkFirefoxAccount(false); - }); - setEventListener("rejectReSignIn", "command", - gSyncPane.reSignIn); - setEventListener("rejectUnlinkFxaAccount", "command", function () { - gSyncPane.unlinkFirefoxAccount(true); - }); - setEventListener("fxaSyncComputerName", "keypress", function (e) { - if (e.keyCode == KeyEvent.DOM_VK_RETURN) { - document.getElementById("fxaSaveChangeDeviceName").click(); - } else if (e.keyCode == KeyEvent.DOM_VK_ESCAPE) { - document.getElementById("fxaCancelChangeDeviceName").click(); - } - }); - }, - - _initProfileImageUI: function () { - try { - if (Services.prefs.getBoolPref("identity.fxaccounts.profile_image.enabled")) { - document.getElementById("fxaProfileImage").hidden = false; - } - } catch (e) { } + document.getElementById("weavePrefsDeck").setAttribute("hidden", ""); }, updateWeavePrefs: function () { - let service = Components.classes["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED || Weave.Svc.Prefs.get("firstSync", "") == "notReady") { this.page = PAGE_NO_ACCOUNT; - // else: sync was previously configured for the legacy provider, so we - // make the "old" panels available. } else if (Weave.Status.login == Weave.LOGIN_FAILED_INVALID_PASSPHRASE || Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) { this.needsUpdate(); } else { this.page = PAGE_HAS_ACCOUNT; - document.getElementById("accountName").textContent = Weave.Service.identity.account; + document.getElementById("accountName").value = Weave.Service.identity.account; document.getElementById("syncComputerName").value = Weave.Service.clientsEngine.localName; - document.getElementById("tosPP-normal").hidden = this._usingCustomServer; + document.getElementById("tosPP").hidden = this._usingCustomServer; } }, startOver: function (showDialog) { if (showDialog) { let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING + - Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL + + Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL + Services.prompt.BUTTON_POS_1_DEFAULT; let buttonChoice = Services.prompt.confirmEx(window, @@ -336,8 +117,9 @@ var gSyncPane = { null, null, null, {}); // If the user selects cancel, just bail - if (buttonChoice == 1) + if (buttonChoice == 1) { return; + } } Weave.Service.startOver(); @@ -345,33 +127,19 @@ var gSyncPane = { }, updatePass: function () { - if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) + if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) { gSyncUtils.changePassword(); - else + } else { gSyncUtils.updatePassphrase(); + } }, resetPass: function () { - if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) + if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) { gSyncUtils.resetPassword(); - else + } else { gSyncUtils.resetPassphrase(); - }, - - _getEntryPoint: function () { - let params = new URLSearchParams(document.URL.split("#")[0].split("?")[1] || ""); - return params.get("entrypoint") || "preferences"; - }, - - _openAboutAccounts: function(action) { - let entryPoint = this._getEntryPoint(); - let params = new URLSearchParams(); - if (action) { - params.set("action", action); } - params.set("entrypoint", entryPoint); - - this.replaceTabWithUrl("about:accounts?" + params); }, /** @@ -384,163 +152,16 @@ var gSyncPane = { * "reset" -- reset sync */ openSetup: function (wizardType) { - let service = Components.classes["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; - - if (service.fxAccountsEnabled) { - this._openAboutAccounts(); + let win = Services.wm.getMostRecentWindow("Weave:AccountSetup"); + if (win) { + win.focus(); } else { - let win = Services.wm.getMostRecentWindow("Weave:AccountSetup"); - if (win) - win.focus(); - else { - window.openDialog("chrome://browser/content/sync/setup.xul", - "weaveSetup", "centerscreen,chrome,resizable=no", - wizardType); - } - } - }, - - openContentInBrowser: function(url, options) { - let win = Services.wm.getMostRecentWindow("navigator:browser"); - if (!win) { - // no window to use, so use _openLink to create a new one. We don't - // always use that as it prefers to open a new window rather than use - // an existing one. - gSyncUtils._openLink(url); - return; - } - win.switchToTabHavingURI(url, true, options); - }, - - // Replace the current tab with the specified URL. - replaceTabWithUrl(url) { - // Get the <browser> element hosting us. - let browser = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell) - .chromeEventHandler; - // And tell it to load our URL. - browser.loadURI(url); - }, - - signUp: function() { - this._openAboutAccounts("signup"); - }, - - signIn: function() { - this._openAboutAccounts("signin"); - }, - - reSignIn: function() { - this._openAboutAccounts("reauth"); - }, - - - clickOrSpaceOrEnterPressed: function(event) { - // Note: charCode is deprecated, but 'char' not yet implemented. - // Replace charCode with char when implemented, see Bug 680830 - return ((event.type == "click" && event.button == 0) || - (event.type == "keypress" && - (event.charCode == KeyEvent.DOM_VK_SPACE || event.keyCode == KeyEvent.DOM_VK_RETURN))); - }, - - openChangeProfileImage: function(event) { - if (this.clickOrSpaceOrEnterPressed(event)) { - fxAccounts.promiseAccountsChangeProfileURI(this._getEntryPoint(), "avatar") - .then(url => { - this.openContentInBrowser(url, { - replaceQueryString: true - }); - }); - // Prevent page from scrolling on the space key. - event.preventDefault(); + window.openDialog("chrome://browser/content/sync/setup.xul", + "weaveSetup", "centerscreen,chrome,resizable=no", + wizardType); } }, - openManageFirefoxAccount: function(event) { - if (this.clickOrSpaceOrEnterPressed(event)) { - this.manageFirefoxAccount(); - // Prevent page from scrolling on the space key. - event.preventDefault(); - } - }, - - manageFirefoxAccount: function() { - fxAccounts.promiseAccountsManageURI(this._getEntryPoint()) - .then(url => { - this.openContentInBrowser(url, { - replaceQueryString: true - }); - }); - }, - - verifyFirefoxAccount: function() { - let showVerifyNotification = (data) => { - let isError = !data; - let maybeNot = isError ? "Not" : ""; - let sb = this._accountsStringBundle; - let title = sb.GetStringFromName("verification" + maybeNot + "SentTitle"); - let email = !isError && data ? data.email : ""; - let body = sb.formatStringFromName("verification" + maybeNot + "SentBody", [email], 1); - new Notification(title, { body }) - } - - let onError = () => { - showVerifyNotification(); - }; - - let onSuccess = data => { - if (data) { - showVerifyNotification(data); - } else { - onError(); - } - }; - - fxAccounts.resendVerificationEmail() - .then(fxAccounts.getSignedInUser, onError) - .then(onSuccess, onError); - }, - - openOldSyncSupportPage: function() { - let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "old-sync"; - this.openContentInBrowser(url); - }, - - unlinkFirefoxAccount: function(confirm) { - if (confirm) { - // We use a string bundle shared with aboutAccounts. - let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); - let disconnectLabel = sb.GetStringFromName("disconnect.label"); - let title = sb.GetStringFromName("disconnect.verify.title"); - let body = sb.GetStringFromName("disconnect.verify.bodyHeading") + - "\n\n" + - sb.GetStringFromName("disconnect.verify.bodyText"); - let ps = Services.prompt; - let buttonFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING) + - (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL) + - ps.BUTTON_POS_1_DEFAULT; - - let factory = Cc["@mozilla.org/prompter;1"] - .getService(Ci.nsIPromptFactory); - let prompt = factory.getPrompt(window, Ci.nsIPrompt); - let bag = prompt.QueryInterface(Ci.nsIWritablePropertyBag2); - bag.setPropertyAsBool("allowTabModal", true); - - let pressed = prompt.confirmEx(title, body, buttonFlags, - disconnectLabel, null, null, null, {}); - - if (pressed != 0) { // 0 is the "continue" button - return; - } - } - fxAccounts.signOut().then(() => { - this.updateWeavePrefs(); - }); - }, - openQuotaDialog: function () { let win = Services.wm.getMostRecentWindow("Sync:ViewQuota"); if (win) { @@ -552,27 +173,21 @@ var gSyncPane = { }, openAddDevice: function () { - if (!Weave.Utils.ensureMPUnlocked()) + if (!Weave.Utils.ensureMPUnlocked()) { return; + } let win = Services.wm.getMostRecentWindow("Sync:AddDevice"); - if (win) + if (win) { win.focus(); - else + } else { window.openDialog("chrome://browser/content/sync/addDevice.xul", "syncAddDevice", "centerscreen,chrome,resizable=no"); + } }, resetSync: function () { this.openSetup("reset"); }, - - _populateComputerName(value) { - let textbox = document.getElementById("fxaSyncComputerName"); - if (!textbox.hasAttribute("placeholder")) { - textbox.setAttribute("placeholder", - Weave.Utils.getDefaultDeviceName()); - } - textbox.value = value; - }, }; + diff --git a/application/basilisk/components/preferences/in-content/sync.xul b/application/basilisk/components/preferences/in-content/sync.xul index cf0e81ca1..7ca075483 100644 --- a/application/basilisk/components/preferences/in-content/sync.xul +++ b/application/basilisk/components/preferences/in-content/sync.xul @@ -1,35 +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/. - -<!-- Sync panel --> - -<preferences id="syncEnginePrefs" hidden="true" data-category="paneSync"> - <preference id="engine.addons" - name="services.sync.engine.addons" - type="bool"/> - <preference id="engine.bookmarks" - name="services.sync.engine.bookmarks" - type="bool"/> - <preference id="engine.history" - name="services.sync.engine.history" - type="bool"/> - <preference id="engine.tabs" - name="services.sync.engine.tabs" - type="bool"/> - <preference id="engine.prefs" - name="services.sync.engine.prefs" - type="bool"/> - <preference id="engine.passwords" - name="services.sync.engine.passwords" - type="bool"/> -</preferences> +<!-- 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/. --> <script type="application/javascript" src="chrome://browser/content/preferences/in-content/sync.js"/> <script type="application/javascript" src="chrome://browser/content/sync/utils.js"/> +<preferences> +<!-- <preference id="engine.addons" name="services.sync.engine.addons" type="bool"/> --> + <preference id="engine.bookmarks" name="services.sync.engine.bookmarks" type="bool"/> + <preference id="engine.history" name="services.sync.engine.history" type="bool"/> + <preference id="engine.tabs" name="services.sync.engine.tabs" type="bool"/> + <preference id="engine.prefs" name="services.sync.engine.prefs" type="bool"/> + <preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/> +</preferences> + + <hbox id="header-sync" class="header" hidden="true" @@ -39,22 +26,19 @@ </hbox> <deck id="weavePrefsDeck" data-category="paneSync" hidden="true"> - <!-- These panels are for the "legacy" sync provider --> <vbox id="noAccount" align="center"> <spacer flex="1"/> <description id="syncDesc"> &weaveDesc.label; </description> <separator/> - <label id="noAccountSetup" class="text-link"> - &setupButton.label; - </label> - <vbox id="pairDevice"> - <separator/> - <label id="noAccountPair" class="text-link"> - &pairDevice.label; - </label> - </vbox> + <label class="text-link" + onclick="event.stopPropagation(); gSyncPane.openSetup(null);" + value="&setupButton.label;"/> + <separator/> + <label class="text-link" + onclick="event.stopPropagation(); gSyncPane.openSetup('pair');" + value="&pairDevice.label;"/> <spacer flex="3"/> </vbox> @@ -63,7 +47,7 @@ <!-- label is set to account name --> <caption id="accountCaption" align="center"> <image id="accountCaptionImage"/> - <label id="accountName"/> + <label id="accountName" value=""/> </caption> <hbox> @@ -71,28 +55,39 @@ label="&manageAccount.label;" accesskey="&manageAccount.accesskey;"> <menupopup> - <menuitem id="syncViewQuota" label="&viewQuota.label;" + <menuitem label="&viewQuota.label;" oncommand="gSyncPane.openQuotaDialog();"/> - <menuseparator/> - <menuitem id="syncChangePassword" label="&changePassword2.label;"/> - <menuitem id="syncResetPassphrase" label="&myRecoveryKey.label;"/> <menuseparator/> - <menuitem id="syncReset" label="&resetSync2.label;"/> + <menuitem label="&changePassword2.label;" + oncommand="gSyncUtils.changePassword();"/> + <menuitem label="&myRecoveryKey.label;" + oncommand="gSyncUtils.resetPassphrase();"/> + <menuseparator/> + <menuitem label="&resetSync2.label;" + oncommand="gSyncPane.resetSync();"/> </menupopup> </button> </hbox> <hbox> <label id="syncAddDeviceLabel" - class="text-link"> - &pairDevice.label; - </label> + class="text-link" + onclick="gSyncPane.openAddDevice(); return false;" + value="&pairDevice.label;"/> </hbox> <vbox> - <label>&syncMy.label;</label> + <label value="&syncMy.label;" /> <richlistbox id="syncEnginesList" - orient="vertical"> + orient="vertical" + onselect="if (this.selectedCount) this.clearSelection();"> + <!-- + <richlistitem> + <checkbox label="&engine.addons.label;" + accesskey="&engine.addons.accesskey;" + preference="engine.addons"/> + </richlistitem> + --> <richlistitem> <checkbox label="&engine.bookmarks.label;" accesskey="&engine.bookmarks.accesskey;" @@ -130,228 +125,42 @@ </columns> <rows> <row align="center"> - <label control="syncComputerName"> - &syncDeviceName.label; - </label> - <textbox id="syncComputerName"/> + <label value="&syncDeviceName.label;" + accesskey="&syncDeviceName.accesskey;" + control="syncComputerName"/> + <textbox id="syncComputerName" + onchange="gSyncUtils.changeName(this)"/> </row> </rows> </grid> <hbox> - <label id="unlinkDevice" class="text-link"> - &unlinkDevice.label; - </label> + <label class="text-link" + onclick="gSyncPane.startOver(true); return false;" + value="&unlinkDevice.label;"/> </hbox> </groupbox> - <vbox id="tosPP-normal"> - <label id="tosPP-normal-ToS" class="text-link"> - &prefs.tosLink.label; - </label> - <label id="tosPP-normal-PP" class="text-link"> - &prefs.ppLink.label; - </label> - </vbox> - </vbox> - - <vbox id="needsUpdate" align="center" pack="center"> - <hbox> - <label id="loginError"/> - <label id="loginErrorUpdatePass" class="text-link"> - &updatePass.label; - </label> - <label id="loginErrorResetPass" class="text-link"> - &resetPass.label; - </label> + <hbox id="tosPP" pack="center"> + <label class="text-link" + onclick="event.stopPropagation();gSyncUtils.openToS();" + value="&prefs.tosLink.label;"/> + <label class="text-link" + onclick="event.stopPropagation();gSyncUtils.openPrivacyPolicy();" + value="&prefs.ppLink.label;"/> </hbox> - <label id="loginErrorStartOver" class="text-link"> - &unlinkDevice.label; - </label> </vbox> - <!-- These panels are for the Firefox Accounts identity provider --> - <vbox id="noFxaAccount"> - <hbox> - <vbox id="fxaContentWrapper"> - <groupbox id="noFxaGroup"> - <vbox> - <label id="noFxaCaption">&signedOut.caption;</label> - <description id="noFxaDescription" flex="1">&signedOut.description;</description> - <hbox class="fxaAccountBox"> - <vbox> - <image class="fxaFirefoxLogo"/> - </vbox> - <vbox flex="1"> - <label id="signedOutAccountBoxTitle">&signedOut.accountBox.title;</label> - <hbox class="fxaAccountBoxButtons"> - <button id="noFxaSignUp" label="&signedOut.accountBox.create;" accesskey="&signedOut.accountBox.create.accesskey;"></button> - <button id="noFxaSignIn" label="&signedOut.accountBox.signin;" accesskey="&signedOut.accountBox.signin.accesskey;"></button> - </hbox> - </vbox> - </hbox> - </vbox> - </groupbox> - </vbox> - <vbox> - <image class="fxaSyncIllustration"/> - </vbox> - </hbox> - <label class="fxaMobilePromo"> - &mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces - --><label id="fxaMobilePromo-android" - class="androidLink text-link"><!-- - -->&mobilePromo3.androidLink;</label><!-- - -->&mobilePromo3.iOSBefore;<!-- - --><label id="fxaMobilePromo-ios" - class="iOSLink text-link"><!-- - -->&mobilePromo3.iOSLink;</label><!-- - -->&mobilePromo3.end; - </label> - </vbox> - - <vbox id="hasFxaAccount"> + <vbox id="needsUpdate" align="center" pack="center"> <hbox> - <vbox id="fxaContentWrapper"> - <groupbox id="fxaGroup"> - <caption><label>&syncBrand.fxAccount.label;</label></caption> - <deck id="fxaLoginStatus"> - - <!-- logged in and verified and all is good --> - <hbox id="fxaLoginVerified" class="fxaAccountBox"> - <vbox align="center" pack="center"> - <image id="fxaProfileImage" class="actionable" - role="button" - onclick="gSyncPane.openChangeProfileImage(event);" hidden="true" - onkeypress="gSyncPane.openChangeProfileImage(event);" - tooltiptext="&profilePicture.tooltip;"/> - </vbox> - <vbox flex="1" pack="center"> - <label id="fxaDisplayName" hidden="true"/> - <label id="fxaEmailAddress1"/> - <hbox class="fxaAccountBoxButtons"> - <button id="fxaUnlinkButton" label="&disconnect.label;" accesskey="&disconnect.accesskey;"/> - <html:a id="verifiedManage" target="_blank" - accesskey="&verifiedManage.accesskey;" - onkeypress="gSyncPane.openManageFirefoxAccount(event);"><!-- - -->&verifiedManage.label;</html:a> - </hbox> - </vbox> - </hbox> - - <!-- logged in to an unverified account --> - <hbox id="fxaLoginUnverified" class="fxaAccountBox"> - <vbox> - <image id="fxaProfileImage"/> - </vbox> - <vbox flex="1"> - <hbox> - <vbox><image id="fxaLoginRejectedWarning"/></vbox> - <description flex="1"> - &signedInUnverified.beforename.label; - <label id="fxaEmailAddress2"/> - &signedInUnverified.aftername.label; - </description> - </hbox> - <hbox class="fxaAccountBoxButtons"> - <button id="verifyFxaAccount" accesskey="&verify.accesskey;">&verify.label;</button> - <button id="unverifiedUnlinkFxaAccount" accesskey="&forget.accesskey;">&forget.label;</button> - </hbox> - </vbox> - </hbox> - - <!-- logged in locally but server rejected credentials --> - <hbox id="fxaLoginRejected" class="fxaAccountBox"> - <vbox> - <image id="fxaProfileImage"/> - </vbox> - <vbox flex="1"> - <hbox> - <vbox><image id="fxaLoginRejectedWarning"/></vbox> - <description flex="1"> - &signedInLoginFailure.beforename.label; - <label id="fxaEmailAddress3"/> - &signedInLoginFailure.aftername.label; - </description> - </hbox> - <hbox class="fxaAccountBoxButtons"> - <button id="rejectReSignIn" accessky="&signIn.accesskey;">&signIn.label;</button> - <button id="rejectUnlinkFxaAccount" accesskey="&forget.accesskey;">&forget.label;</button> - </hbox> - </vbox> - </hbox> - </deck> - </groupbox> - <groupbox id="syncOptions"> - <caption><label>&signedIn.engines.label;</label></caption> - <hbox id="fxaSyncEngines"> - <vbox align="start" flex="1"> - <checkbox label="&engine.tabs.label;" - accesskey="&engine.tabs.accesskey;" - preference="engine.tabs"/> - <checkbox label="&engine.bookmarks.label;" - accesskey="&engine.bookmarks.accesskey;" - preference="engine.bookmarks"/> - <checkbox label="&engine.passwords.label;" - accesskey="&engine.passwords.accesskey;" - preference="engine.passwords"/> - </vbox> - <vbox align="start" flex="1"> - <checkbox label="&engine.history.label;" - accesskey="&engine.history.accesskey;" - preference="engine.history"/> - <checkbox label="&engine.addons.label;" - accesskey="&engine.addons.accesskey;" - preference="engine.addons"/> - <checkbox label="&engine.prefs.label;" - accesskey="&engine.prefs.accesskey;" - preference="engine.prefs"/> - </vbox> - <spacer/> - </hbox> - </groupbox> - </vbox> - <vbox> - <image class="fxaSyncIllustration"/> - </vbox> + <label id="loginError" value=""/> + <label class="text-link" + onclick="gSyncPane.updatePass(); return false;" + value="&updatePass.label;"/> + <label class="text-link" + onclick="gSyncPane.resetPass(); return false;" + value="&resetPass.label;"/> </hbox> - <groupbox> - <caption> - <label control="fxaSyncComputerName"> - &fxaSyncDeviceName.label; - </label> - </caption> - <hbox id="fxaDeviceName"> - <textbox id="fxaSyncComputerName" disabled="true"/> - <hbox> - <button id="fxaChangeDeviceName" - label="&changeSyncDeviceName.label;" - accesskey="&changeSyncDeviceName.accesskey;"/> - <button id="fxaCancelChangeDeviceName" - label="&cancelChangeSyncDeviceName.label;" - accesskey="&cancelChangeSyncDeviceName.accesskey;" - hidden="true"/> - <button id="fxaSaveChangeDeviceName" - label="&saveChangeSyncDeviceName.label;" - accesskey="&saveChangeSyncDeviceName.accesskey;" - hidden="true"/> - </hbox> - </hbox> - </groupbox> - <label class="fxaMobilePromo"> - &mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces - --><label class="androidLink text-link" id="fxaMobilePromo-android-hasFxaAccount"><!-- - -->&mobilePromo3.androidLink;</label><!-- - -->&mobilePromo3.iOSBefore;<!-- - --><label class="iOSLink text-link" id="fxaMobilePromo-ios-hasFxaAccount"><!-- - -->&mobilePromo3.iOSLink;</label><!-- - -->&mobilePromo3.end; - </label> - <vbox id="tosPP-small" align="start"> - <label id="tosPP-small-ToS" class="text-link"> - &prefs.tosLink.label; - </label> - <label id="tosPP-small-PP" class="text-link"> - &fxaPrivacyNotice.link.label; - </label> - </vbox> + <label class="text-link" + onclick="gSyncPane.startOver(true); return false;" + value="&unlinkDevice.label;"/> </vbox> </deck> diff --git a/application/basilisk/base/content/sync/aboutSyncTabs-bindings.xml b/application/basilisk/components/sync/aboutSyncTabs-bindings.xml index e6108209a..e6108209a 100644 --- a/application/basilisk/base/content/sync/aboutSyncTabs-bindings.xml +++ b/application/basilisk/components/sync/aboutSyncTabs-bindings.xml diff --git a/application/basilisk/base/content/sync/aboutSyncTabs.css b/application/basilisk/components/sync/aboutSyncTabs.css index 5a353175b..5a353175b 100644 --- a/application/basilisk/base/content/sync/aboutSyncTabs.css +++ b/application/basilisk/components/sync/aboutSyncTabs.css diff --git a/application/basilisk/base/content/sync/aboutSyncTabs.js b/application/basilisk/components/sync/aboutSyncTabs.js index f4bb607ea..410494b5b 100644 --- a/application/basilisk/base/content/sync/aboutSyncTabs.js +++ b/application/basilisk/components/sync/aboutSyncTabs.js @@ -11,14 +11,6 @@ Cu.import("resource://gre/modules/PlacesUtils.jsm", this); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource://gre/modules/Promise.jsm"); - -#ifdef MOZ_SERVICES_CLOUDSYNC -XPCOMUtils.defineLazyModuleGetter(this, "CloudSync", - "resource://gre/modules/CloudSync.jsm"); -#endif - var RemoteTabViewer = { _tabsList: null, @@ -26,8 +18,6 @@ var RemoteTabViewer = { Services.obs.addObserver(this, "weave:service:login:finish", false); Services.obs.addObserver(this, "weave:engine:sync:finish", false); - Services.obs.addObserver(this, "cloudsync:tabs:update", false); - this._tabsList = document.getElementById("tabsList"); this.buildList(true); @@ -36,14 +26,12 @@ var RemoteTabViewer = { uninit: function () { Services.obs.removeObserver(this, "weave:service:login:finish"); Services.obs.removeObserver(this, "weave:engine:sync:finish"); - - Services.obs.removeObserver(this, "cloudsync:tabs:update"); }, - createItem: function (attrs) { + createItem: function(attrs) { let item = document.createElement("richlistitem"); - // Copy the attributes from the argument into the item. + // Copy the attributes from the argument into the item for (let attr in attrs) { item.setAttribute(attr, attrs[attr]); } @@ -55,7 +43,7 @@ var RemoteTabViewer = { return item; }, - filterTabs: function (event) { + filterTabs: function(event) { let val = event.target.value.toLowerCase(); let numTabs = this._tabsList.getRowCount(); let clientTabs = 0; @@ -65,7 +53,7 @@ var RemoteTabViewer = { let item = this._tabsList.getItemAtIndex(i); let hide = false; if (item.getAttribute("type") == "tab") { - if (!item.getAttribute("url").toLowerCase().includes(val) && + if (!item.getAttribute("url").toLowerCase().includes(val) && !item.getAttribute("title").toLowerCase().includes(val)) { hide = true; } else { @@ -88,10 +76,10 @@ var RemoteTabViewer = { } }, - openSelected: function () { + openSelected: function() { let items = this._tabsList.selectedItems; let urls = []; - for (let i = 0; i < items.length; i++) { + for (let i = 0;i < items.length;i++) { if (items[i].getAttribute("type") == "tab") { urls.push(items[i].getAttribute("url")); let index = this._tabsList.getIndexOfItem(items[i]); @@ -104,7 +92,7 @@ var RemoteTabViewer = { } }, - bookmarkSingleTab: function () { + bookmarkSingleTab: function() { let item = this._tabsList.selectedItems[0]; let uri = Weave.Utils.makeURI(item.getAttribute("url")); let title = item.getAttribute("title"); @@ -119,10 +107,10 @@ var RemoteTabViewer = { }, window.top); }, - bookmarkSelectedTabs: function () { + bookmarkSelectedTabs: function() { let items = this._tabsList.selectedItems; let URIs = []; - for (let i = 0; i < items.length; i++) { + for (let i = 0;i < items.length;i++) { if (items[i].getAttribute("type") == "tab") { let uri = Weave.Utils.makeURI(items[i].getAttribute("url")); if (!uri) { @@ -157,7 +145,7 @@ var RemoteTabViewer = { _buildListRequested: false, - buildList: function (forceSync) { + buildList: function (force) { if (this._waitingForBuildList) { this._buildListRequested = true; return; @@ -168,37 +156,27 @@ var RemoteTabViewer = { this._clearTabList(); - if (Weave.Service.isLoggedIn) { - this._refetchTabs(forceSync); + if (Weave.Service.isLoggedIn && this._refetchTabs(force)) { this._generateWeaveTabList(); } else { - // XXXzpao We should say something about not being logged in & not having data + //XXXzpao We should say something about not being logged in & not having data // or tell the appropriate condition. (bug 583344) } - let complete = () => { + function complete() { this._waitingForBuildList = false; if (this._buildListRequested) { CommonUtils.nextTick(this.buildList, this); } } -#ifdef MOZ_SERVICES_CLOUDSYNC - if (CloudSync && CloudSync.ready && CloudSync().tabsReady && CloudSync().tabs.hasRemoteTabs()) { - this._generateCloudSyncTabList() - .then(complete, complete); - } else { - complete(); - } -#else complete(); -#endif }, _clearTabList: function () { let list = this._tabsList; - // Clear out existing richlistitems. + // Clear out existing richlistitems let count = list.getRowCount(); if (count > 0) { for (let i = count - 1; i >= 0; i--) { @@ -214,7 +192,7 @@ var RemoteTabViewer = { let seenURLs = new Set(); let localURLs = engine.getOpenURLs(); - for (let [, client] of Object.entries(engine.getAllClients())) { + for (let [guid, client] in Iterator(engine.getAllClients())) { // Create the client node, but don't add it in-case we don't show any tabs let appendClient = true; @@ -248,37 +226,7 @@ var RemoteTabViewer = { } }, - _generateCloudSyncTabList: function () { - let updateTabList = function (remoteTabs) { - let list = this._tabsList; - - for (let client of remoteTabs) { - let clientAttrs = { - type: "client", - clientName: client.name, - }; - - let clientEnt = this.createItem(clientAttrs); - list.appendChild(clientEnt); - - for (let tab of client.tabs) { - let tabAttrs = { - type: "tab", - title: tab.title, - url: tab.url, - icon: this.getIcon(tab.icon), - }; - let tabEnt = this.createItem(tabAttrs); - list.appendChild(tabEnt); - } - } - }.bind(this); - - return CloudSync().tabs.getRemoteTabs() - .then(updateTabList, Promise.reject.bind(Promise)); - }, - - adjustContextMenu: function (event) { + adjustContextMenu: function(event) { let mode = "all"; switch (this._tabsList.selectedItems.length) { case 0: @@ -303,7 +251,7 @@ var RemoteTabViewer = { } }, - _refetchTabs: function (force) { + _refetchTabs: function(force) { if (!force) { // Don't bother refetching tabs if we already did so recently let lastFetch = 0; @@ -320,40 +268,40 @@ var RemoteTabViewer = { } } - // Ask Sync to just do the tabs engine if it can. - Weave.Service.sync(["tabs"]); + // if Clients hasn't synced yet this session, we need to sync it as well. + if (Weave.Service.clientsEngine.lastSync == 0) { + Weave.Service.clientsEngine.sync(); + } + + // Force a sync only for the tabs engine + let engine = Weave.Service.engineManager.get("tabs"); + engine.lastModified = null; + engine.sync(); Services.prefs.setIntPref("services.sync.lastTabFetch", Math.floor(Date.now() / 1000)); return true; }, - observe: function (subject, topic, data) { + observe: function(subject, topic, data) { switch (topic) { case "weave:service:login:finish": - // A login has finished, which means that a Sync is about to start and - // we will eventually get to the "tabs" engine - but try and force the - // tab engine to sync first by passing |true| for the forceSync param. this.buildList(true); break; case "weave:engine:sync:finish": - if (data == "tabs") { - // The tabs engine just finished, so re-build the list without - // forcing a new sync of the tabs engine. + if (subject == "tabs") { this.buildList(false); } break; - case "cloudsync:tabs:update": - this.buildList(false); - break; } }, - handleClick: function (event) { + handleClick: function(event) { if (event.target.getAttribute("type") != "tab") { return; } + if (event.button == 1) { let url = event.target.getAttribute("url"); openUILink(url, event); @@ -362,3 +310,4 @@ var RemoteTabViewer = { } } } + diff --git a/application/basilisk/base/content/sync/aboutSyncTabs.xul b/application/basilisk/components/sync/aboutSyncTabs.xul index a4aa0032f..a4aa0032f 100644 --- a/application/basilisk/base/content/sync/aboutSyncTabs.xul +++ b/application/basilisk/components/sync/aboutSyncTabs.xul diff --git a/application/basilisk/base/content/sync/addDevice.js b/application/basilisk/components/sync/addDevice.js index 0390d4397..0390d4397 100644 --- a/application/basilisk/base/content/sync/addDevice.js +++ b/application/basilisk/components/sync/addDevice.js diff --git a/application/basilisk/base/content/sync/addDevice.xul b/application/basilisk/components/sync/addDevice.xul index 83c3b7b3c..f2371aad0 100644 --- a/application/basilisk/base/content/sync/addDevice.xul +++ b/application/basilisk/components/sync/addDevice.xul @@ -43,7 +43,7 @@ &pairDevice.dialog.description.label; <label class="text-link" value="&addDevice.showMeHow.label;" - href="https://services.mozilla.com/sync/help/add-device"/> + href="http://www.palemoon.org/sync/help/easy-setup.shtml"/> </description> <separator class="groove-thin"/> <description> diff --git a/application/basilisk/base/content/sync/genericChange.js b/application/basilisk/components/sync/genericChange.js index 51a74f1b1..df6639178 100644 --- a/application/basilisk/base/content/sync/genericChange.js +++ b/application/basilisk/components/sync/genericChange.js @@ -32,6 +32,7 @@ var Change = { onLoad: function Change_onLoad() { /* Load labels */ let introText = document.getElementById("introText"); + let introText2 = document.getElementById("introText2"); let warningText = document.getElementById("warningText"); // load some other elements & info from the window @@ -69,7 +70,6 @@ var Change = { else { document.getElementById("generatePassphraseButton").hidden = false; document.getElementById("passphraseBackupButtons").hidden = false; - this._passphraseBox.setAttribute("readonly", "true"); let pp = Weave.Service.identity.syncKey; if (Weave.Utils.isPassphrase(pp)) pp = Weave.Utils.hyphenatePassphrase(pp); @@ -120,7 +120,7 @@ var Change = { _updateStatus: function Change__updateStatus(str, state) { this._updateStatusWithString(this._str(str), state); }, - + _updateStatusWithString: function Change__updateStatusWithString(string, state) { this._statusRow.hidden = false; this._status.value = string; @@ -141,10 +141,11 @@ var Change = { case "UpdatePassphrase": case "ResetPassphrase": return this.doChangePassphrase(); + break; case "ChangePassword": return this.doChangePassword(); + break; } - return undefined; }, doGeneratePassphrase: function () { @@ -212,10 +213,10 @@ var Change = { [valid, errorString] = gSyncUtils.validatePassword(this._firstBox, this._secondBox); } else { - if (!this._updatingPassphrase) - return; - - valid = this._passphraseBox.value != ""; + //Pale Moon: Enforce minimum length of 8 for allowed custom passphrase + //and don't restrict it to "out of sync" situations only. People who + //go to this page generally know what they are doing ;) + valid = this._passphraseBox.value.length >= 8; } if (errorString == "") diff --git a/application/basilisk/base/content/sync/genericChange.xul b/application/basilisk/components/sync/genericChange.xul index db74a1b31..3c0b2cd6c 100644 --- a/application/basilisk/base/content/sync/genericChange.xul +++ b/application/basilisk/components/sync/genericChange.xul @@ -67,7 +67,7 @@ <label id="generatePassphraseButton" hidden="true" value="&syncGenerateNewKey.label;" - class="text-link" + class="text-link inline-link" onclick="event.stopPropagation(); Change.doGeneratePassphrase();"/> </hbox> @@ -105,7 +105,7 @@ <description> &existingRecoveryKey.description; <label class="text-link" - href="https://services.mozilla.com/sync/help/manual-setup"> + href="http://www.palemoon.org/sync/help/recoverykey.shtml"> &addDevice.showMeHow.label; </label> </description> diff --git a/application/basilisk/components/sync/jar.mn b/application/basilisk/components/sync/jar.mn new file mode 100644 index 000000000..3782038cd --- /dev/null +++ b/application/basilisk/components/sync/jar.mn @@ -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/. + +browser.jar: + content/browser/sync/aboutSyncTabs.xul + content/browser/sync/aboutSyncTabs.js + content/browser/sync/aboutSyncTabs.css + content/browser/sync/aboutSyncTabs-bindings.xml + content/browser/sync/setup.xul + content/browser/sync/addDevice.js + content/browser/sync/addDevice.xul + content/browser/sync/setup.js + content/browser/sync/genericChange.xul + content/browser/sync/genericChange.js + content/browser/sync/key.xhtml + content/browser/sync/notification.xml + content/browser/sync/quota.xul + content/browser/sync/quota.js + content/browser/sync/utils.js + content/browser/sync/progress.js + content/browser/sync/progress.xhtml
\ No newline at end of file diff --git a/application/basilisk/base/content/sync/key.xhtml b/application/basilisk/components/sync/key.xhtml index 1363132e7..92abf0ee6 100644 --- a/application/basilisk/base/content/sync/key.xhtml +++ b/application/basilisk/components/sync/key.xhtml @@ -44,7 +44,7 @@ <p><em>&syncKey.keepItSafe1.description;</em>&syncKey.keepItSafe2.description;<em>&syncKey.keepItSafe3.description;</em>&syncKey.keepItSafe4a.description;</p> </div> -<p>&syncKey.findOutMore1.label;<a href="https://services.mozilla.com">https://services.mozilla.com</a>&syncKey.findOutMore2.label;</p> +<p>&syncKey.findOutMore1.label;<a href="http://www.palemoon.org/sync/">http://www.palemoon.org/sync/</a>&syncKey.findOutMore2.label;</p> <footer> &syncKey.footer1.label;<a id="tosLink" href="termsURL">termsURL</a>&syncKey.footer2.label;<a id="ppLink" href="privacyURL">privacyURL</a>&syncKey.footer3.label; diff --git a/application/basilisk/components/syncedtabs/jar.mn b/application/basilisk/components/sync/moz.build index ba2b105a1..2d64d506c 100644 --- a/application/basilisk/components/syncedtabs/jar.mn +++ b/application/basilisk/components/sync/moz.build @@ -1,7 +1,8 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: # 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/. -browser.jar: - content/browser/syncedtabs/sidebar.xhtml - content/browser/syncedtabs/sidebar.js +JAR_MANIFESTS += ['jar.mn'] + diff --git a/application/basilisk/components/sync/notification.xml b/application/basilisk/components/sync/notification.xml new file mode 100644 index 000000000..8ac881e08 --- /dev/null +++ b/application/basilisk/components/sync/notification.xml @@ -0,0 +1,129 @@ +<?xml version="1.0"?> + +<!-- 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/. --> + +<!DOCTYPE bindings [ +<!ENTITY % notificationDTD SYSTEM "chrome://global/locale/notification.dtd"> +%notificationDTD; +]> + +<bindings id="notificationBindings" + xmlns="http://www.mozilla.org/xbl" + xmlns:xbl="http://www.mozilla.org/xbl" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <binding id="notificationbox" extends="chrome://global/content/bindings/notification.xml#notificationbox"> + <content> + <xul:vbox xbl:inherits="hidden=notificationshidden"> + <xul:spacer/> + <children includes="notification"/> + </xul:vbox> + <children/> + </content> + + <implementation> + <constructor><![CDATA[ + let temp = {}; + Cu.import("resource://services-common/observers.js", temp); + temp.Observers.add("weave:notification:added", this.onNotificationAdded, this); + temp.Observers.add("weave:notification:removed", this.onNotificationRemoved, this); + + for each (var notification in Weave.Notifications.notifications) + this._appendNotification(notification); + ]]></constructor> + + <destructor><![CDATA[ + let temp = {}; + Cu.import("resource://services-common/observers.js", temp); + temp.Observers.remove("weave:notification:added", this.onNotificationAdded, this); + temp.Observers.remove("weave:notification:removed", this.onNotificationRemoved, this); + ]]></destructor> + + <method name="onNotificationAdded"> + <parameter name="subject"/> + <parameter name="data"/> + <body><![CDATA[ + this._appendNotification(subject); + ]]></body> + </method> + + <method name="onNotificationRemoved"> + <parameter name="subject"/> + <parameter name="data"/> + <body><![CDATA[ + // If the view of the notification hasn't been removed yet, remove it. + var notifications = this.allNotifications; + for each (var notification in notifications) { + if (notification.notification == subject) { + notification.close(); + break; + } + } + ]]></body> + </method> + + <method name="_appendNotification"> + <parameter name="notification"/> + <body><![CDATA[ + var node = this.appendNotification(notification.description, + notification.title, + notification.iconURL, + notification.priority, + notification.buttons); + node.notification = notification; + ]]></body> + </method> + + </implementation> + </binding> + + <binding id="notification" extends="chrome://global/content/bindings/notification.xml#notification"> + <content> + <xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type"> + <xul:toolbarbutton ondblclick="event.stopPropagation();" + class="messageCloseButton close-icon tabbable" + xbl:inherits="hidden=hideclose" + tooltiptext="&closeNotification.tooltip;" + oncommand="document.getBindingParent(this).close()"/> + <xul:hbox anonid="details" align="center" flex="1"> + <xul:image anonid="messageImage" class="messageImage" xbl:inherits="src=image,type"/> + <xul:description anonid="messageText" class="messageText" xbl:inherits="xbl:text=label"/> + + <!-- The children are the buttons defined by the notification. --> + <xul:hbox oncommand="document.getBindingParent(this)._doButtonCommand(event);"> + <children/> + </xul:hbox> + </xul:hbox> + </xul:hbox> + </content> + <implementation> + <!-- Note: this used to be a field, but for some reason it kept getting + - reset to its default value for TabNotification elements. + - As a property, that doesn't happen, even though the property stores + - its value in a JS property |_notification| that is not defined + - in XBL as a field or property. Maybe this is wrong, but it works. + --> + <property name="notification" + onget="return this._notification" + onset="this._notification = val; return val;"/> + <method name="close"> + <body><![CDATA[ + Weave.Notifications.remove(this.notification); + + // We should be able to call the base class's close method here + // to remove the notification element from the notification box, + // but we can't because of bug 373652, so instead we copied its code + // and execute it below. + var control = this.control; + if (control) + control.removeNotification(this); + else + this.hidden = true; + ]]></body> + </method> + </implementation> + </binding> + +</bindings> diff --git a/application/basilisk/components/sync/progress.js b/application/basilisk/components/sync/progress.js new file mode 100644 index 000000000..101160fa8 --- /dev/null +++ b/application/basilisk/components/sync/progress.js @@ -0,0 +1,71 @@ +/* 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/. */ + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://services-sync/main.js"); + +var gProgressBar; +var gCounter = 0; + +function onLoad(event) { + Services.obs.addObserver(onEngineSync, "weave:engine:sync:finish", false); + Services.obs.addObserver(onEngineSync, "weave:engine:sync:error", false); + Services.obs.addObserver(onServiceSync, "weave:service:sync:finish", false); + Services.obs.addObserver(onServiceSync, "weave:service:sync:error", false); + + gProgressBar = document.getElementById('uploadProgressBar'); + + if (Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) { + gProgressBar.hidden = false; + } + else { + gProgressBar.hidden = true; + } +} + +function onUnload(event) { + cleanUpObservers(); +} + +function cleanUpObservers() { + try { + Services.obs.removeObserver(onEngineSync, "weave:engine:sync:finish"); + Services.obs.removeObserver(onEngineSync, "weave:engine:sync:error"); + Services.obs.removeObserver(onServiceSync, "weave:service:sync:finish"); + Services.obs.removeObserver(onServiceSync, "weave:service:sync:error"); + } + catch (e) { + // may be double called by unload & exit. Ignore. + } +} + +function onEngineSync(subject, topic, data) { + // The Clients engine syncs first. At this point we don't necessarily know + // yet how many engines will be enabled, so we'll ignore the Clients engine + // and evaluate how many engines are enabled when the first "real" engine + // syncs. + if (data == "clients") { + return; + } + + if (!gCounter && + Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) { + gProgressBar.max = Weave.Service.engineManager.getEnabled().length; + } + + gCounter += 1; + gProgressBar.setAttribute("value", gCounter); +} + +function onServiceSync(subject, topic, data) { + // To address the case where 0 engines are synced, we will fill the + // progress bar so the user knows that the sync has finished. + gProgressBar.setAttribute("value", gProgressBar.max); + cleanUpObservers(); +} + +function closeTab() { + window.close(); +} diff --git a/application/basilisk/components/sync/progress.xhtml b/application/basilisk/components/sync/progress.xhtml new file mode 100644 index 000000000..d403cb20d --- /dev/null +++ b/application/basilisk/components/sync/progress.xhtml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- 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/. --> + +<!DOCTYPE html [ + <!ENTITY % htmlDTD + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "DTD/xhtml1-strict.dtd"> + %htmlDTD; + <!ENTITY % syncProgressDTD + SYSTEM "chrome://browser/locale/syncProgress.dtd"> + %syncProgressDTD; + <!ENTITY % syncSetupDTD + SYSTEM "chrome://browser/locale/syncSetup.dtd"> + %syncSetupDTD; + <!ENTITY % globalDTD + SYSTEM "chrome://global/locale/global.dtd"> + %globalDTD; +]> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>&syncProgress.pageTitle;</title> + + <link rel="stylesheet" type="text/css" media="all" + href="chrome://browser/skin/syncProgress.css"/> + + <link rel="icon" type="image/png" id="favicon" + href="chrome://browser/skin/sync-16.png"/> + + <script type="text/javascript;version=1.8" + src="chrome://browser/content/sync/progress.js"/> + </head> + <body onload="onLoad(event)" onunload="onUnload(event)" dir="&locale.dir;"> + <title>&setup.successPage.title;</title> + <div id="floatingBox" class="main-content"> + <div id="title"> + <h1>&setup.successPage.title;</h1> + </div> + <div id="successLogo"> + <img id="brandSyncLogo" src="chrome://browser/skin/sync-128.png" alt="&syncProgress.logoAltText;" /> + </div> + <div id="loadingText"> + <p id="blurb">&syncProgress.textBlurb; </p> + </div> + <div id="progressBar"> + <progress id="uploadProgressBar" value="0"/> + </div> + <div id="bottomRow"> + <button id="closeButton" onclick="closeTab()">&syncProgress.closeButton; </button> + </div> + </div> + </body> +</html> diff --git a/application/basilisk/base/content/sync/quota.js b/application/basilisk/components/sync/quota.js index b416a44cc..b416a44cc 100644 --- a/application/basilisk/base/content/sync/quota.js +++ b/application/basilisk/components/sync/quota.js diff --git a/application/basilisk/base/content/sync/quota.xul b/application/basilisk/components/sync/quota.xul index 99e6ed78b..99e6ed78b 100644 --- a/application/basilisk/base/content/sync/quota.xul +++ b/application/basilisk/components/sync/quota.xul diff --git a/application/basilisk/base/content/sync/setup.js b/application/basilisk/components/sync/setup.js index f9dae1bd4..e8d67a5f6 100644 --- a/application/basilisk/base/content/sync/setup.js +++ b/application/basilisk/components/sync/setup.js @@ -1,4 +1,3 @@ -// -*- 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/. */ @@ -51,9 +50,7 @@ var gSyncSetup = { server: false }, - get _remoteSites() { - return [Weave.Service.serverURL, RECAPTCHA_DOMAIN]; - }, + get _remoteSites() [Weave.Service.serverURL, RECAPTCHA_DOMAIN], get _usingMainServers() { if (this._settingUpNew) @@ -72,7 +69,7 @@ var gSyncSetup = { let self = this; let addRem = function(add) { obs.forEach(function([topic, func]) { - // XXXzpao This should use Services.obs.* but Weave's Obs does nice handling + //XXXzpao This should use Services.obs.* but Weave's Obs does nice handling // of `this`. Fix in a followup. (bug 583347) if (add) Weave.Svc.Obs.add(topic, self[func], self); @@ -81,7 +78,7 @@ var gSyncSetup = { }); }; addRem(true); - window.addEventListener("unload", () => addRem(false), false); + window.addEventListener("unload", function() addRem(false), false); window.setTimeout(function () { // Force Service to be loaded so that engines are registered. @@ -123,14 +120,14 @@ var gSyncSetup = { startNewAccountSetup: function () { if (!Weave.Utils.ensureMPUnlocked()) - return; + return false; this._settingUpNew = true; this.wizard.pageIndex = NEW_ACCOUNT_START_PAGE; }, useExistingAccount: function () { if (!Weave.Utils.ensureMPUnlocked()) - return; + return false; this._settingUpNew = false; if (this.wizardType == "pair") { // We're already pairing, so there's no point in pairing again. @@ -512,6 +509,7 @@ var gSyncSetup = { onWizardBack: function () { switch (this.wizard.pageIndex) { case NEW_ACCOUNT_START_PAGE: + case EXISTING_ACCOUNT_LOGIN_PAGE: this.wizard.pageIndex = INTRO_PAGE; return false; case EXISTING_ACCOUNT_CONNECT_PAGE: @@ -552,12 +550,19 @@ var gSyncSetup = { for (let i = 0;i < prefs.length;i++) { Weave.Svc.Prefs.set(prefs[i], isChecked(prefs[i])); } + + // XXX: Addons syncing is currently not operational; + // Make doubly-sure to always disable addons syncing pref + Weave.Svc.Prefs.set("engine.addons", false); + this._handleNoScript(false); if (Weave.Svc.Prefs.get("firstSync", "") == "notReady") Weave.Svc.Prefs.reset("firstSync"); Weave.Service.persistLogin(); Weave.Svc.Obs.notify("weave:service:setup-complete"); + + gSyncUtils.openFirstSyncProgressPage(); } Weave.Utils.nextTick(Weave.Service.sync, Weave.Service); window.close(); @@ -797,6 +802,7 @@ var gSyncSetup = { let el = document.getElementById("server"); let valid = false; let feedback = document.getElementById("serverFeedbackRow"); + let str = ""; if (el.value) { valid = this._validateServer(el); let str = valid ? "" : "serverInvalid.label"; @@ -932,7 +938,12 @@ var gSyncSetup = { let addonsEngine = Weave.Service.engineManager.get("addons"); if (addonsEngine.enabled) { let ids = addonsEngine._store.getAllIDs(); - let blessedcount = Object.keys(ids).filter(id => ids[id]).length; + let blessedcount = 0; + for each (let i in ids) { + if (i) { + blessedcount++; + } + } // bug 600141 does not apply, as this does not have to support existing strings document.getElementById("addonCount").value = PluralForm.get(blessedcount, @@ -956,7 +967,7 @@ var gSyncSetup = { box.appendChild(node); } - for (let name of Weave.Service.clientsEngine.stats.names) { + for each (let name in Weave.Service.clientsEngine.stats.names) { // Don't list the current client if (name == Weave.Service.clientsEngine.localName) continue; @@ -998,7 +1009,7 @@ var gSyncSetup = { if (string) { try { str = this._stringBundle.GetStringFromName(string); - } catch (e) {} + } catch(e) {} if (!str) str = Weave.Utils.getErrorString(string); @@ -1027,7 +1038,7 @@ var gSyncSetup = { // If we didn't find a captcha, assume it's not needed and don't show it. let responseStatus = request.QueryInterface(Ci.nsIHttpChannel).responseStatus; setVisibility(this.captchaBrowser, responseStatus != 404); - // XXX TODO we should really log any responseStatus other than 200 + //XXX TODO we should really log any responseStatus other than 200 }, onProgressChange: function() {}, onStatusChange: function() {}, diff --git a/application/basilisk/base/content/sync/setup.xul b/application/basilisk/components/sync/setup.xul index 11c085931..cf2cc77e4 100644 --- a/application/basilisk/base/content/sync/setup.xul +++ b/application/basilisk/components/sync/setup.xul @@ -43,7 +43,7 @@ &pairDevice.dialog.description.label; <label class="text-link" value="&addDevice.showMeHow.label;" - href="https://services.mozilla.com/sync/help/add-device"/> + href="http://www.palemoon.org/sync/help/easy-setup.shtml"/> </description> <separator class="groove-thin"/> <description> @@ -183,12 +183,12 @@ onclick="document.getElementById('tos').focus(); document.getElementById('tos').click()"> &setup.tosAgree1.label; - <label class="text-link" + <label class="text-link inline-link" onclick="event.stopPropagation();gSyncUtils.openToS();"> &setup.tosLink.label; </label> &setup.tosAgree2.label; - <label class="text-link" + <label class="text-link inline-link" onclick="event.stopPropagation();gSyncUtils.openPrivacyPolicy();"> &setup.ppLink.label; </label> @@ -221,7 +221,7 @@ &pairDevice.setup.description.label; <label class="text-link" value="&addDevice.showMeHow.label;" - href="https://services.mozilla.com/sync/help/easy-setup"/> + href="http://www.palemoon.org/sync/help/easy-setup.shtml"/> </description> <label value="&addDevice.setup.enterCode.label;" control="easySetupPIN1"/> @@ -340,7 +340,7 @@ <description> &existingRecoveryKey.description; <label class="text-link" - href="https://services.mozilla.com/sync/help/manual-setup"> + href="http://www.palemoon.org/sync/help/recoverykey.shtml"> &addDevice.showMeHow.label; </label> <spacer id="passphraseHelpSpacer"/> @@ -359,7 +359,7 @@ <grid> <columns> <column/> - <column flex="1" style="margin-inline-end: 2px"/> + <column flex="1" style="-moz-margin-end: 2px"/> </columns> <rows> <row align="center"> @@ -375,7 +375,8 @@ <checkbox label="&engine.addons.label;" accesskey="&engine.addons.accesskey;" id="engine.addons" - checked="true"/> + checked="false" + hidden="true"/> <checkbox label="&engine.bookmarks.label;" accesskey="&engine.bookmarks.accesskey;" id="engine.bookmarks" diff --git a/application/basilisk/base/content/sync/utils.js b/application/basilisk/components/sync/utils.js index 92981f7b4..d41ecf18a 100644 --- a/application/basilisk/base/content/sync/utils.js +++ b/application/basilisk/components/sync/utils.js @@ -14,13 +14,6 @@ var gSyncUtils = { return this.bundle = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); }, - get fxAccountsEnabled() { - let service = Components.classes["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; - return service.fxAccountsEnabled; - }, - // opens in a new window if we're in a modal prefwindow world, in a new tab otherwise _openLink: function (url) { let thisDocEl = document.documentElement, @@ -77,22 +70,16 @@ var gSyncUtils = { this._openLink(Weave.Service.pwResetURL); }, - get tosURL() { - let root = this.fxAccountsEnabled ? "fxa." : ""; - return Weave.Svc.Prefs.get(root + "termsURL"); - }, - openToS: function () { - this._openLink(this.tosURL); + this._openLink(Weave.Svc.Prefs.get("termsURL")); }, - get privacyPolicyURL() { - let root = this.fxAccountsEnabled ? "fxa." : ""; - return Weave.Svc.Prefs.get(root + "privacyURL"); + openPrivacyPolicy: function () { + this._openLink(Weave.Svc.Prefs.get("privacyURL")); }, - openPrivacyPolicy: function () { - this._openLink(this.privacyPolicyURL); + openFirstSyncProgressPage: function () { + this._openLink("about:sync-progress"); }, /** @@ -134,7 +121,7 @@ var gSyncUtils = { /** * Print passphrase backup document. - * + * * @param elid : ID of the form element containing the passphrase. */ passphrasePrint: function(elid) { @@ -162,7 +149,7 @@ var gSyncUtils = { /** * Save passphrase backup document to disk as HTML file. - * + * * @param elid : ID of the form element containing the passphrase. */ passphraseSave: function(elid) { @@ -200,7 +187,7 @@ var gSyncUtils = { * * @param el1 : the first textbox element in the form * @param el2 : the second textbox element, if omitted it's an update form - * + * * returns [valid, errorString] */ validatePassword: function (el1, el2) { diff --git a/application/basilisk/components/syncedtabs/EventEmitter.jsm b/application/basilisk/components/syncedtabs/EventEmitter.jsm deleted file mode 100644 index ec3225f0f..000000000 --- a/application/basilisk/components/syncedtabs/EventEmitter.jsm +++ /dev/null @@ -1,45 +0,0 @@ -/* 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"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -this.EXPORTED_SYMBOLS = [ - "EventEmitter" -]; - -// Simple event emitter abstraction for storage objects to use. -function EventEmitter () { - this._events = new Map(); -} - -EventEmitter.prototype = { - on(event, listener) { - if (this._events.has(event)) { - this._events.get(event).add(listener); - } else { - this._events.set(event, new Set([listener])); - } - }, - off(event, listener) { - if (!this._events.has(event)) { - return; - } - this._events.get(event).delete(listener); - }, - emit(event, ...args) { - if (!this._events.has(event)) { - return; - } - for (let listener of this._events.get(event).values()) { - try { - listener.apply(this, args); - } catch (e) { - Cu.reportError(e); - } - } - }, -}; - diff --git a/application/basilisk/components/syncedtabs/SyncedTabsDeckComponent.js b/application/basilisk/components/syncedtabs/SyncedTabsDeckComponent.js deleted file mode 100644 index c35277795..000000000 --- a/application/basilisk/components/syncedtabs/SyncedTabsDeckComponent.js +++ /dev/null @@ -1,169 +0,0 @@ -/* 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"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckStore.js"); -Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckView.js"); -Cu.import("resource:///modules/syncedtabs/SyncedTabsListStore.js"); -Cu.import("resource:///modules/syncedtabs/TabListComponent.js"); -Cu.import("resource:///modules/syncedtabs/TabListView.js"); -let { getChromeWindow } = Cu.import("resource:///modules/syncedtabs/util.js", {}); - -XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () { - return Components.utils.import("resource://gre/modules/FxAccountsCommon.js", {}); -}); - -let log = Cu.import("resource://gre/modules/Log.jsm", {}) - .Log.repository.getLogger("Sync.RemoteTabs"); - -this.EXPORTED_SYMBOLS = [ - "SyncedTabsDeckComponent" -]; - -/* SyncedTabsDeckComponent - * This component instantiates views and storage objects as well as defines - * behaviors that will be passed down to the views. This helps keep the views - * isolated and easier to test. - */ - -function SyncedTabsDeckComponent({ - window, SyncedTabs, fxAccounts, deckStore, listStore, listComponent, DeckView, getChromeWindowMock, -}) { - this._window = window; - this._SyncedTabs = SyncedTabs; - this._fxAccounts = fxAccounts; - this._DeckView = DeckView || SyncedTabsDeckView; - // used to stub during tests - this._getChromeWindow = getChromeWindowMock || getChromeWindow; - - this._deckStore = deckStore || new SyncedTabsDeckStore(); - this._syncedTabsListStore = listStore || new SyncedTabsListStore(SyncedTabs); - this.tabListComponent = listComponent || new TabListComponent({ - window: this._window, - store: this._syncedTabsListStore, - View: TabListView, - SyncedTabs: SyncedTabs, - clipboardHelper: Cc["@mozilla.org/widget/clipboardhelper;1"] - .getService(Ci.nsIClipboardHelper), - getChromeWindow: this._getChromeWindow, - }); -} - -SyncedTabsDeckComponent.prototype = { - PANELS: { - TABS_CONTAINER: "tabs-container", - TABS_FETCHING: "tabs-fetching", - NOT_AUTHED_INFO: "notAuthedInfo", - SINGLE_DEVICE_INFO: "singleDeviceInfo", - TABS_DISABLED: "tabs-disabled", - }, - - get container() { - return this._deckView ? this._deckView.container : null; - }, - - init() { - Services.obs.addObserver(this, this._SyncedTabs.TOPIC_TABS_CHANGED, false); - Services.obs.addObserver(this, FxAccountsCommon.ONLOGIN_NOTIFICATION, false); - - // Go ahead and trigger sync - this._SyncedTabs.syncTabs() - .catch(Cu.reportError); - - this._deckView = new this._DeckView(this._window, this.tabListComponent, { - onAndroidClick: event => this.openAndroidLink(event), - oniOSClick: event => this.openiOSLink(event), - onSyncPrefClick: event => this.openSyncPrefs(event) - }); - - this._deckStore.on("change", state => this._deckView.render(state)); - // Trigger the initial rendering of the deck view - // Object.values only in nightly - this._deckStore.setPanels(Object.keys(this.PANELS).map(k => this.PANELS[k])); - // Set the initial panel to display - this.updatePanel(); - }, - - uninit() { - Services.obs.removeObserver(this, this._SyncedTabs.TOPIC_TABS_CHANGED); - Services.obs.removeObserver(this, FxAccountsCommon.ONLOGIN_NOTIFICATION); - this._deckView.destroy(); - }, - - observe(subject, topic, data) { - switch (topic) { - case this._SyncedTabs.TOPIC_TABS_CHANGED: - this._syncedTabsListStore.getData(); - this.updatePanel(); - break; - case FxAccountsCommon.ONLOGIN_NOTIFICATION: - this.updatePanel(); - break; - default: - break; - } - }, - - // There's no good way to mock fxAccounts in browser tests where it's already - // been instantiated, so we have this method for stubbing. - _accountStatus() { - return this._fxAccounts.accountStatus(); - }, - - getPanelStatus() { - return this._accountStatus().then(exists => { - if (!exists) { - return this.PANELS.NOT_AUTHED_INFO; - } - if (!this._SyncedTabs.isConfiguredToSyncTabs) { - return this.PANELS.TABS_DISABLED; - } - if (!this._SyncedTabs.hasSyncedThisSession) { - return this.PANELS.TABS_FETCHING; - } - return this._SyncedTabs.getTabClients().then(clients => { - if (clients.length) { - return this.PANELS.TABS_CONTAINER; - } - return this.PANELS.SINGLE_DEVICE_INFO; - }); - }) - .catch(err => { - Cu.reportError(err); - return this.PANELS.NOT_AUTHED_INFO; - }); - }, - - updatePanel() { - // return promise for tests - return this.getPanelStatus() - .then(panelId => this._deckStore.selectPanel(panelId)) - .catch(Cu.reportError); - }, - - openAndroidLink(event) { - let href = Services.prefs.getCharPref("identity.mobilepromo.android") + "synced-tabs-sidebar"; - this._openUrl(href, event); - }, - - openiOSLink(event) { - let href = Services.prefs.getCharPref("identity.mobilepromo.ios") + "synced-tabs-sidebar"; - this._openUrl(href, event); - }, - - _openUrl(url, event) { - this._window.openUILink(url, event); - }, - - openSyncPrefs() { - this._getChromeWindow(this._window).gSyncUI.openSetup(null, "tabs-sidebar"); - } -}; - diff --git a/application/basilisk/components/syncedtabs/SyncedTabsDeckStore.js b/application/basilisk/components/syncedtabs/SyncedTabsDeckStore.js deleted file mode 100644 index ede6914c8..000000000 --- a/application/basilisk/components/syncedtabs/SyncedTabsDeckStore.js +++ /dev/null @@ -1,60 +0,0 @@ -/* 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"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -let { EventEmitter } = Cu.import("resource:///modules/syncedtabs/EventEmitter.jsm", {}); - -this.EXPORTED_SYMBOLS = [ - "SyncedTabsDeckStore" -]; - -/** - * SyncedTabsDeckStore - * - * This store keeps track of the deck view state, including the panels and which - * one is selected. The view listens for change events on the store, which are - * triggered whenever the state changes. If it's a small change, the state - * will have `isUpdatable` set to true so the view can skip rerendering the whole - * DOM. - */ -function SyncedTabsDeckStore() { - EventEmitter.call(this); - this._panels = []; -} - -Object.assign(SyncedTabsDeckStore.prototype, EventEmitter.prototype, { - _change(isUpdatable = false) { - let panels = this._panels.map(panel => { - return {id: panel, selected: panel === this._selectedPanel}; - }); - this.emit("change", {panels, isUpdatable: isUpdatable}); - }, - - /** - * Sets the selected panelId and triggers a change event. - * @param {String} panelId - ID of the panel to select. - */ - selectPanel(panelId) { - if (this._panels.indexOf(panelId) === -1 || this._selectedPanel === panelId) { - return; - } - this._selectedPanel = panelId; - this._change(true); - }, - - /** - * Update the set of panels in the deck and trigger a change event. - * @param {Array} panels - an array of IDs for each panel in the deck. - */ - setPanels(panels) { - if (panels === this._panels) { - return; - } - this._panels = panels || []; - this._change(); - } -}); diff --git a/application/basilisk/components/syncedtabs/SyncedTabsDeckView.js b/application/basilisk/components/syncedtabs/SyncedTabsDeckView.js deleted file mode 100644 index e9efff323..000000000 --- a/application/basilisk/components/syncedtabs/SyncedTabsDeckView.js +++ /dev/null @@ -1,116 +0,0 @@ -/* 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"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -let { getChromeWindow } = Cu.import("resource:///modules/syncedtabs/util.js", {}); - -let log = Cu.import("resource://gre/modules/Log.jsm", {}) - .Log.repository.getLogger("Sync.RemoteTabs"); - -this.EXPORTED_SYMBOLS = [ - "SyncedTabsDeckView" -]; - -/** - * SyncedTabsDeckView - * - * Instances of SyncedTabsDeckView render DOM nodes from a given state. - * No state is kept internaly and the DOM will completely - * rerender unless the state flags `isUpdatable`, which helps - * make small changes without the overhead of a full rerender. - */ -const SyncedTabsDeckView = function (window, tabListComponent, props) { - this.props = props; - - this._window = window; - this._doc = window.document; - - this._tabListComponent = tabListComponent; - this._deckTemplate = this._doc.getElementById("deck-template"); - this.container = this._doc.createElement("div"); -}; - -SyncedTabsDeckView.prototype = { - render(state) { - if (state.isUpdatable) { - this.update(state); - } else { - this.create(state); - } - }, - - create(state) { - let deck = this._doc.importNode(this._deckTemplate.content, true).firstElementChild; - this._clearChilden(); - - let tabListWrapper = this._doc.createElement("div"); - tabListWrapper.className = "tabs-container sync-state"; - this._tabListComponent.init(); - tabListWrapper.appendChild(this._tabListComponent.container); - deck.appendChild(tabListWrapper); - this.container.appendChild(deck); - - this._generateDevicePromo(); - - this._attachListeners(); - this.update(state); - }, - - _getBrowserBundle() { - return getChromeWindow(this._window).document.getElementById("bundle_browser"); - }, - - _generateDevicePromo() { - let bundle = this._getBrowserBundle(); - let formatArgs = ["android", "ios"].map(os => { - let link = this._doc.createElement("a"); - link.textContent = bundle.getString(`appMenuRemoteTabs.mobilePromo.${os}`); - link.className = `${os}-link text-link`; - link.setAttribute("href", "#"); - return link.outerHTML; - }); - // Put it all together... - let contents = bundle.getFormattedString("appMenuRemoteTabs.mobilePromo.text2", formatArgs); - this.container.querySelector(".device-promo").innerHTML = contents; - }, - - destroy() { - this._tabListComponent.uninit(); - this.container.remove(); - }, - - update(state) { - // Note that we may also want to update elements that are outside of the - // deck, so use the document to find the class names rather than our - // container. - for (let panel of state.panels) { - if (panel.selected) { - Array.prototype.map.call(this._doc.getElementsByClassName(panel.id), - item => item.classList.add("selected")); - } else { - Array.prototype.map.call(this._doc.getElementsByClassName(panel.id), - item => item.classList.remove("selected")); - } - } - }, - - _clearChilden() { - while (this.container.firstChild) { - this.container.removeChild(this.container.firstChild); - } - }, - - _attachListeners() { - this.container.querySelector(".android-link").addEventListener("click", this.props.onAndroidClick); - this.container.querySelector(".ios-link").addEventListener("click", this.props.oniOSClick); - let syncPrefLinks = this.container.querySelectorAll(".sync-prefs"); - for (let link of syncPrefLinks) { - link.addEventListener("click", this.props.onSyncPrefClick); - } - }, -}; - diff --git a/application/basilisk/components/syncedtabs/SyncedTabsListStore.js b/application/basilisk/components/syncedtabs/SyncedTabsListStore.js deleted file mode 100644 index 8f03d9a89..000000000 --- a/application/basilisk/components/syncedtabs/SyncedTabsListStore.js +++ /dev/null @@ -1,235 +0,0 @@ -/* 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"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -let { EventEmitter } = Cu.import("resource:///modules/syncedtabs/EventEmitter.jsm", {}); - -this.EXPORTED_SYMBOLS = [ - "SyncedTabsListStore" -]; - -/** - * SyncedTabsListStore - * - * Instances of this store encapsulate all of the state associated with a synced tabs list view. - * The state includes the clients, their tabs, the row that is currently selected, - * and the filtered query. - */ -function SyncedTabsListStore(SyncedTabs) { - EventEmitter.call(this); - this._SyncedTabs = SyncedTabs; - this.data = []; - this._closedClients = {}; - this._selectedRow = [-1, -1]; - this.filter = ""; - this.inputFocused = false; -} - -Object.assign(SyncedTabsListStore.prototype, EventEmitter.prototype, { - // This internal method triggers the "change" event that views - // listen for. It denormalizes the state so that it's easier for - // the view to deal with. updateType hints to the view what - // actually needs to be rerendered or just updated, and can be - // empty (to (re)render everything), "searchbox" (to rerender just the tab list), - // or "all" (to skip rendering and just update all attributes of existing nodes). - _change(updateType) { - let selectedParent = this._selectedRow[0]; - let selectedChild = this._selectedRow[1]; - let rowSelected = false; - // clone the data so that consumers can't mutate internal storage - let data = Cu.cloneInto(this.data, {}); - let tabCount = 0; - - data.forEach((client, index) => { - client.closed = !!this._closedClients[client.id]; - - if (rowSelected || selectedParent < 0) { - return; - } - if (this.filter) { - if (selectedParent < tabCount + client.tabs.length) { - client.tabs[selectedParent - tabCount].selected = true; - client.tabs[selectedParent - tabCount].focused = !this.inputFocused; - rowSelected = true; - } else { - tabCount += client.tabs.length; - } - return; - } - if (selectedParent === index && selectedChild === -1) { - client.selected = true; - client.focused = !this.inputFocused; - rowSelected = true; - } else if (selectedParent === index) { - client.tabs[selectedChild].selected = true; - client.tabs[selectedChild].focused = !this.inputFocused; - rowSelected = true; - } - }); - - // If this were React the view would be smart enough - // to not re-render the whole list unless necessary. But it's - // not, so updateType is a hint to the view of what actually - // needs to be rerendered. - this.emit("change", { - clients: data, - canUpdateAll: updateType === "all", - canUpdateInput: updateType === "searchbox", - filter: this.filter, - inputFocused: this.inputFocused - }); - }, - - /** - * Moves the row selection from a child to its parent, - * which occurs when the parent of a selected row closes. - */ - _selectParentRow() { - this._selectedRow[1] = -1; - }, - - _toggleBranch(id, closed) { - this._closedClients[id] = closed; - if (this._closedClients[id]) { - this._selectParentRow(); - } - this._change("all"); - }, - - _isOpen(client) { - return !this._closedClients[client.id]; - }, - - moveSelectionDown() { - let branchRow = this._selectedRow[0]; - let childRow = this._selectedRow[1]; - let branch = this.data[branchRow]; - - if (this.filter) { - this.selectRow(branchRow + 1); - return; - } - - if (branchRow < 0) { - this.selectRow(0, -1); - } else if ((!branch.tabs.length || childRow >= branch.tabs.length - 1 || !this._isOpen(branch)) && branchRow < this.data.length) { - this.selectRow(branchRow + 1, -1); - } else if (childRow < branch.tabs.length) { - this.selectRow(branchRow, childRow + 1); - } - }, - - moveSelectionUp() { - let branchRow = this._selectedRow[0]; - let childRow = this._selectedRow[1]; - - if (this.filter) { - this.selectRow(branchRow - 1); - return; - } - - if (branchRow < 0) { - this.selectRow(0, -1); - } else if (childRow < 0 && branchRow > 0) { - let prevBranch = this.data[branchRow - 1]; - let newChildRow = this._isOpen(prevBranch) ? prevBranch.tabs.length - 1 : -1; - this.selectRow(branchRow - 1, newChildRow); - } else if (childRow >= 0) { - this.selectRow(branchRow, childRow - 1); - } - }, - - // Selects a row and makes sure the selection is within bounds - selectRow(parent, child) { - let maxParentRow = this.filter ? this._tabCount() : this.data.length; - let parentRow = parent; - if (parent <= -1) { - parentRow = 0; - } else if (parent >= maxParentRow) { - return; - } - - let childRow = child; - if (parentRow === -1 || this.filter || typeof child === "undefined" || child < -1) { - childRow = -1; - } else if (child >= this.data[parentRow].tabs.length) { - childRow = this.data[parentRow].tabs.length - 1; - } - - if (this._selectedRow[0] === parentRow && this._selectedRow[1] === childRow) { - return; - } - - this._selectedRow = [parentRow, childRow]; - this.inputFocused = false; - this._change("all"); - }, - - _tabCount() { - return this.data.reduce((prev, curr) => curr.tabs.length + prev, 0); - }, - - toggleBranch(id) { - this._toggleBranch(id, !this._closedClients[id]); - }, - - closeBranch(id) { - this._toggleBranch(id, true); - }, - - openBranch(id) { - this._toggleBranch(id, false); - }, - - focusInput() { - this.inputFocused = true; - // A change type of "all" updates rather than rebuilds, which is what we - // want here - only the selection/focus has changed. - this._change("all"); - }, - - blurInput() { - this.inputFocused = false; - // A change type of "all" updates rather than rebuilds, which is what we - // want here - only the selection/focus has changed. - this._change("all"); - }, - - clearFilter() { - this.filter = ""; - this._selectedRow = [-1, -1]; - return this.getData(); - }, - - // Fetches data from the SyncedTabs module and triggers - // and update - getData(filter) { - let updateType; - let hasFilter = typeof filter !== "undefined"; - if (hasFilter) { - this.filter = filter; - this._selectedRow = [-1, -1]; - - // When a filter is specified we tell the view that only the list - // needs to be rerendered so that it doesn't disrupt the input - // field's focus. - updateType = "searchbox"; - } - - // return promise for tests - return this._SyncedTabs.getTabClients(this.filter) - .then(result => { - if (!hasFilter) { - // Only sort clients and tabs if we're rendering the whole list. - this._SyncedTabs.sortTabClientsByLastUsed(result); - } - this.data = result; - this._change(updateType); - }) - .catch(Cu.reportError); - } -}); diff --git a/application/basilisk/components/syncedtabs/TabListComponent.js b/application/basilisk/components/syncedtabs/TabListComponent.js deleted file mode 100644 index aa60e4769..000000000 --- a/application/basilisk/components/syncedtabs/TabListComponent.js +++ /dev/null @@ -1,138 +0,0 @@ -/* 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"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -let log = Cu.import("resource://gre/modules/Log.jsm", {}) - .Log.repository.getLogger("Sync.RemoteTabs"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUIUtils", - "resource:///modules/PlacesUIUtils.jsm"); - -this.EXPORTED_SYMBOLS = [ - "TabListComponent" -]; - -/** - * TabListComponent - * - * The purpose of this component is to compose the view, state, and actions. - * It defines high level actions that act on the state and passes them to the - * view for it to trigger during user interaction. It also subscribes the view - * to state changes so it can rerender. - */ - -function TabListComponent({window, store, View, SyncedTabs, clipboardHelper, - getChromeWindow}) { - this._window = window; - this._store = store; - this._View = View; - this._clipboardHelper = clipboardHelper; - this._getChromeWindow = getChromeWindow; - // used to trigger Sync from context menu - this._SyncedTabs = SyncedTabs; -} - -TabListComponent.prototype = { - get container() { - return this._view.container; - }, - - init() { - log.debug("Initializing TabListComponent"); - - this._view = new this._View(this._window, { - onSelectRow: (...args) => this.onSelectRow(...args), - onOpenTab: (...args) => this.onOpenTab(...args), - onOpenTabs: (...args) => this.onOpenTabs(...args), - onMoveSelectionDown: (...args) => this.onMoveSelectionDown(...args), - onMoveSelectionUp: (...args) => this.onMoveSelectionUp(...args), - onToggleBranch: (...args) => this.onToggleBranch(...args), - onBookmarkTab: (...args) => this.onBookmarkTab(...args), - onCopyTabLocation: (...args) => this.onCopyTabLocation(...args), - onSyncRefresh: (...args) => this.onSyncRefresh(...args), - onFilter: (...args) => this.onFilter(...args), - onClearFilter: (...args) => this.onClearFilter(...args), - onFilterFocus: (...args) => this.onFilterFocus(...args), - onFilterBlur: (...args) => this.onFilterBlur(...args) - }); - - this._store.on("change", state => this._view.render(state)); - this._view.render({clients: []}); - // get what's already available... - this._store.getData(); - this._store.focusInput(); - }, - - uninit() { - this._view.destroy(); - }, - - onFilter(query) { - this._store.getData(query); - }, - - onClearFilter() { - this._store.clearFilter(); - }, - - onFilterFocus() { - this._store.focusInput(); - }, - - onFilterBlur() { - this._store.blurInput(); - }, - - onSelectRow(position) { - this._store.selectRow(position[0], position[1]); - }, - - onMoveSelectionDown() { - this._store.moveSelectionDown(); - }, - - onMoveSelectionUp() { - this._store.moveSelectionUp(); - }, - - onToggleBranch(id) { - this._store.toggleBranch(id); - }, - - onBookmarkTab(uri, title) { - this._window.top.PlacesCommandHook - .bookmarkLink(this._window.top.PlacesUtils.bookmarksMenuFolderId, uri, title) - .catch(Cu.reportError); - }, - - onOpenTab(url, where, params) { - this._window.openUILinkIn(url, where, params); - }, - - onOpenTabs(urls, where) { - if (!PlacesUIUtils.confirmOpenInTabs(urls.length, this._window)) { - return; - } - if (where == "window") { - this._window.openDialog(this._window.getBrowserURL(), "_blank", - "chrome,dialog=no,all", urls.join("|")); - } else { - let loadInBackground = where == "tabshifted" ? true : false; - this._getChromeWindow(this._window).gBrowser.loadTabs(urls, loadInBackground, false); - } - }, - - onCopyTabLocation(url) { - this._clipboardHelper.copyString(url); - }, - - onSyncRefresh() { - this._SyncedTabs.syncTabs(true); - } -}; diff --git a/application/basilisk/components/syncedtabs/TabListView.js b/application/basilisk/components/syncedtabs/TabListView.js deleted file mode 100644 index dab15101b..000000000 --- a/application/basilisk/components/syncedtabs/TabListView.js +++ /dev/null @@ -1,568 +0,0 @@ -/* 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"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); - -let { getChromeWindow } = Cu.import("resource:///modules/syncedtabs/util.js", {}); - -let log = Cu.import("resource://gre/modules/Log.jsm", {}) - .Log.repository.getLogger("Sync.RemoteTabs"); - -this.EXPORTED_SYMBOLS = [ - "TabListView" -]; - -function getContextMenu(window) { - return getChromeWindow(window).document.getElementById("SyncedTabsSidebarContext"); -} - -function getTabsFilterContextMenu(window) { - return getChromeWindow(window).document.getElementById("SyncedTabsSidebarTabsFilterContext"); -} - -/* - * TabListView - * - * Given a state, this object will render the corresponding DOM. - * It maintains no state of it's own. It listens for DOM events - * and triggers actions that may cause the state to change and - * ultimately the view to rerender. - */ -function TabListView(window, props) { - this.props = props; - - this._window = window; - this._doc = this._window.document; - - this._tabsContainerTemplate = this._doc.getElementById("tabs-container-template"); - this._clientTemplate = this._doc.getElementById("client-template"); - this._emptyClientTemplate = this._doc.getElementById("empty-client-template"); - this._tabTemplate = this._doc.getElementById("tab-template"); - this.tabsFilter = this._doc.querySelector(".tabsFilter"); - this.clearFilter = this._doc.querySelector(".textbox-search-clear"); - this.searchBox = this._doc.querySelector(".search-box"); - this.searchIcon = this._doc.querySelector(".textbox-search-icon"); - - this.container = this._doc.createElement("div"); - - this._attachFixedListeners(); - - this._setupContextMenu(); -} - -TabListView.prototype = { - render(state) { - // Don't rerender anything; just update attributes, e.g. selection - if (state.canUpdateAll) { - this._update(state); - return; - } - // Rerender the tab list - if (state.canUpdateInput) { - this._updateSearchBox(state); - this._createList(state); - return; - } - // Create the world anew - this._create(state); - }, - - // Create the initial DOM from templates - _create(state) { - let wrapper = this._doc.importNode(this._tabsContainerTemplate.content, true).firstElementChild; - this._clearChilden(); - this.container.appendChild(wrapper); - - this.list = this.container.querySelector(".list"); - - this._createList(state); - this._updateSearchBox(state); - - this._attachListListeners(); - }, - - _createList(state) { - this._clearChilden(this.list); - for (let client of state.clients) { - if (state.filter) { - this._renderFilteredClient(client); - } else { - this._renderClient(client); - } - } - if (this.list.firstChild) { - const firstTab = this.list.firstChild.querySelector(".item.tab:first-child .item-title"); - if (firstTab) { - firstTab.setAttribute("tabindex", 2); - } - } - }, - - destroy() { - this._teardownContextMenu(); - this.container.remove(); - }, - - _update(state) { - this._updateSearchBox(state); - for (let client of state.clients) { - let clientNode = this._doc.getElementById("item-" + client.id); - if (clientNode) { - this._updateClient(client, clientNode); - } - - client.tabs.forEach((tab, index) => { - let tabNode = this._doc.getElementById('tab-' + client.id + '-' + index); - this._updateTab(tab, tabNode, index); - }); - } - }, - - // Client rows are hidden when the list is filtered - _renderFilteredClient(client, filter) { - client.tabs.forEach((tab, index) => { - let node = this._renderTab(client, tab, index); - this.list.appendChild(node); - }); - }, - - _renderClient(client) { - let itemNode = client.tabs.length ? - this._createClient(client) : - this._createEmptyClient(client); - - this._updateClient(client, itemNode); - - let tabsList = itemNode.querySelector(".item-tabs-list"); - client.tabs.forEach((tab, index) => { - let node = this._renderTab(client, tab, index); - tabsList.appendChild(node); - }); - - this.list.appendChild(itemNode); - return itemNode; - }, - - _renderTab(client, tab, index) { - let itemNode = this._createTab(tab); - this._updateTab(tab, itemNode, index); - return itemNode; - }, - - _createClient(item) { - return this._doc.importNode(this._clientTemplate.content, true).firstElementChild; - }, - - _createEmptyClient(item) { - return this._doc.importNode(this._emptyClientTemplate.content, true).firstElementChild; - }, - - _createTab(item) { - return this._doc.importNode(this._tabTemplate.content, true).firstElementChild; - }, - - _clearChilden(node) { - let parent = node || this.container; - while (parent.firstChild) { - parent.removeChild(parent.firstChild); - } - }, - - // These listeners are attached only once, when we initialize the view - _attachFixedListeners() { - this.tabsFilter.addEventListener("input", this.onFilter.bind(this)); - this.tabsFilter.addEventListener("focus", this.onFilterFocus.bind(this)); - this.tabsFilter.addEventListener("blur", this.onFilterBlur.bind(this)); - this.clearFilter.addEventListener("click", this.onClearFilter.bind(this)); - this.searchIcon.addEventListener("click", this.onFilterFocus.bind(this)); - }, - - // These listeners have to be re-created every time since we re-create the list - _attachListListeners() { - this.list.addEventListener("click", this.onClick.bind(this)); - this.list.addEventListener("mouseup", this.onMouseUp.bind(this)); - this.list.addEventListener("keydown", this.onKeyDown.bind(this)); - }, - - _updateSearchBox(state) { - if (state.filter) { - this.searchBox.classList.add("filtered"); - } else { - this.searchBox.classList.remove("filtered"); - } - this.tabsFilter.value = state.filter; - if (state.inputFocused) { - this.searchBox.setAttribute("focused", true); - this.tabsFilter.focus(); - } else { - this.searchBox.removeAttribute("focused"); - } - }, - - /** - * Update the element representing an item, ensuring it's in sync with the - * underlying data. - * @param {client} item - Item to use as a source. - * @param {Element} itemNode - Element to update. - */ - _updateClient(item, itemNode) { - itemNode.setAttribute("id", "item-" + item.id); - let lastSync = new Date(item.lastModified); - let lastSyncTitle = getChromeWindow(this._window).gSyncUI.formatLastSyncDate(lastSync); - itemNode.setAttribute("title", lastSyncTitle); - if (item.closed) { - itemNode.classList.add("closed"); - } else { - itemNode.classList.remove("closed"); - } - if (item.selected) { - itemNode.classList.add("selected"); - } else { - itemNode.classList.remove("selected"); - } - if (item.isMobile) { - itemNode.classList.add("device-image-mobile"); - } else { - itemNode.classList.add("device-image-desktop"); - } - if (item.focused) { - itemNode.focus(); - } - itemNode.dataset.id = item.id; - itemNode.querySelector(".item-title").textContent = item.name; - }, - - /** - * Update the element representing a tab, ensuring it's in sync with the - * underlying data. - * @param {tab} item - Item to use as a source. - * @param {Element} itemNode - Element to update. - */ - _updateTab(item, itemNode, index) { - itemNode.setAttribute("title", `${item.title}\n${item.url}`); - itemNode.setAttribute("id", "tab-" + item.client + '-' + index); - if (item.selected) { - itemNode.classList.add("selected"); - } else { - itemNode.classList.remove("selected"); - } - if (item.focused) { - itemNode.focus(); - } - itemNode.dataset.url = item.url; - - itemNode.querySelector(".item-title").textContent = item.title; - - if (item.icon) { - let icon = itemNode.querySelector(".item-icon-container"); - icon.style.backgroundImage = "url(" + item.icon + ")"; - } - }, - - onMouseUp(event) { - if (event.which == 2) { // Middle click - this.onClick(event); - } - }, - - onClick(event) { - let itemNode = this._findParentItemNode(event.target); - if (!itemNode) { - return; - } - - if (itemNode.classList.contains("tab")) { - let url = itemNode.dataset.url; - if (url) { - this.onOpenSelected(url, event); - } - } - - // Middle click on a client - if (itemNode.classList.contains("client")) { - let where = getChromeWindow(this._window).whereToOpenLink(event); - if (where != "current") { - const tabs = itemNode.querySelector(".item-tabs-list").childNodes; - const urls = [...tabs].map(tab => tab.dataset.url); - this.props.onOpenTabs(urls, where); - } - } - - if (event.target.classList.contains("item-twisty-container") - && event.which != 2) { - this.props.onToggleBranch(itemNode.dataset.id); - return; - } - - let position = this._getSelectionPosition(itemNode); - this.props.onSelectRow(position); - }, - - /** - * Handle a keydown event on the list box. - * @param {Event} event - Triggering event. - */ - onKeyDown(event) { - if (event.keyCode == this._window.KeyEvent.DOM_VK_DOWN) { - event.preventDefault(); - this.props.onMoveSelectionDown(); - } else if (event.keyCode == this._window.KeyEvent.DOM_VK_UP) { - event.preventDefault(); - this.props.onMoveSelectionUp(); - } else if (event.keyCode == this._window.KeyEvent.DOM_VK_RETURN) { - let selectedNode = this.container.querySelector('.item.selected'); - if (selectedNode.dataset.url) { - this.onOpenSelected(selectedNode.dataset.url, event); - } else if (selectedNode) { - this.props.onToggleBranch(selectedNode.dataset.id); - } - } - }, - - onBookmarkTab() { - let item = this._getSelectedTabNode(); - if (item) { - let title = item.querySelector(".item-title").textContent; - this.props.onBookmarkTab(item.dataset.url, title); - } - }, - - onCopyTabLocation() { - let item = this._getSelectedTabNode(); - if (item) { - this.props.onCopyTabLocation(item.dataset.url); - } - }, - - onOpenSelected(url, event) { - let where = getChromeWindow(this._window).whereToOpenLink(event); - this.props.onOpenTab(url, where, {}); - }, - - onOpenSelectedFromContextMenu(event) { - let item = this._getSelectedTabNode(); - if (item) { - let where = event.target.getAttribute("where"); - let params = { - private: event.target.hasAttribute("private"), - }; - this.props.onOpenTab(item.dataset.url, where, params); - } - }, - - onFilter(event) { - let query = event.target.value; - if (query) { - this.props.onFilter(query); - } else { - this.props.onClearFilter(); - } - }, - - onClearFilter() { - this.props.onClearFilter(); - }, - - onFilterFocus() { - this.props.onFilterFocus(); - }, - onFilterBlur() { - this.props.onFilterBlur(); - }, - - _getSelectedTabNode() { - let item = this.container.querySelector('.item.selected'); - if (this._isTab(item) && item.dataset.url) { - return item; - } - return null; - }, - - // Set up the custom context menu - _setupContextMenu() { - Services.els.addSystemEventListener(this._window, "contextmenu", this, false); - for (let getMenu of [getContextMenu, getTabsFilterContextMenu]) { - let menu = getMenu(this._window); - menu.addEventListener("popupshowing", this, true); - menu.addEventListener("command", this, true); - } - }, - - _teardownContextMenu() { - // Tear down context menu - Services.els.removeSystemEventListener(this._window, "contextmenu", this, false); - for (let getMenu of [getContextMenu, getTabsFilterContextMenu]) { - let menu = getMenu(this._window); - menu.removeEventListener("popupshowing", this, true); - menu.removeEventListener("command", this, true); - } - }, - - handleEvent(event) { - switch (event.type) { - case "contextmenu": - this.handleContextMenu(event); - break; - - case "popupshowing": { - if (event.target.getAttribute("id") == "SyncedTabsSidebarTabsFilterContext") { - this.handleTabsFilterContextMenuShown(event); - } - break; - } - - case "command": { - let menu = event.target.closest("menupopup"); - switch (menu.getAttribute("id")) { - case "SyncedTabsSidebarContext": - this.handleContentContextMenuCommand(event); - break; - - case "SyncedTabsSidebarTabsFilterContext": - this.handleTabsFilterContextMenuCommand(event); - break; - } - break; - } - } - }, - - handleTabsFilterContextMenuShown(event) { - let document = event.target.ownerDocument; - let focusedElement = document.commandDispatcher.focusedElement; - if (focusedElement != this.tabsFilter) { - this.tabsFilter.focus(); - } - for (let item of event.target.children) { - if (!item.hasAttribute("cmd")) { - continue; - } - let command = item.getAttribute("cmd"); - let controller = document.commandDispatcher.getControllerForCommand(command); - if (controller.isCommandEnabled(command)) { - item.removeAttribute("disabled"); - } else { - item.setAttribute("disabled", "true"); - } - } - }, - - handleContentContextMenuCommand(event) { - let id = event.target.getAttribute("id"); - switch (id) { - case "syncedTabsOpenSelected": - case "syncedTabsOpenSelectedInTab": - case "syncedTabsOpenSelectedInWindow": - case "syncedTabsOpenSelectedInPrivateWindow": - this.onOpenSelectedFromContextMenu(event); - break; - case "syncedTabsBookmarkSelected": - this.onBookmarkTab(); - break; - case "syncedTabsCopySelected": - this.onCopyTabLocation(); - break; - case "syncedTabsRefresh": - case "syncedTabsRefreshFilter": - this.props.onSyncRefresh(); - break; - } - }, - - handleTabsFilterContextMenuCommand(event) { - let command = event.target.getAttribute("cmd"); - let dispatcher = getChromeWindow(this._window).document.commandDispatcher; - let controller = dispatcher.focusedElement.controllers.getControllerForCommand(command); - controller.doCommand(command); - }, - - handleContextMenu(event) { - let menu; - - if (event.target == this.tabsFilter) { - menu = getTabsFilterContextMenu(this._window); - } else { - let itemNode = this._findParentItemNode(event.target); - if (itemNode) { - let position = this._getSelectionPosition(itemNode); - this.props.onSelectRow(position); - } - menu = getContextMenu(this._window); - this.adjustContextMenu(menu); - } - - menu.openPopupAtScreen(event.screenX, event.screenY, true, event); - }, - - adjustContextMenu(menu) { - let item = this.container.querySelector('.item.selected'); - let showTabOptions = this._isTab(item); - - let el = menu.firstChild; - - while (el) { - if (showTabOptions || el.getAttribute("id") === "syncedTabsRefresh") { - el.hidden = false; - } else { - el.hidden = true; - } - - el = el.nextSibling; - } - }, - - /** - * Find the parent item element, from a given child element. - * @param {Element} node - Child element. - * @return {Element} Element for the item, or null if not found. - */ - _findParentItemNode(node) { - while (node && node !== this.list && node !== this._doc.documentElement && - !node.classList.contains("item")) { - node = node.parentNode; - } - - if (node !== this.list && node !== this._doc.documentElement) { - return node; - } - - return null; - }, - - _findParentBranchNode(node) { - while (node && !node.classList.contains("list") && node !== this._doc.documentElement && - !node.parentNode.classList.contains("list")) { - node = node.parentNode; - } - - if (node !== this.list && node !== this._doc.documentElement) { - return node; - } - - return null; - }, - - _getSelectionPosition(itemNode) { - let parent = this._findParentBranchNode(itemNode); - let parentPosition = this._indexOfNode(parent.parentNode, parent); - let childPosition = -1; - // if the node is not a client, find its position within the parent - if (parent !== itemNode) { - childPosition = this._indexOfNode(itemNode.parentNode, itemNode); - } - return [parentPosition, childPosition]; - }, - - _indexOfNode(parent, child) { - return Array.prototype.indexOf.call(parent.childNodes, child); - }, - - _isTab(item) { - return item && item.classList.contains("tab"); - } -}; diff --git a/application/basilisk/components/syncedtabs/moz.build b/application/basilisk/components/syncedtabs/moz.build deleted file mode 100644 index a6515d6a1..000000000 --- a/application/basilisk/components/syncedtabs/moz.build +++ /dev/null @@ -1,17 +0,0 @@ -# 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/. - -JAR_MANIFESTS += ['jar.mn'] - -EXTRA_JS_MODULES.syncedtabs += [ - 'EventEmitter.jsm', - 'SyncedTabsDeckComponent.js', - 'SyncedTabsDeckStore.js', - 'SyncedTabsDeckView.js', - 'SyncedTabsListStore.js', - 'TabListComponent.js', - 'TabListView.js', - 'util.js', -] - diff --git a/application/basilisk/components/syncedtabs/sidebar.js b/application/basilisk/components/syncedtabs/sidebar.js deleted file mode 100644 index 84df95e9d..000000000 --- a/application/basilisk/components/syncedtabs/sidebar.js +++ /dev/null @@ -1,30 +0,0 @@ -/* 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"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://services-sync/SyncedTabs.jsm"); -Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckComponent.js"); - -XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", - "resource://gre/modules/FxAccounts.jsm"); - -this.syncedTabsDeckComponent = new SyncedTabsDeckComponent({window, SyncedTabs, fxAccounts}); - -let onLoaded = () => { - syncedTabsDeckComponent.init(); - document.getElementById("template-container").appendChild(syncedTabsDeckComponent.container); -}; - -let onUnloaded = () => { - removeEventListener("DOMContentLoaded", onLoaded); - removeEventListener("unload", onUnloaded); - syncedTabsDeckComponent.uninit(); -}; - -addEventListener("DOMContentLoaded", onLoaded); -addEventListener("unload", onUnloaded); diff --git a/application/basilisk/components/syncedtabs/sidebar.xhtml b/application/basilisk/components/syncedtabs/sidebar.xhtml deleted file mode 100644 index 3efcbea0e..000000000 --- a/application/basilisk/components/syncedtabs/sidebar.xhtml +++ /dev/null @@ -1,114 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- 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/. --> - -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" [ - <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd"> - %browserDTD; - <!ENTITY % globalDTD - SYSTEM "chrome://global/locale/global.dtd"> - %globalDTD; - <!ENTITY % syncBrandDTD - SYSTEM "chrome://browser/locale/syncBrand.dtd"> - %syncBrandDTD; -]> -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - <head> - <script src="chrome://browser/content/syncedtabs/sidebar.js" type="application/javascript;version=1.8"></script> - <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/> - - <link rel="stylesheet" type="text/css" media="all" href="chrome://browser/skin/syncedtabs/sidebar.css"/> - <link rel="stylesheet" type="text/css" media="all" href="chrome://global/skin/"/> - <link rel="stylesheet" type="text/css" media="all" href="chrome://global/skin/textbox.css"/> - <link rel="stylesheet" type="text/css" media="all" href="chrome://browser/content/browser.css"/> - <title>&syncedTabs.sidebar.label;</title> - </head> - - <body dir="&locale.dir;" role="application"> - <template id="client-template"> - <div class="item client" role="option" tabindex="-1"> - <div class="item-title-container"> - <div class="item-twisty-container"></div> - <div class="item-icon-container"></div> - <p class="item-title"></p> - </div> - <div class="item-tabs-list"></div> - </div> - </template> - <template id="empty-client-template"> - <div class="item empty client" role="option" tabindex="-1"> - <div class="item-title-container"> - <div class="item-twisty-container"></div> - <div class="item-icon-container"></div> - <p class="item-title"></p> - </div> - <div class="item-tabs-list"> - <div class="item empty" role="option" tabindex="-1"> - <div class="item-title-container"> - <div class="item-icon-container"></div> - <p class="item-title">&syncedTabs.sidebar.notabs.label;</p> - </div> - </div> - </div> - </div> - </template> - <template id="tab-template"> - <div class="item tab" role="option" tabindex="-1"> - <div class="item-title-container"> - <div class="item-icon-container"></div> - <p class="item-title"></p> - </div> - </div> - </template> - - <template id="tabs-container-template"> - <div class="tabs-container"> - <div class="list" role="listbox"></div> - </div> - </template> - - <template id="deck-template"> - <div class="deck"> - <div class="tabs-fetching sync-state"> - <!-- Show intentionally blank panel, see bug 1239845 --> - </div> - <div class="notAuthedInfo sync-state"> - <p>&syncedTabs.sidebar.notsignedin.label;</p> - <p><a href="#" class="sync-prefs text-link">&fxaSignIn.label;</a></p> - </div> - <div class="singleDeviceInfo sync-state"> - <p>&syncedTabs.sidebar.noclients.title;</p> - <p>&syncedTabs.sidebar.noclients.subtitle;</p> - <p class="device-promo" fxAccountsBrand="&syncBrand.fxAccount.label;"></p> - </div> - <div class="tabs-disabled sync-state"> - <p>&syncedTabs.sidebar.tabsnotsyncing.label;</p> - <p><a href="#" class="sync-prefs text-link">&syncedTabs.sidebar.openprefs.label;</a></p> - </div> - </div> - </template> - - <div class="content-container"> - <!-- the non-scrollable header --> - <div class="content-header"> - <div class="sidebar-search-container tabs-container sync-state"> - <div class="search-box compact"> - <div class="textbox-input-box"> - <input type="text" class="tabsFilter textbox-input" tabindex="1"/> - <div class="textbox-search-icons"> - <a class="textbox-search-clear"></a> - <a class="textbox-search-icon"></a> - </div> - </div> - </div> - </div> - </div> - <!-- the scrollable content area where our templates are inserted --> - <div id="template-container" class="content-scrollable" tabindex="-1"> - </div> - </div> - </body> -</html> diff --git a/application/basilisk/components/syncedtabs/util.js b/application/basilisk/components/syncedtabs/util.js deleted file mode 100644 index e09a1a528..000000000 --- a/application/basilisk/components/syncedtabs/util.js +++ /dev/null @@ -1,23 +0,0 @@ -/* 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"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -this.EXPORTED_SYMBOLS = [ - "getChromeWindow" -]; - -// Get the chrome (ie, browser) window hosting this content. -function getChromeWindow(window) { - return window - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow) - .wrappedJSObject; -} diff --git a/application/basilisk/configure.in b/application/basilisk/configure.in index 4e7a06390..13f2ad54d 100644 --- a/application/basilisk/configure.in +++ b/application/basilisk/configure.in @@ -16,3 +16,10 @@ AC_SUBST(MC_BASILISK) dnl Optional parts of the build. +dnl ======================================================== +dnl = Disable Sync +dnl ======================================================== +MOZ_ARG_DISABLE_BOOL(sync, +[ --disable-sync Disable Sync], + MOZ_SERVICES_SYNC=, + MOZ_SERVICES_SYNC=1)
\ No newline at end of file diff --git a/application/basilisk/locales/en-US/chrome/browser/aboutAccounts.dtd b/application/basilisk/locales/en-US/chrome/browser/aboutAccounts.dtd deleted file mode 100644 index 358722156..000000000 --- a/application/basilisk/locales/en-US/chrome/browser/aboutAccounts.dtd +++ /dev/null @@ -1,16 +0,0 @@ -<!-- 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/. --> - -<!ENTITY aboutAccounts.welcome "Welcome to &syncBrand.shortName.label;"> -<!ENTITY aboutAccounts.connected "Account connected"> - -<!ENTITY aboutAccountsConfig.description "Sign in to sync your tabs, bookmarks, passwords & more."> -<!ENTITY aboutAccountsConfig.startButton.label "Get started"> -<!ENTITY aboutAccountsConfig.useOldSync.label "Using an older version of Sync?"> -<!ENTITY aboutAccountsConfig.syncPreferences.label "Sync preferences"> -<!ENTITY aboutAccounts.noConnection.title "No connection"> -<!ENTITY aboutAccounts.noConnection.description "You must be connected to the Internet to sign in."> -<!ENTITY aboutAccounts.noConnection.retry "Try again"> -<!ENTITY aboutAccounts.badConfig.title "Bad configuration"> -<!ENTITY aboutAccounts.badConfig.description "Unable to determine your Firefox Account server configuration. Please try again later."> diff --git a/application/basilisk/locales/en-US/chrome/browser/browser.dtd b/application/basilisk/locales/en-US/chrome/browser/browser.dtd index d02a6eedb..87f4a7807 100644 --- a/application/basilisk/locales/en-US/chrome/browser/browser.dtd +++ b/application/basilisk/locales/en-US/chrome/browser/browser.dtd @@ -723,43 +723,19 @@ you can use these alternative items. Otherwise, their values should be empty. - The word "toolbar" is appended automatically and should not be contained below! --> <!ENTITY tabsToolbar.label "Browser tabs"> -<!-- LOCALIZATION NOTE (syncTabsMenu3.label): This appears in the history menu --> -<!ENTITY syncTabsMenu3.label "Synced Tabs"> - -<!ENTITY syncedTabs.sidebar.label "Synced Tabs"> -<!ENTITY syncedTabs.sidebar.noclients.label "Sign in to Firefox from your other devices to view their tabs here."> -<!ENTITY syncedTabs.sidebar.noclients.title "No synced tabs… yet!"> -<!ENTITY syncedTabs.sidebar.noclients.subtitle "Want to see your tabs from other devices here?"> -<!ENTITY syncedTabs.sidebar.notsignedin.label "Sign in to view a list of tabs from your other devices."> -<!ENTITY syncedTabs.sidebar.notabs.label "No open tabs"> -<!ENTITY syncedTabs.sidebar.openprefs.label "Open &syncBrand.shortName.label; Preferences"> -<!-- LOCALIZATION NOTE (syncedTabs.sidebar.tabsnotsyncing.label): This is shown - when Sync is configured but syncing tabs is disabled. --> -<!ENTITY syncedTabs.sidebar.tabsnotsyncing.label "Turn on tab syncing to view a list of tabs from your other devices."> - -<!ENTITY syncedTabs.context.open.label "Open"> -<!ENTITY syncedTabs.context.open.accesskey "O"> -<!ENTITY syncedTabs.context.openInNewTab.label "Open in a New Tab"> -<!ENTITY syncedTabs.context.openInNewTab.accesskey "w"> -<!ENTITY syncedTabs.context.openInNewWindow.label "Open in a New Window"> -<!ENTITY syncedTabs.context.openInNewWindow.accesskey "N"> -<!ENTITY syncedTabs.context.openInNewPrivateWindow.label "Open in a New Private Window"> -<!ENTITY syncedTabs.context.openInNewPrivateWindow.accesskey "P"> -<!ENTITY syncedTabs.context.bookmarkSingleTab.label "Bookmark This Tab…"> -<!ENTITY syncedTabs.context.bookmarkSingleTab.accesskey "B"> -<!ENTITY syncedTabs.context.copy.label "Copy"> -<!ENTITY syncedTabs.context.copy.accesskey "C"> - +#ifdef MOZ_SERVICES_SYNC +<!-- LOCALIZATION NOTE (syncTabsMenu2.label): This appears in the history menu --> +<!ENTITY syncTabsMenu2.label "Tabs From Other Devices"> <!ENTITY syncBrand.shortName.label "Sync"> -<!ENTITY syncSignIn.label "Sign In To &syncBrand.shortName.label;…"> -<!ENTITY syncSignIn.accesskey "Y"> +<!ENTITY syncSetup.label "Set Up &syncBrand.shortName.label;…"> +<!ENTITY syncSetup.accesskey "Y"> <!ENTITY syncSyncNowItem.label "Sync Now"> <!ENTITY syncSyncNowItem.accesskey "S"> -<!ENTITY syncReAuthItem.label "Reconnect to &syncBrand.shortName.label;…"> -<!ENTITY syncReAuthItem.accesskey "R"> <!ENTITY syncToolbarButton.label "Sync"> +<!ENTITY syncTabsToolbarButton.label "Synced Tabs"> +#endif <!ENTITY customizeMode.menuAndToolbars.header2 "Additional Tools and Features"> <!ENTITY customizeMode.menuAndToolbars.empty "Want more tools?"> diff --git a/application/basilisk/locales/en-US/chrome/browser/preferences/sync.dtd b/application/basilisk/locales/en-US/chrome/browser/preferences/sync.dtd index a5b290052..f6ef3b876 100644 --- a/application/basilisk/locales/en-US/chrome/browser/preferences/sync.dtd +++ b/application/basilisk/locales/en-US/chrome/browser/preferences/sync.dtd @@ -39,80 +39,9 @@ <!-- Device Settings --> <!ENTITY syncDeviceName.label "Device Name:"> -<!ENTITY fxaSyncDeviceName.label "Device Name"> -<!ENTITY changeSyncDeviceName.label "Change Device Name…"> -<!ENTITY changeSyncDeviceName.accesskey "h"> -<!ENTITY cancelChangeSyncDeviceName.label "Cancel"> -<!ENTITY cancelChangeSyncDeviceName.accesskey "n"> -<!ENTITY saveChangeSyncDeviceName.label "Save"> -<!ENTITY saveChangeSyncDeviceName.accesskey "v"> +<!ENTITY syncDeviceName.accesskey "c"> <!ENTITY unlinkDevice.label "Unlink This Device"> <!-- Footer stuff --> <!ENTITY prefs.tosLink.label "Terms of Service"> <!ENTITY prefs.ppLink.label "Privacy Policy"> - -<!-- Firefox Accounts stuff --> -<!ENTITY fxaPrivacyNotice.link.label "Privacy Notice"> -<!ENTITY determiningAcctStatus.label "Determining your account status…"> - -<!-- LOCALIZATION NOTE (signedInUnverified.beforename.label, -signedInUnverified.aftername.label): these two string are used respectively -before and after the account email address. Localizers can use one of them, or -both, to better adapt this sentence to their language. ---> -<!ENTITY signedInUnverified.beforename.label ""> -<!ENTITY signedInUnverified.aftername.label "is not verified."> - -<!-- LOCALIZATION NOTE (signedInLoginFailure.beforename.label, -signedInLoginFailure.aftername.label): these two string are used respectively -before and after the account email address. Localizers can use one of them, or -both, to better adapt this sentence to their language. ---> -<!ENTITY signedInLoginFailure.beforename.label "Please sign in to reconnect"> -<!ENTITY signedInLoginFailure.aftername.label ""> - -<!ENTITY notSignedIn.label "You are not signed in."> -<!ENTITY signIn.label "Sign in"> -<!ENTITY signIn.accesskey "g"> -<!ENTITY profilePicture.tooltip "Change profile picture"> -<!ENTITY verifiedManage.label "Manage Account"> -<!ENTITY verifiedManage.accesskey "o"> -<!ENTITY disconnect.label "Disconnect…"> -<!ENTITY disconnect.accesskey "D"> -<!ENTITY verify.label "Verify Email"> -<!ENTITY verify.accesskey "V"> -<!ENTITY forget.label "Forget this Email"> -<!ENTITY forget.accesskey "F"> - -<!ENTITY welcome.description "Access your tabs, bookmarks, passwords and more wherever you use &brandShortName;."> -<!ENTITY welcome.signIn.label "Sign In"> -<!ENTITY welcome.createAccount.label "Create Account"> - -<!ENTITY welcome.useOldSync.label "Using an older version of Sync?"> - -<!ENTITY signedOut.caption "Take your Web with you"> -<!ENTITY signedOut.description "Synchronize your bookmarks, history, tabs, passwords, add-ons, and preferences across all your devices."> -<!ENTITY signedOut.accountBox.title "Connect with a &syncBrand.fxAccount.label;"> -<!ENTITY signedOut.accountBox.create "Create Account"> -<!ENTITY signedOut.accountBox.create.accesskey "C"> -<!ENTITY signedOut.accountBox.signin "Sign In"> -<!ENTITY signedOut.accountBox.signin.accesskey "I"> - -<!ENTITY signedIn.engines.label "Sync across all devices"> - -<!-- LOCALIZATION NOTE (mobilePromo3.*): the following strings will be used to - create a single sentence with active links. - The resulting sentence in English is: "Download Firefox for - Android or iOS to sync with your mobile device." --> - -<!ENTITY mobilePromo3.start "Download Firefox for "> -<!-- LOCALIZATION NOTE (mobilePromo3.androidLink): This is a link title that links to https://www.mozilla.org/firefox/android/ --> -<!ENTITY mobilePromo3.androidLink "Android"> - -<!-- LOCALIZATION NOTE (mobilePromo3.iOSBefore): This is text displayed between mobilePromo3.androidLink and mobilePromo3.iosLink --> -<!ENTITY mobilePromo3.iOSBefore " or "> -<!-- LOCALIZATION NOTE (mobilePromo3.iOSLink): This is a link title that links to https://www.mozilla.org/firefox/ios/ --> -<!ENTITY mobilePromo3.iOSLink "iOS"> - -<!ENTITY mobilePromo3.end " to sync with your mobile device."> diff --git a/application/basilisk/locales/en-US/chrome/browser/syncBrand.dtd b/application/basilisk/locales/en-US/chrome/browser/syncBrand.dtd index 71a9f68af..bc4d1b3e0 100644 --- a/application/basilisk/locales/en-US/chrome/browser/syncBrand.dtd +++ b/application/basilisk/locales/en-US/chrome/browser/syncBrand.dtd @@ -4,4 +4,3 @@ <!ENTITY syncBrand.shortName.label "Sync"> <!ENTITY syncBrand.fullName.label "Pale Moon Sync"> -<!ENTITY syncBrand.fxAccount.label "Firefox Account"> diff --git a/application/basilisk/locales/en-US/chrome/browser/syncKey.dtd b/application/basilisk/locales/en-US/chrome/browser/syncKey.dtd index 2ff001842..f37f2c92e 100644 --- a/application/basilisk/locales/en-US/chrome/browser/syncKey.dtd +++ b/application/basilisk/locales/en-US/chrome/browser/syncKey.dtd @@ -5,12 +5,12 @@ <!ENTITY syncKey.page.title "Your &syncBrand.fullName.label; Key"> <!ENTITY syncKey.page.description2 "This key is used to decode the data in your &syncBrand.fullName.label; account. You will need to enter the key each time you configure &syncBrand.fullName.label; on a new device."> <!ENTITY syncKey.keepItSecret.heading "Keep it secret"> -<!ENTITY syncKey.keepItSecret.description "Your &syncBrand.fullName.label; account is encrypted to protect your privacy. Without this key, it would take years for anyone to decode your personal information. You are the only person who holds this key. This means you’re the only one who can access your &syncBrand.fullName.label; data."> +<!ENTITY syncKey.keepItSecret.description "Your &syncBrand.fullName.label; account is encrypted to protect your privacy. Without this key, it would take years for anyone to decode your personal information. You are the only person who holds this key. This means you're the only one who can access your &syncBrand.fullName.label; data."> <!ENTITY syncKey.keepItSafe.heading "Keep it safe"> <!ENTITY syncKey.keepItSafe1.description "Do not lose this key."> -<!ENTITY syncKey.keepItSafe2.description " We don’t keep a copy of your key (that wouldn’t be keeping it secret!) so "> -<!ENTITY syncKey.keepItSafe3.description "we can’t help you recover it"> -<!ENTITY syncKey.keepItSafe4a.description " if it’s lost. You’ll need to use this key any time you connect a new device to &syncBrand.fullName.label;."> +<!ENTITY syncKey.keepItSafe2.description " We don't keep a copy of your key (that wouldn't be keeping it secret!) so "> +<!ENTITY syncKey.keepItSafe3.description "we can't help you recover it"> +<!ENTITY syncKey.keepItSafe4a.description " if it's lost. You'll need to use this key any time you connect a new device to &syncBrand.fullName.label;."> <!ENTITY syncKey.findOutMore1.label "Find out more about &syncBrand.fullName.label; and your privacy at "> <!ENTITY syncKey.findOutMore2.label "."> <!ENTITY syncKey.footer1.label "&syncBrand.fullName.label; Terms of Service are available at "> diff --git a/application/basilisk/locales/en-US/chrome/browser/syncProgress.dtd b/application/basilisk/locales/en-US/chrome/browser/syncProgress.dtd new file mode 100644 index 000000000..db45cb935 --- /dev/null +++ b/application/basilisk/locales/en-US/chrome/browser/syncProgress.dtd @@ -0,0 +1,15 @@ +<!-- 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/. --> + +<!ENTITY % brandDTD + SYSTEM "chrome://branding/locale/brand.dtd"> + %brandDTD; + +<!-- These strings are used in the sync progress upload page --> +<!ENTITY syncProgress.pageTitle "Your First Sync"> +<!ENTITY syncProgress.textBlurb "Your data is now being encrypted and uploaded in the background. You can close this tab and continue using &brandShortName;."> +<!ENTITY syncProgress.closeButton "Close"> +<!ENTITY syncProgress.logoAltText "&brandShortName; logo"> +<!ENTITY syncProgress.diffText "&brandShortName; will now automatically sync in the background. You can close this tab and continue using &brandShortName;."> + diff --git a/application/basilisk/locales/en-US/chrome/browser/syncQuota.properties b/application/basilisk/locales/en-US/chrome/browser/syncQuota.properties index 099090ec9..0e1b857ca 100644 --- a/application/basilisk/locales/en-US/chrome/browser/syncQuota.properties +++ b/application/basilisk/locales/en-US/chrome/browser/syncQuota.properties @@ -30,7 +30,7 @@ quota.remove.label = Remove quota.treeCaption.label = Uncheck items to stop syncing them and free up space on the server. # LOCALIZATION NOTE (quota.removal.label): %S is a list of engines that will be # disabled and whose data will be removed once the user confirms. -quota.removal.label = Firefox Sync will remove the following data: %S. +quota.removal.label = Sync will remove the following data: %S. # LOCALIZATION NOTE (quota.list.separator): This is the separator string used # for the list of engines (incl. spaces where appropriate) quota.list.separator = ,\u0020 diff --git a/application/basilisk/locales/en-US/chrome/browser/syncSetup.dtd b/application/basilisk/locales/en-US/chrome/browser/syncSetup.dtd index 2657156b7..7ee938e5d 100644 --- a/application/basilisk/locales/en-US/chrome/browser/syncSetup.dtd +++ b/application/basilisk/locales/en-US/chrome/browser/syncSetup.dtd @@ -6,13 +6,13 @@ <!-- First page of the wizard --> -<!ENTITY setup.pickSetupType.description2 "Welcome! If you’ve never used &syncBrand.fullName.label; before, you will need to create a new account."> +<!ENTITY setup.pickSetupType.description2 "Welcome! If you've never used &syncBrand.fullName.label; before, you will need to create a new account."> <!ENTITY button.createNewAccount.label "Create a New Account"> <!ENTITY button.haveAccount.label "I Have an Account"> <!ENTITY setup.choicePage.title.label "Have you used &syncBrand.fullName.label; before?"> -<!ENTITY setup.choicePage.new.label "I’ve never used &syncBrand.shortName.label; before"> -<!ENTITY setup.choicePage.existing2.label "I’m already using &syncBrand.shortName.label; on another device"> +<!ENTITY setup.choicePage.new.label "I've never used &syncBrand.shortName.label; before"> +<!ENTITY setup.choicePage.existing2.label "I'm already using &syncBrand.shortName.label; on another device"> <!-- New Account AND Existing Account --> <!ENTITY server.label "Server"> @@ -33,6 +33,8 @@ <!ENTITY setup.choosePassword.accesskey "P"> <!ENTITY setup.confirmPassword.label "Confirm Password"> <!ENTITY setup.confirmPassword.accesskey "m"> +<!ENTITY setup.setupMetro.label "Sync with Windows 8 style &brandShortName;"> +<!ENTITY setup.setupMetro.accesskey "S"> <!-- LOCALIZATION NOTE: tosAgree1, tosLink, tosAgree2, ppLink, tosAgree3 are joined with implicit white space, so spaces in the strings aren't necessary --> @@ -60,7 +62,7 @@ <!-- Existing Account Page 1: Pair a Device (incl. Pair a Device dialog strings) --> <!ENTITY pairDevice.title.label "Pair a Device"> <!ENTITY addDevice.showMeHow.label "Show me how."> -<!ENTITY addDevice.dontHaveDevice.label "I don’t have the device with me"> +<!ENTITY addDevice.dontHaveDevice.label "I don't have the device with me"> <!ENTITY pairDevice.setup.description.label "To activate, select "Pair a Device" on your other device."> <!ENTITY addDevice.setup.enterCode.label "Then, enter this code:"> <!ENTITY pairDevice.dialog.description.label "To activate your new device, select "Set Up Sync" on the device."> @@ -72,7 +74,7 @@ <!-- Existing Account Page 2: Manual Login --> <!ENTITY setup.signInPage.title.label "Sign In"> -<!ENTITY existingRecoveryKey.description "You can get a copy of your Recovery Key by going to &syncBrand.shortName.label; Preferences on your other device, and selecting "My Recovery Key" under "Manage Account"."> +<!ENTITY existingRecoveryKey.description "You can get a copy of your Recovery Key by going to &syncBrand.shortName.label; Options on your other device, and selecting "My Recovery Key" under "Manage Account"."> <!ENTITY verifying.label "Verifying…"> <!ENTITY resetPassword.label "Reset Password"> <!ENTITY resetSyncKey.label "I have lost my other device."> @@ -96,14 +98,14 @@ <!ENTITY engine.addons.label "Add-ons"> <!ENTITY engine.addons.accesskey "A"> -<!ENTITY choice2a.merge.main.label "Merge this device’s data with my &syncBrand.shortName.label; data"> +<!ENTITY choice2a.merge.main.label "Merge this device's data with my &syncBrand.shortName.label; data"> <!ENTITY choice2.merge.recommended.label "Recommended:"> <!ENTITY choice2a.client.main.label "Replace all data on this device with my &syncBrand.shortName.label; data"> -<!ENTITY choice2a.server.main.label "Replace all other devices with this device’s data"> +<!ENTITY choice2a.server.main.label "Replace all other devices with this device's data"> <!-- Confirm Merge Options --> <!ENTITY setup.optionsConfirmPage.title "Confirm"> -<!ENTITY confirm.merge2.label "&syncBrand.fullName.label; will now merge all this device’s browser data into your Sync account."> +<!ENTITY confirm.merge2.label "&syncBrand.fullName.label; will now merge all this device's browser data into your Sync account."> <!ENTITY confirm.client3.label "Warning: The following &brandShortName; data on this device will be deleted:"> <!ENTITY confirm.client2.moreinfo.label "&brandShortName; will then copy your &syncBrand.fullName.label; data to this device."> <!ENTITY confirm.server2.label "Warning: The following devices will be overwritten with your local data:"> diff --git a/application/basilisk/locales/en-US/chrome/browser/syncSetup.properties b/application/basilisk/locales/en-US/chrome/browser/syncSetup.properties index 9d388af86..8a5170adb 100644 --- a/application/basilisk/locales/en-US/chrome/browser/syncSetup.properties +++ b/application/basilisk/locales/en-US/chrome/browser/syncSetup.properties @@ -35,33 +35,17 @@ passwordsCount.label = #1 password;#1 passwords # LOCALIZATION NOTE (addonsCount.label): Semicolon-separated list of plural forms. # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals # #1 is the number of add-ons, see the link above for forms -addonsCount.label = #1 add-on;#1 add-ons +addonsCount.label = #1 addon;#1 addons save.recoverykey.title = Save Recovery Key -save.recoverykey.defaultfilename = Firefox Recovery Key.html +save.recoverykey.defaultfilename = Pale Moon Recovery Key.html -newAccount.action.label = Firefox Sync is now set up to automatically sync all of your browser data. +newAccount.action.label = Sync is now set up to automatically sync all of your browser data. newAccount.change.label = You can choose exactly what to sync by selecting Sync Options below. -resetClient.change2.label = Firefox Sync will now merge all this device’s browser data into your Sync account. -wipeClient.change2.label = Firefox Sync will now replace all of the browser data on this device with the data in your Sync account. -wipeRemote.change2.label = Firefox Sync will now replace all of the browser data in your Sync account with the data on this device. +resetClient.change2.label = Sync will now merge all this device's browser data into your Sync account. +wipeClient.change2.label = Sync will now replace all of the browser data on this device with the data in your Sync account. +wipeRemote.change2.label = Sync will now replace all of the browser data in your Sync account with the data on this device. existingAccount.change.label = You can change this preference by selecting Sync Options below. # Several other strings are used (via Weave.Status.login), but they come from # /services/sync - -# Firefox Accounts based setup. -continue.label = Continue - -# LOCALIZATION NOTE (disconnect.label, disconnect.verify.title, disconnect.verify.bodyHeading, disconnect.verify.bodyText): -# These strings are used in the confirmation dialog shown when the user hits the disconnect button -# LOCALIZATION NOTE (disconnect.label): This is the label for the disconnect button -disconnect.label = Disconnect -disconnect.verify.title = Disconnect -disconnect.verify.bodyHeading = Disconnect from Sync? -disconnect.verify.bodyText = Your browsing data will remain on this computer, but it will no longer sync with your account. - -relinkVerify.title = Merge Warning -relinkVerify.heading = Are you sure you want to sign in to Sync? -# LOCALIZATION NOTE (relinkVerify.description): Email address of a user previously signed into sync. -relinkVerify.description = A different user was previously signed in to Sync on this computer. Signing in will merge this browser’s bookmarks, passwords and other settings with %S diff --git a/application/basilisk/locales/jar.mn b/application/basilisk/locales/jar.mn index 1a9b7f315..1e1e9be2f 100644 --- a/application/basilisk/locales/jar.mn +++ b/application/basilisk/locales/jar.mn @@ -7,7 +7,6 @@ @AB_CD@.jar: % locale browser @AB_CD@ %locale/browser/ * locale/browser/bookmarks.html (generic/profile/bookmarks.html.in) - locale/browser/aboutAccounts.dtd (%chrome/browser/aboutAccounts.dtd) locale/browser/aboutDialog.dtd (%chrome/browser/aboutDialog.dtd) locale/browser/aboutPrivateBrowsing.dtd (%chrome/browser/aboutPrivateBrowsing.dtd) locale/browser/aboutPrivateBrowsing.properties (%chrome/browser/aboutPrivateBrowsing.properties) @@ -20,8 +19,7 @@ locale/browser/aboutSessionRestore.dtd (%chrome/browser/aboutSessionRestore.dtd) locale/browser/aboutTabCrashed.dtd (%chrome/browser/aboutTabCrashed.dtd) locale/browser/syncCustomize.dtd (%chrome/browser/syncCustomize.dtd) - locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd) - locale/browser/browser.dtd (%chrome/browser/browser.dtd) +* locale/browser/browser.dtd (%chrome/browser/browser.dtd) locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd) locale/browser/browser.properties (%chrome/browser/browser.properties) locale/browser/customizableui/customizableWidgets.properties (%chrome/browser/customizableui/customizableWidgets.properties) @@ -90,6 +88,10 @@ locale/browser/syncKey.dtd (%chrome/browser/syncKey.dtd) locale/browser/syncQuota.dtd (%chrome/browser/syncQuota.dtd) locale/browser/syncQuota.properties (%chrome/browser/syncQuota.properties) +#ifdef MOZ_SERVICES_SYNC + locale/browser/syncProgress.dtd (%chrome/browser/syncProgress.dtd) + locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd) +#endif % resource search-plugins chrome://browser/locale/searchplugins/ #if BUILD_FASTER locale/browser/searchplugins/ (searchplugins/*.xml) diff --git a/application/basilisk/themes/linux/jar.mn b/application/basilisk/themes/linux/jar.mn index 189027812..5835b1ca6 100644 --- a/application/basilisk/themes/linux/jar.mn +++ b/application/basilisk/themes/linux/jar.mn @@ -9,7 +9,6 @@ browser.jar: skin/classic/browser/sanitizeDialog.css skin/classic/browser/aboutSessionRestore-window-icon.png skin/classic/browser/aboutSyncTabs.css -* skin/classic/browser/syncedtabs/sidebar.css (syncedtabs/sidebar.css) skin/classic/browser/actionicon-tab.png * skin/classic/browser/browser.css * skin/classic/browser/devedition.css @@ -125,6 +124,7 @@ browser.jar: skin/classic/browser/syncQuota.css skin/classic/browser/syncProgress-horizontalbar.png skin/classic/browser/syncProgress-horizontalbar@2x.png + skin/classic/browser/syncProgress.css [extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar: % override chrome://browser/skin/feeds/audioFeedIcon.png chrome://browser/skin/feeds/feedIcon.png diff --git a/application/basilisk/themes/linux/syncProgress.css b/application/basilisk/themes/linux/syncProgress.css new file mode 100644 index 000000000..d7aa59976 --- /dev/null +++ b/application/basilisk/themes/linux/syncProgress.css @@ -0,0 +1,46 @@ +/* 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/. */ +@import url(chrome://global/skin/inContentUI.css); + +:root { + height: 100%; + width: 100%; + padding: 0; +} + +body { + margin: 0; + padding: 0 2em; +} + +#floatingBox { + margin: 4em auto; + max-width: 40em; + min-width: 23em; + padding: 1em 1.5em; + position: relative; + text-align: center; +} + +#successLogo { + margin: 1em 2em; +} + +#loadingText { + margin: 2em 6em; +} + +#progressBar { + margin: 2em 10em; +} + +#uploadProgressBar{ + width: 100%; +} + +#bottomRow { + margin-top: 2em; + padding: 0; + text-align: end; +} diff --git a/application/basilisk/themes/linux/syncedtabs/sidebar.css b/application/basilisk/themes/linux/syncedtabs/sidebar.css deleted file mode 100644 index 04e00a7d4..000000000 --- a/application/basilisk/themes/linux/syncedtabs/sidebar.css +++ /dev/null @@ -1,69 +0,0 @@ -/* 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/. */ - -%include ../../shared/syncedtabs/sidebar.inc.css - -/* These styles are intended to mimic XUL trees and the XUL search box. */ - -html { - border: 1px solid ThreeDShadow; - background-color: -moz-Field; - color: -moz-FieldText; - box-sizing: border-box; -} - -.item { - padding-inline-end: 0; -} - -.item-title { - margin: 1px 0 0; - margin-inline-end: 6px; -} - - -.search-box { - -moz-appearance: textfield; - cursor: text; - margin: 2px 4px; - border: 2px solid; - -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow; - -moz-border-right-colors: ThreeDHighlight ThreeDLightShadow; - -moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow; - -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow; - padding: 2px 2px 3px; - padding-inline-start: 4px; - background-color: -moz-Field; - color: -moz-FieldText; -} - -.textbox-search-clear { - background-image: url(moz-icon://stock/gtk-clear?size=menu); - background-repeat: no-repeat; - width: 16px; - height: 16px; -} - -.textbox-search-icon { - background-image: url(moz-icon://stock/gtk-find?size=menu); - background-repeat: no-repeat; - width: 16px; - height: 16px; - display: block; -} - -.textbox-search-icon[searchbutton]:not([disabled]) , -.textbox-search-clear:not([disabled]) { - cursor: pointer; -} - -.item.client .item-twisty-container { - -moz-appearance: treetwistyopen; - margin-top: 3px; - margin-left: 2px; -} - -.item.client.closed .item-twisty-container { - -moz-appearance: treetwisty; -} diff --git a/application/basilisk/themes/osx/jar.mn b/application/basilisk/themes/osx/jar.mn index 27802843d..39fcf6343 100644 --- a/application/basilisk/themes/osx/jar.mn +++ b/application/basilisk/themes/osx/jar.mn @@ -8,7 +8,6 @@ browser.jar: skin/classic/browser/sanitizeDialog.css skin/classic/browser/aboutSessionRestore-window-icon.png skin/classic/browser/aboutSyncTabs.css -* skin/classic/browser/syncedtabs/sidebar.css (syncedtabs/sidebar.css) skin/classic/browser/actionicon-tab.png skin/classic/browser/actionicon-tab@2x.png * skin/classic/browser/browser.css @@ -179,6 +178,7 @@ browser.jar: skin/classic/browser/syncProgress-toolbar@2x.png skin/classic/browser/syncProgress-toolbar-inverted.png skin/classic/browser/syncProgress-toolbar-inverted@2x.png + skin/classic/browser/syncProgress.css skin/classic/browser/Toolbar-background-noise.png (Toolbar-background-noise.png) skin/classic/browser/lion/toolbarbutton-dropmarker.png (toolbarbutton-dropmarker-lion.png) skin/classic/browser/toolbarbutton-dropmarker@2x.png (toolbarbutton-dropmarker-lion@2x.png) diff --git a/application/basilisk/themes/osx/syncProgress.css b/application/basilisk/themes/osx/syncProgress.css new file mode 100644 index 000000000..d7aa59976 --- /dev/null +++ b/application/basilisk/themes/osx/syncProgress.css @@ -0,0 +1,46 @@ +/* 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/. */ +@import url(chrome://global/skin/inContentUI.css); + +:root { + height: 100%; + width: 100%; + padding: 0; +} + +body { + margin: 0; + padding: 0 2em; +} + +#floatingBox { + margin: 4em auto; + max-width: 40em; + min-width: 23em; + padding: 1em 1.5em; + position: relative; + text-align: center; +} + +#successLogo { + margin: 1em 2em; +} + +#loadingText { + margin: 2em 6em; +} + +#progressBar { + margin: 2em 10em; +} + +#uploadProgressBar{ + width: 100%; +} + +#bottomRow { + margin-top: 2em; + padding: 0; + text-align: end; +} diff --git a/application/basilisk/themes/osx/syncedtabs/sidebar.css b/application/basilisk/themes/osx/syncedtabs/sidebar.css deleted file mode 100644 index 4d1de766c..000000000 --- a/application/basilisk/themes/osx/syncedtabs/sidebar.css +++ /dev/null @@ -1,154 +0,0 @@ -/* 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/. */ - -%include ../../shared/syncedtabs/sidebar.inc.css - -/* These styles are intended to mimic XUL trees and the XUL search box. */ - -.content-container { - -moz-appearance: -moz-mac-source-list; -} - -.item { - color: -moz-DialogText; -} - -.item-title-container { - box-sizing: border-box; - align-items: center; - height: 24px; - font-size: 12px; -} - -.item.selected > .item-title-container { - color: HighlightText; - font-weight: bold; -} - -.item.selected > .item-title-container { - -moz-appearance: -moz-mac-source-list-selection; -} - -.item.selected:focus > .item-title-container { - -moz-appearance: -moz-mac-active-source-list-selection; -} - -.item.client .item-twisty-container { - min-width: 16px; - height: 16px; - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded"); -} - -@media not all and (-moz-mac-yosemite-theme) { - .item.client.selected .item-twisty-container { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted"); - } - - .item.client.selected.closed .item-twisty-container { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted"); - } - - .item.client.selected .item-twisty-container:dir(rtl) { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted"); - } - - .item.client.selected.closed .item-twisty-container:dir(rtl) { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted-rtl"); - } -} - -.item.client.closed .item-twisty-container { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed"); -} - -.item.client.selected:focus .item-twisty-container { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted"); -} - -.item.client.selected.closed:focus .item-twisty-container { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted"); -} - -.item.client .item-twisty-container:dir(rtl) { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded"); -} - -.item.client.closed .item-twisty-container:dir(rtl) { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-rtl"); -} - -.item.client.selected:focus .item-twisty-container:dir(rtl) { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-expanded-inverted"); -} - -.item.client.selected.closed:focus .item-twisty-container:dir(rtl) { - background-image: url("chrome://global/skin/tree/arrow-disclosure.svg#arrow-disclosure-collapsed-inverted-rtl"); -} - -@media (-moz-mac-yosemite-theme) { - .item.selected > .item-title-container { - color: -moz-dialogtext; - font-weight: 500; - } - - .item.selected:focus > .item-title-container { - color: #fff; - } -} - -.sidebar-search-container { - border-bottom: 1px solid #bdbdbd; -} - -.search-box { - -moz-appearance: searchfield; - padding: 1px; - font-size: 12px; - cursor: text; - margin: 4px 8px 10px; - border-width: 3px; - border-style: solid; - border-color: currentcolor; - border-image: none; - -moz-border-top-colors: transparent #888 #000; - -moz-border-right-colors: transparent #FFF #000; - -moz-border-bottom-colors: transparent #FFF #000; - -moz-border-left-colors: transparent #888 #000; - border-top-right-radius: 2px; - border-bottom-left-radius: 2px; - background-color: #FFF; - color: #000; - -moz-user-select: text; - text-shadow: none; -} - -.search-box.compact > .textbox-input-box > .textbox-search-icons > .textbox-search-clear { - background-image: url(chrome://global/skin/icons/searchfield-cancel.svg); - background-repeat: no-repeat; - background-size: 11px 11px; - width: 11px; - height: 11px; -} - -.search-box.compact > .textbox-input-box > .textbox-search-icons > .textbox-search-icon { - display: none; -} - -.search-box[focused="true"] { - -moz-border-top-colors: -moz-mac-focusring -moz-mac-focusring #000000; - -moz-border-right-colors: -moz-mac-focusring -moz-mac-focusring #000000; - -moz-border-bottom-colors: -moz-mac-focusring -moz-mac-focusring #000000; - -moz-border-left-colors: -moz-mac-focusring -moz-mac-focusring #000000; -} - -.search-box.compact { - padding: 0px; - /* font size is in px because the XUL it was copied from uses px */ - font-size: 11px; -} - -.textbox-search-clear, -.textbox-search-icon { - margin-top: 1px; -} diff --git a/application/basilisk/themes/shared/browser.inc b/application/basilisk/themes/shared/browser.inc index 81caf94d6..6989f064a 100644 --- a/application/basilisk/themes/shared/browser.inc +++ b/application/basilisk/themes/shared/browser.inc @@ -2,7 +2,7 @@ % Note that zoom-reset-button is a bit different since it doesn't use an image and thus has the image with display: none. %define nestedButtons #zoom-out-button, #zoom-reset-button, #zoom-in-button, #cut-button, #copy-button, #paste-button -%define primaryToolbarButtons #back-button, #forward-button, #home-button, #print-button, #downloads-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #fullscreen-button, #sync-button, #feed-button, #open-file-button, #find-button, #developer-button, #preferences-button, #privatebrowsing-button, #save-page-button, #add-ons-button, #history-panelmenu, #nav-bar-overflow-button, #PanelUI-menu-button, #characterencoding-button, #email-link-button, #sidebar-button, @nestedButtons@, #e10s-button, #panic-button, #webide-button, #containers-panelmenu +%define primaryToolbarButtons #back-button, #forward-button, #home-button, #print-button, #downloads-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #fullscreen-button, #sync-button, #sync-tabs-button, #feed-button, #open-file-button, #find-button, #developer-button, #preferences-button, #privatebrowsing-button, #save-page-button, #add-ons-button, #history-panelmenu, #nav-bar-overflow-button, #PanelUI-menu-button, #characterencoding-button, #email-link-button, #sidebar-button, @nestedButtons@, #e10s-button, #panic-button, #webide-button, #containers-panelmenu %ifdef XP_MACOSX % Prior to 10.7 there wasn't a native fullscreen button so we use #restore-button to exit fullscreen diff --git a/application/basilisk/themes/shared/customizableui/panelUI.inc.css b/application/basilisk/themes/shared/customizableui/panelUI.inc.css index ba36da995..5550ef295 100644 --- a/application/basilisk/themes/shared/customizableui/panelUI.inc.css +++ b/application/basilisk/themes/shared/customizableui/panelUI.inc.css @@ -61,8 +61,7 @@ height: 13px; } -#PanelUI-menu-button[badge-status="download-warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge, -#PanelUI-menu-button[badge-status="fxa-needs-authentication"] > .toolbarbutton-badge-stack > .toolbarbutton-badge { +#PanelUI-menu-button[badge-status="download-warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge { box-shadow: none; filter: drop-shadow(0 1px 0 hsla(206, 50%, 10%, .15)); } @@ -86,13 +85,7 @@ background: #D90000; } -#PanelUI-menu-button[badge-status="fxa-needs-authentication"] > .toolbarbutton-badge-stack > .toolbarbutton-badge { - height: 13px; - background: transparent url(chrome://browser/skin/warning.svg) no-repeat center; -} - -#PanelUI-menu-button[badge-status="download-warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge:-moz-window-inactive, -#PanelUI-menu-button[badge-status="fxa-needs-authentication"] > .toolbarbutton-badge-stack > .toolbarbutton-badge:-moz-window-inactive { +#PanelUI-menu-button[badge-status="download-warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge:-moz-window-inactive { filter: none; } @@ -381,9 +374,6 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"] > iframe { #PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-contents-scroller > #PanelUI-contents > .panel-wide-item, #PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-contents-scroller > #PanelUI-contents > .toolbarbutton-1:not([panel-multiview-anchor="true"]), #PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-update-status, -#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-fxa > #PanelUI-fxa-status > #PanelUI-fxa-avatar, -#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-fxa > #PanelUI-fxa-status > #PanelUI-fxa-label, -#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-fxa > #PanelUI-fxa-icon, #PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > toolbarseparator, #PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > #PanelUI-customize, #PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > #PanelUI-help:not([panel-multiview-anchor="true"]) { @@ -481,26 +471,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { margin: 0; } -#main-window[customizing] #PanelUI-footer-fxa { - display: none; -} - -#PanelUI-footer-fxa:not([fxastatus="signedin"]) > toolbarseparator, -#PanelUI-footer-fxa:not([fxastatus="signedin"]) > #PanelUI-fxa-icon, -#PanelUI-footer-fxa:not([fxaprofileimage]) > #PanelUI-fxa-status > #PanelUI-fxa-avatar { - display: none; -} - -#PanelUI-footer-fxa[fxastatus="error"] > #PanelUI-fxa-status::after { - content: url(chrome://browser/skin/warning.svg); - filter: drop-shadow(0 1px 0 hsla(206,50%,10%,.15)); - width: 47px; - padding-top: 1px; - display: block; - text-align: center; - position: relative; - top: 25%; -} #PanelUI-update-status[update-status]::after { content: ""; @@ -523,40 +493,28 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { background-color: #D90000; } -#PanelUI-fxa-status { - display: flex; - flex: 1 1 0%; - width: 1px; -} - -#PanelUI-footer-inner, -#PanelUI-footer-fxa:not([hidden]) { +#PanelUI-footer-inner { display: flex; border-top: 1px solid var(--panel-separator-color); } -#PanelUI-multiView[viewtype="subview"] #PanelUI-footer-inner, -#PanelUI-multiView[viewtype="subview"] #PanelUI-footer-fxa { +#PanelUI-multiView[viewtype="subview"] #PanelUI-footer-inner { position: relative; } -#PanelUI-footer-inner > toolbarseparator, -#PanelUI-footer-fxa > toolbarseparator { +#PanelUI-footer-inner > toolbarseparator { border: 0; border-left: 1px solid var(--panel-separator-color); margin: 7px 0 7px; -moz-appearance: none; } -#PanelUI-footer-inner:hover > toolbarseparator, -#PanelUI-footer-fxa:hover > toolbarseparator { +#PanelUI-footer-inner:hover > toolbarseparator { margin: 0; } #PanelUI-update-status, #PanelUI-help, -#PanelUI-fxa-label, -#PanelUI-fxa-icon, #PanelUI-customize, #PanelUI-quit { margin: 0; @@ -590,7 +548,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { } #PanelUI-update-status > .toolbarbutton-text, -#PanelUI-fxa-label > .toolbarbutton-text, #PanelUI-customize > .toolbarbutton-text { margin: 0; padding: 0 6px; @@ -598,37 +555,23 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { } #PanelUI-help > .toolbarbutton-text, -#PanelUI-quit > .toolbarbutton-text, -#PanelUI-fxa-avatar > .toolbarbutton-text { +#PanelUI-quit > .toolbarbutton-text { display: none; } #PanelUI-update-status > .toolbarbutton-icon, -#PanelUI-fxa-label > .toolbarbutton-icon, -#PanelUI-fxa-icon > .toolbarbutton-icon, #PanelUI-customize > .toolbarbutton-icon, #PanelUI-help > .toolbarbutton-icon, #PanelUI-quit > .toolbarbutton-icon { margin-inline-end: 0; } -#PanelUI-fxa-icon { - padding-inline-start: 15px; - padding-inline-end: 15px; -} - -#PanelUI-fxa-label, #PanelUI-customize { flex: 1; padding-inline-start: 15px; border-inline-start-style: none; } -#PanelUI-footer-fxa[fxaprofileimage="set"] > #PanelUI-fxa-status > #PanelUI-fxa-label, -#PanelUI-footer-fxa[fxaprofileimage="enabled"]:not([fxastatus="error"]) > #PanelUI-fxa-status > #PanelUI-fxa-label { - padding-inline-start: 0px; -} - #PanelUI-update-status { width: calc(@menuPanelWidth@ + 30px); padding-inline-start: 15px; @@ -639,130 +582,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { list-style-image: url(chrome://branding/content/icon16.png); } -#PanelUI-fxa-label, -#PanelUI-fxa-icon { - list-style-image: url(chrome://browser/skin/sync-horizontalbar.png); -} - -#PanelUI-remotetabs { - --panel-ui-sync-illustration-height: 157.5px; -} - -.PanelUI-remotetabs-instruction-title, -.PanelUI-remotetabs-instruction-label, -#PanelUI-remotetabs-mobile-promo { - /* If you change the margin here, the min-height of the synced tabs panel - (e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, etc) may - need adjusting (see bug 1248506) */ - margin: 15px; - text-align: center; - text-shadow: none; - max-width: 15em; - color: GrayText; -} - -.PanelUI-remotetabs-instruction-title { - font-size: 1.3em; -} - -/* The boxes with "instructions" get extra top and bottom padding for space - around the illustration and buttons */ -.PanelUI-remotetabs-instruction-box { - /* If you change the padding here, the min-height of the synced tabs panel - (e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, etc) may - need adjusting (see bug 1248506) */ - padding-bottom: 30px; - padding-top: 15px; -} - -.PanelUI-remotetabs-prefs-button { - -moz-appearance: none; - background-color: #0096dd; - /* !important for the color as an OSX specific rule when a lightweight theme - is used for buttons in the toolbox overrides. See bug 1238531 for details */ - color: white !important; - border-radius: 2px; - /* If you change the margin or padding below, the min-height of the synced tabs - panel (e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, - etc) may need adjusting (see bug 1248506) */ - margin-top: 10px; - margin-bottom: 10px; - padding: 8px; - text-shadow: none; - min-width: 200px; -} - -.PanelUI-remotetabs-prefs-button:hover, -.PanelUI-remotetabs-prefs-button:hover:active { - background-color: #018acb; -} - -.remotetabs-promo-link { - margin: 0; -} - -.PanelUI-remotetabs-notabsforclient-label { - color: GrayText; - /* This margin is to line this label up with the labels in toolbarbuttons. */ - margin-left: 28px; -} - -.fxaSyncIllustration { - height: var(--panel-ui-sync-illustration-height); - list-style-image: url(chrome://browser/skin/fxa/sync-illustration.svg); -} - -.PanelUI-remotetabs-prefs-button > .toolbarbutton-text { - /* !important to override ".cui-widget-panel toolbarbutton > .toolbarbutton-text" above. */ - text-align: center !important; - text-shadow: none; -} - -#PanelUI-remotetabs[mainview] { /* panel anchored to toolbar button might be too skinny */ - min-width: 19em; -} - -/* Work around bug 1224412 - these boxes will cause scrollbars to appear when - the panel is anchored to a toolbar button. -*/ -#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, -#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-reauthsync, -#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-nodevicespane, -#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-tabsdisabledpane { - min-height: calc(var(--panel-ui-sync-illustration-height) + - 20px + /* margin of .PanelUI-remotetabs-prefs-button */ - 16px + /* padding of .PanelUI-remotetabs-prefs-button */ - 30px + /* margin of .PanelUI-remotetabs-instruction-label */ - 30px + 15px + /* padding of .PanelUI-remotetabs-instruction-box */ - 11em); -} - -#PanelUI-remotetabs-tabslist > label[itemtype="client"] { - color: GrayText; -} - -/* Collapse the non-active vboxes in the remotetabs deck to use only the - height the active box needs */ -#PanelUI-remotetabs-deck:not([selectedIndex="1"]) > #PanelUI-remotetabs-tabsdisabledpane, -#PanelUI-remotetabs-deck:not([selectedIndex="2"]) > #PanelUI-remotetabs-fetching, -#PanelUI-remotetabs-deck:not([selectedIndex="3"]) > #PanelUI-remotetabs-nodevicespane { - visibility: collapse; -} - -#PanelUI-remotetabs-main[devices-status="single"] > #PanelUI-remotetabs-buttons { - display: none; -} - -#PanelUI-fxa-icon[syncstatus="active"]:not([disabled]) { - list-style-image: url(chrome://browser/skin/syncProgress-horizontalbar.png); -} - -#PanelUI-footer-fxa[fxastatus="migrate-signup"] > #PanelUI-fxa-status > #PanelUI-fxa-label, -#PanelUI-footer-fxa[fxastatus="migrate-verify"] > #PanelUI-fxa-status > #PanelUI-fxa-label { - list-style-image: url(chrome://browser/skin/warning.svg); - -moz-image-region: auto; -} - #PanelUI-customize { list-style-image: url(chrome://browser/skin/menuPanel-customize.png); } @@ -780,46 +599,12 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { list-style-image: url(chrome://browser/skin/menuPanel-exit.png); } -#PanelUI-fxa-label, -#PanelUI-fxa-icon, #PanelUI-customize, #PanelUI-help, #PanelUI-quit { -moz-image-region: rect(0, 16px, 16px, 0); } -#PanelUI-footer-fxa[fxastatus="signedin"] > #PanelUI-fxa-status > #PanelUI-fxa-label > .toolbarbutton-icon, -#PanelUI-footer-fxa[fxastatus="error"][fxaprofileimage="set"] > #PanelUI-fxa-status > #PanelUI-fxa-label > .toolbarbutton-icon { - display: none; -} - -#PanelUI-footer-fxa[fxastatus="error"]:not([fxaprofileimage="set"]) > #PanelUI-fxa-status > #PanelUI-fxa-avatar { - display: none; -} - -#PanelUI-fxa-status[disabled], -#PanelUI-fxa-icon[disabled] { - pointer-events: none; -} - -#PanelUI-fxa-avatar { - width: 32px; - height: 32px; - border-radius: 50%; - background-repeat: no-repeat; - background-position: 0 0; - background-size: contain; - align-self: center; - margin: 0px 7px; - padding: 0px; - border: 0px none; - margin-inline-end: 0; -} - -#PanelUI-footer-fxa[fxaprofileimage="enabled"] > #PanelUI-fxa-status > #PanelUI-fxa-avatar { - list-style-image: url(chrome://browser/skin/fxa/default-avatar.svg); -} - #PanelUI-customize:hover, #PanelUI-help:not([disabled]):hover, #PanelUI-quit:not([disabled]):hover { @@ -837,16 +622,10 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { } #PanelUI-help[disabled], -#PanelUI-quit[disabled], -#PanelUI-fxa-icon[disabled], -#PanelUI-fxa-avatar[disabled], -#PanelUI-fxa-label[disabled] > .toolbarbutton-icon, -#PanelUI-fxa-status::after { +#PanelUI-quit[disabled] { opacity: 0.4; } -#PanelUI-fxa-status:not([disabled]):hover, -#PanelUI-fxa-icon:not([disabled]):hover, #PanelUI-help:not([disabled]):hover, #PanelUI-customize:hover, #PanelUI-quit:not([disabled]):hover { @@ -854,8 +633,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { background-color: var(--arrowpanel-dimmed); } -#PanelUI-fxa-status:not([disabled]):hover:active, -#PanelUI-fxa-icon:not([disabled]):hover:active, #PanelUI-help:not([disabled]):hover:active, #PanelUI-customize:hover:active, #PanelUI-quit:not([disabled]):hover:active { @@ -864,27 +641,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset; } -#PanelUI-fxa-status:not([disabled]):hover, -#PanelUI-fxa-status:not([disabled]):hover:active, -#PanelUI-fxa-icon:not([disabled]):hover, -#PanelUI-fxa-icon:not([disabled]):hover:active { - outline: none; -} - -#PanelUI-footer-fxa[fxastatus="error"] { - background-color: hsl(42,94%,88%); - border-top: 1px solid hsl(42,94%,70%); -} - -#PanelUI-footer-fxa[fxastatus="error"] > #PanelUI-fxa-status:hover { - background-color: hsl(42,94%,85%); -} - -#PanelUI-footer-fxa[fxastatus="error"] > #PanelUI-fxa-status:hover:active { - background-color: hsl(42,94%,82%); - box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset; -} - #PanelUI-update-status { color: black; } @@ -1150,19 +906,16 @@ menuitem.panel-subview-footer@menuStateActive@, color: GrayText; } -#PanelUI-remotetabs-tabslist > toolbarbutton, #PanelUI-historyItems > toolbarbutton { list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png"); } @media (min-resolution: 1.1dppx) { - #PanelUI-remotetabs-tabslist > toolbarbutton, #PanelUI-historyItems > toolbarbutton { list-style-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png"); } } -#PanelUI-remotetabs-tabslist > toolbarbutton > .toolbarbutton-icon, #PanelUI-recentlyClosedWindows > toolbarbutton > .toolbarbutton-icon, #PanelUI-recentlyClosedTabs > toolbarbutton > .toolbarbutton-icon, #PanelUI-historyItems > toolbarbutton > .toolbarbutton-icon { @@ -1616,15 +1369,6 @@ menuitem[checked="true"].subviewbutton > .menu-iconic-left { list-style-image: url(chrome://branding/content/icon32.png); } - #PanelUI-fxa-label, - #PanelUI-fxa-icon { - list-style-image: url(chrome://browser/skin/sync-horizontalbar@2x.png); - } - - #PanelUI-fxa-icon[syncstatus="active"]:not([disabled]) { - list-style-image: url(chrome://browser/skin/syncProgress-horizontalbar@2x.png); - } - #PanelUI-customize { list-style-image: url(chrome://browser/skin/menuPanel-customize@2x.png); } @@ -1641,8 +1385,6 @@ menuitem[checked="true"].subviewbutton > .menu-iconic-left { list-style-image: url(chrome://browser/skin/menuPanel-exit@2x.png); } - #PanelUI-fxa-label, - #PanelUI-fxa-icon, #PanelUI-customize, #PanelUI-help, #PanelUI-quit { @@ -1650,8 +1392,6 @@ menuitem[checked="true"].subviewbutton > .menu-iconic-left { } #PanelUI-update-status > .toolbarbutton-icon, - #PanelUI-fxa-label > .toolbarbutton-icon, - #PanelUI-fxa-icon > .toolbarbutton-icon, #PanelUI-customize > .toolbarbutton-icon, #PanelUI-help > .toolbarbutton-icon, #PanelUI-quit > .toolbarbutton-icon { diff --git a/application/basilisk/themes/shared/menupanel.inc.css b/application/basilisk/themes/shared/menupanel.inc.css index 266e1c83e..2feb941a2 100644 --- a/application/basilisk/themes/shared/menupanel.inc.css +++ b/application/basilisk/themes/shared/menupanel.inc.css @@ -48,11 +48,32 @@ toolbarpaletteitem[place="palette"] > #save-page-button { -moz-image-region: rect(0px, 352px, 32px, 320px); } +/* Start Sync Buttons */ + #sync-button[cui-areatype="menu-panel"], toolbarpaletteitem[place="palette"] > #sync-button { + -moz-image-region: rect(0px, 384px, 32px, 352px) +} + +#sync-button[cui-areatype="menu-panel"][status="active"] { + list-style-image: url("chrome://browser/skin/syncProgress-menuPanel.png"); + -moz-image-region: rect(0, 32px, 32px, 0); +} + +@media (min-resolution: 1.1dppx) { + #sync-button[cui-areatype="menu-panel"][status="active"] { + list-style-image: url("chrome://browser/skin/syncProgress-menuPanel@2x.png"); + -moz-image-region: rect(0, 64px, 64px, 0); + } +} + +#sync-tabs-button[cui-areatype="menu-panel"], +toolbarpaletteitem[place="palette"] > #sync-tabs-button { -moz-image-region: rect(0px, 1024px, 32px, 992px); } +/* End Sync Buttons */ + #containers-panelmenu[cui-areatype="menu-panel"], toolbarpaletteitem[place="palette"] > #containers-panelmenu { -moz-image-region: rect(0px, 1056px, 32px, 1024px); diff --git a/application/basilisk/themes/shared/syncedtabs/sidebar.inc.css b/application/basilisk/themes/shared/syncedtabs/sidebar.inc.css deleted file mode 100644 index 4e76a7fc5..000000000 --- a/application/basilisk/themes/shared/syncedtabs/sidebar.inc.css +++ /dev/null @@ -1,234 +0,0 @@ -% 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/. - -/* These styles are intended to mimic XUL trees and the XUL search box. */ - -html { - height: 100%; -} - -body { - height: 100%; - margin: 0; - font: message-box; - color: #333333; - -moz-user-select: none; -} - -/* The content-container holds the non-scrollable header and the scrollable - content area. -*/ -.content-container { - display: flex; - flex-flow: column; - height: 100%; -} - -/* The content header is not scrollable */ -.content-header { - flex: 0 1 auto; -} - -/* The main content area is scrollable and fills the rest of the area */ -.content-scrollable { - flex: 1 1 auto; - overflow: auto; -} - -.emptyListInfo { - cursor: default; - padding: 3em 1em; - text-align: center; -} - -.list, -.item-tabs-list { - display: flex; - flex-flow: column; - flex-grow: 1; -} - -.item.client { - opacity: 1; - max-height: unset; - display: unset; -} - -.item.client.closed .item-tabs-list { - display: none; -} - -.item { - display: inline-block; - opacity: 1; - flex: 1; - min-width: 0; - white-space: nowrap; - overflow: hidden; - outline: none; - color: -moz-FieldText; -} - -.item.selected > .item-title-container { - background-color: -moz-cellhighlight; - color: -moz-cellhighlighttext; - font-weight: bold; -} - -.item.selected:focus > .item-title-container { - background-color: Highlight; - color: HighlightText; -} - -.client .item.tab > .item-title-container { - padding-inline-start: 35px; -} - -.item.tab > .item-title-container { - padding-inline-start: 20px; -} - -.item.client.device-image-desktop > .item-title-container > .item-icon-container { - background-image: url("chrome://browser/skin/sync-desktopIcon.svg#icon"); -} - -.item.client.device-image-desktop.selected:focus > .item-title-container > .item-icon-container { - background-image: url("chrome://browser/skin/sync-desktopIcon.svg#icon-inverted"); -} - -.item.client.device-image-mobile > .item-title-container > .item-icon-container { - background-image: url("chrome://browser/skin/sync-mobileIcon.svg#icon"); -} - -.item.client.device-image-mobile.selected:focus > .item-title-container > .item-icon-container { - background-image: url("chrome://browser/skin/sync-mobileIcon.svg#icon-inverted"); -} - -.item.tab > .item-title-container > .item-icon-container { - background-image: url("chrome://mozapps/skin/places/defaultFavicon.png"); -} - -@media (min-resolution: 1.1dppx) { -.item.tab > .item-title-container > .item-icon-container { - background-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png"); - } -} - -.item-icon-container { - min-width: 16px; - max-width: 16px; - min-height: 16px; - max-height: 16px; - margin-right: 5px; - margin-left: 5px; - background-size: 16px 16px; - background-size: contain; - background-repeat: no-repeat; - background-position: center; -} - -.item-title-container { - display: flex; - flex-flow: row; - overflow: hidden; - flex-grow: 1; - padding: 1px 0px 1px 0px; -} - -.item-title { - flex-grow: 1; - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; - line-height: 1.3; - cursor: default; -} - -.item[hidden] { - opacity: 0; - max-height: 0; - transition: opacity 150ms ease-in-out, max-height 150ms ease-in-out 150ms; -} - -.item.empty .item-title-container { - color: #aeaeae; -} - -.client .item.empty > .item-title-container { - padding-inline-start: 35px; -} - -.text-input-box { - display: flex; - flex-flow: row nowrap; -} - -.textbox-input-box { - display: flex; - flex-direction: row; -} - -.tabsFilter { - flex: 1; - /* min-width of anything to override the implicit "-moz-min-content" value. - 0px is safe as the sidebar itself has a constrained size meaning we will - never actually hit this minimum - */ - min-width: 0px; -} - -.sync-state > p { - padding-inline-end: 10px; - padding-inline-start: 10px; - color: #888; -} - -.text-link { - color: rgb(0, 149, 221); - cursor: pointer; -} - -.text-link:hover { - text-decoration: underline; -} - -.text-link, -.text-link:focus { - margin: 0px; - padding: 0px; - border: 0px; -} - -.deck .sync-state { - display: none; - opacity: 0; - transition: opacity 1.5s; - border-top: 1px solid #bdbdbd; -} - -.deck .sync-state.tabs-container { - border-top: 0px; -} - -.deck .sync-state.selected { - display: unset; - opacity: 100; -} - -.sidebar-search-container.tabs-container:not(.selected) { - display: none; -} - -.textbox-search-clear:not([disabled]) { - cursor: default; -} - -.textbox-search-icons .textbox-search-clear, -.filtered .textbox-search-icons .textbox-search-icon { - display: none; -} - -.filtered .textbox-search-icons .textbox-search-clear { - display: block; -} diff --git a/application/basilisk/themes/shared/toolbarbuttons.inc.css b/application/basilisk/themes/shared/toolbarbuttons.inc.css index c043b8192..2f74b8361 100644 --- a/application/basilisk/themes/shared/toolbarbuttons.inc.css +++ b/application/basilisk/themes/shared/toolbarbuttons.inc.css @@ -52,10 +52,35 @@ toolbar[brighttext] #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarke -moz-image-region: rect(0, 252px, 18px, 234px); } +/* Start Sync Buttons */ + #sync-button[cui-areatype="toolbar"] { + -moz-image-region: rect(0, 270px, 18px, 252px); +} + +#sync-button[cui-areatype="toolbar"][status="active"] { + list-style-image: url("chrome://browser/skin/syncProgress-toolbar.png"); + -moz-image-region: rect(0, 18px, 18px, 0); +} + +@media (-moz-os-version: windows-win7) { + #sync-button[cui-areatype="toolbar"][status="active"] { + list-style-image: url("chrome://browser/skin/syncProgress-toolbar-win7.png"); + -moz-image-region: rect(0, 18px, 18px, 0); + } +} + +toolbar[brighttext] #sync-button[cui-areatype="toolbar"][status="active"] { + list-style-image: url("chrome://browser/skin/syncProgress-toolbar-inverted.png"); + -moz-image-region: rect(0, 18px, 18px, 0); +} + +#sync-tabs-button[cui-areatype="toolbar"] { -moz-image-region: rect(0, 792px, 18px, 774px); } +/* End Sync Buttons */ + #containers-panelmenu[cui-areatype="toolbar"] { -moz-image-region: rect(0, 810px, 18px, 792px); } @@ -226,10 +251,35 @@ toolbar[brighttext] #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarke -moz-image-region: rect(0, 504px, 36px, 468px); } + /* Start Sync Buttons */ + #sync-button[cui-areatype="toolbar"] { + -moz-image-region: rect(0, 540px, 36px, 504px); + } + + #sync-button[cui-areatype="toolbar"][status="active"] { + list-style-image: url("chrome://browser/skin/syncProgress-toolbar@2x.png"); + -moz-image-region: rect(0, 36px, 36px, 0); + } + + @media (-moz-os-version: windows-win7) { + #sync-button[cui-areatype="toolbar"][status="active"] { + list-style-image: url("chrome://browser/skin/syncProgress-toolbar-win7@2x.png"); + -moz-image-region: rect(0, 36px, 36px, 0); + } + } + + toolbar[brighttext] #sync-button[cui-areatype="toolbar"][status="active"] { + list-style-image: url("chrome://browser/skin/syncProgress-toolbar-inverted@2x.png"); + -moz-image-region: rect(0, 36px, 36px, 0); + } + + #sync-tabs-button[cui-areatype="toolbar"] { -moz-image-region: rect(0, 1584px, 36px, 1548px); } + /* End Sync Buttons */ + #containers-panelmenu[cui-areatype="toolbar"] { -moz-image-region: rect(0, 1620px, 36px, 1584px); } diff --git a/application/basilisk/themes/windows/jar.mn b/application/basilisk/themes/windows/jar.mn index e8db7eed2..09004f57d 100644 --- a/application/basilisk/themes/windows/jar.mn +++ b/application/basilisk/themes/windows/jar.mn @@ -8,7 +8,6 @@ browser.jar: skin/classic/browser/sanitizeDialog.css skin/classic/browser/aboutSessionRestore-window-icon.png skin/classic/browser/aboutSyncTabs.css -* skin/classic/browser/syncedtabs/sidebar.css (syncedtabs/sidebar.css) skin/classic/browser/actionicon-tab.png skin/classic/browser/actionicon-tab@2x.png skin/classic/browser/actionicon-tab-win7.png @@ -167,6 +166,7 @@ browser.jar: skin/classic/browser/syncProgress-toolbar-inverted@2x.png skin/classic/browser/syncProgress-toolbar-win7.png skin/classic/browser/syncProgress-toolbar-win7@2x.png + skin/classic/browser/syncProgress.css [extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar: % override chrome://browser/skin/page-livemarks.png chrome://browser/skin/feeds/feedIcon16.png diff --git a/application/basilisk/themes/windows/syncProgress.css b/application/basilisk/themes/windows/syncProgress.css new file mode 100644 index 000000000..d7aa59976 --- /dev/null +++ b/application/basilisk/themes/windows/syncProgress.css @@ -0,0 +1,46 @@ +/* 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/. */ +@import url(chrome://global/skin/inContentUI.css); + +:root { + height: 100%; + width: 100%; + padding: 0; +} + +body { + margin: 0; + padding: 0 2em; +} + +#floatingBox { + margin: 4em auto; + max-width: 40em; + min-width: 23em; + padding: 1em 1.5em; + position: relative; + text-align: center; +} + +#successLogo { + margin: 1em 2em; +} + +#loadingText { + margin: 2em 6em; +} + +#progressBar { + margin: 2em 10em; +} + +#uploadProgressBar{ + width: 100%; +} + +#bottomRow { + margin-top: 2em; + padding: 0; + text-align: end; +} diff --git a/application/basilisk/themes/windows/syncedtabs/sidebar.css b/application/basilisk/themes/windows/syncedtabs/sidebar.css deleted file mode 100644 index 6473206bc..000000000 --- a/application/basilisk/themes/windows/syncedtabs/sidebar.css +++ /dev/null @@ -1,132 +0,0 @@ -/* 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/. */ - -%include ../../shared/syncedtabs/sidebar.inc.css - -/* These styles are intended to mimic XUL trees and the XUL search box. */ - -html { - background-color: #EEF3FA; -} - -.item { - padding-inline-end: 0; -} - -.item-title { - margin: 1px 0 0; -} - -.item-title { - margin-inline-end: 6px; -} - -.search-box { - -moz-appearance: textfield; - cursor: text; - margin: 2px 4px; - padding: 2px 2px 3px; - padding-inline-start: 4px; - color: -moz-FieldText; -} - -.textbox-search-icon { - width: 16px; - height: 16px; - background-image: url(chrome://global/skin/icons/Search-glass.png); - background-repeat: no-repeat; - display: block; -} - -.textbox-search-icon:-moz-locale-dir(rtl) { - transform: scaleX(-1); -} - -.textbox-search-icon[searchbutton]:not([disabled]) { - cursor: pointer; -} - -.textbox-search-clear { - width: 16px; - height: 16px; - background-image: url(chrome://global/skin/icons/Search-close.png); - background-repeat: no-repeat; -} - -.textbox-search-clear:not([disabled]) { - cursor: default; -} - -.textbox-search-icon:not([disabled]) { - cursor: text; -} - -.textbox-search-clear:not([disabled]):hover , -.textbox-search-icon:not([disabled]):hover { - background-position: -16px 0; -} - -.textbox-search-clear:not([disabled]):hover:active , -.textbox-search-icon:not([disabled]):hover:active { - background-position: -32px 0; -} - -.client .item.tab > .item-title-container { - padding-inline-start: 26px; -} -.item.tab > .item-title-container { - padding-inline-start: 14px; -} - -.item-icon-container { - min-width: 16px; - max-width: 16px; - min-height: 16px; - max-height: 16px; - margin-right: 5px; - background-size: 16px 16px; - background-repeat: no-repeat; - background-position: center; -} - -.item-twisty-container { - background-size: contain; - background-repeat: no-repeat; - background-position: center; - padding-top: 5px; - min-width: 9px; /* The image's width is 9 pixels */ - height: 9px; -} - -.item.client .item-twisty-container { - background-image: url("chrome://global/skin/tree/twisty.svg#open"); -} - -.item.client.closed .item-twisty-container { - background-image: url("chrome://global/skin/tree/twisty.svg#clsd"); -} - -.item.client .item-twisty-container:hover { - background-image: url("chrome://global/skin/tree/twisty.svg#open-hover"); -} - -.item.client.closed .item-twisty-container:hover { - background-image: url("chrome://global/skin/tree/twisty.svg#clsd-hover"); -} - -.item.client .item-twisty-container:dir(rtl) { - background-image: url("chrome://global/skin/tree/twisty.svg#open-rtl"); -} - -.item.client.closed .item-twisty-container:dir(rtl) { - background-image: url("chrome://global/skin/tree/twisty.svg#clsd-rtl"); -} - -.item.client .item-twisty-container:hover:dir(rtl) { - background-image: url("chrome://global/skin/tree/twisty.svg#open-hover-rtl"); -} - -.item.client.closed .item-twisty-container:hover:dir(rtl) { - background-image: url("chrome://global/skin/tree/twisty.svg#clsd-hover-rtl"); -} |