browser/base/content/browser-fxaccounts.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/base/content/browser-fxaccounts.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,233 @@
     1.4 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.7 +
     1.8 +XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () {
     1.9 +  return Cu.import("resource://gre/modules/FxAccountsCommon.js", {});
    1.10 +});
    1.11 +
    1.12 +const PREF_SYNC_START_DOORHANGER = "services.sync.ui.showSyncStartDoorhanger";
    1.13 +const DOORHANGER_ACTIVATE_DELAY_MS = 5000;
    1.14 +
    1.15 +let gFxAccounts = {
    1.16 +
    1.17 +  _initialized: false,
    1.18 +  _inCustomizationMode: false,
    1.19 +
    1.20 +  get weave() {
    1.21 +    delete this.weave;
    1.22 +    return this.weave = Cc["@mozilla.org/weave/service;1"]
    1.23 +                          .getService(Ci.nsISupports)
    1.24 +                          .wrappedJSObject;
    1.25 +  },
    1.26 +
    1.27 +  get topics() {
    1.28 +    // Do all this dance to lazy-load FxAccountsCommon.
    1.29 +    delete this.topics;
    1.30 +    return this.topics = [
    1.31 +      "weave:service:ready",
    1.32 +      "weave:service:sync:start",
    1.33 +      "weave:service:login:error",
    1.34 +      "weave:service:setup-complete",
    1.35 +      FxAccountsCommon.ONVERIFIED_NOTIFICATION,
    1.36 +      FxAccountsCommon.ONLOGOUT_NOTIFICATION
    1.37 +    ];
    1.38 +  },
    1.39 +
    1.40 +  get button() {
    1.41 +    delete this.button;
    1.42 +    return this.button = document.getElementById("PanelUI-fxa-status");
    1.43 +  },
    1.44 +
    1.45 +  get loginFailed() {
    1.46 +    // Referencing Weave.Service will implicitly initialize sync, and we don't
    1.47 +    // want to force that - so first check if it is ready.
    1.48 +    let service = Cc["@mozilla.org/weave/service;1"]
    1.49 +                  .getService(Components.interfaces.nsISupports)
    1.50 +                  .wrappedJSObject;
    1.51 +    if (!service.ready) {
    1.52 +      return false;
    1.53 +    }
    1.54 +    // LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in".
    1.55 +    // All other login failures are assumed to be transient and should go
    1.56 +    // away by themselves, so aren't reflected here.
    1.57 +    return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
    1.58 +  },
    1.59 +
    1.60 +  get isActiveWindow() {
    1.61 +    let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
    1.62 +    return fm.activeWindow == window;
    1.63 +  },
    1.64 +
    1.65 +  init: function () {
    1.66 +    // Bail out if we're already initialized and for pop-up windows.
    1.67 +    if (this._initialized || !window.toolbar.visible) {
    1.68 +      return;
    1.69 +    }
    1.70 +
    1.71 +    for (let topic of this.topics) {
    1.72 +      Services.obs.addObserver(this, topic, false);
    1.73 +    }
    1.74 +
    1.75 +    addEventListener("activate", this);
    1.76 +    gNavToolbox.addEventListener("customizationstarting", this);
    1.77 +    gNavToolbox.addEventListener("customizationending", this);
    1.78 +
    1.79 +    this._initialized = true;
    1.80 +
    1.81 +    this.updateUI();
    1.82 +  },
    1.83 +
    1.84 +  uninit: function () {
    1.85 +    if (!this._initialized) {
    1.86 +      return;
    1.87 +    }
    1.88 +
    1.89 +    for (let topic of this.topics) {
    1.90 +      Services.obs.removeObserver(this, topic);
    1.91 +    }
    1.92 +
    1.93 +    this._initialized = false;
    1.94 +  },
    1.95 +
    1.96 +  observe: function (subject, topic) {
    1.97 +    switch (topic) {
    1.98 +      case FxAccountsCommon.ONVERIFIED_NOTIFICATION:
    1.99 +        Services.prefs.setBoolPref(PREF_SYNC_START_DOORHANGER, true);
   1.100 +        break;
   1.101 +      case "weave:service:sync:start":
   1.102 +        this.onSyncStart();
   1.103 +        break;
   1.104 +      default:
   1.105 +        this.updateUI();
   1.106 +        break;
   1.107 +    }
   1.108 +  },
   1.109 +
   1.110 +  onSyncStart: function () {
   1.111 +    if (!this.isActiveWindow) {
   1.112 +      return;
   1.113 +    }
   1.114 +
   1.115 +    let showDoorhanger = false;
   1.116 +
   1.117 +    try {
   1.118 +      showDoorhanger = Services.prefs.getBoolPref(PREF_SYNC_START_DOORHANGER);
   1.119 +    } catch (e) { /* The pref might not exist. */ }
   1.120 +
   1.121 +    if (showDoorhanger) {
   1.122 +      Services.prefs.clearUserPref(PREF_SYNC_START_DOORHANGER);
   1.123 +      this.showSyncStartedDoorhanger();
   1.124 +    }
   1.125 +  },
   1.126 +
   1.127 +  handleEvent: function (event) {
   1.128 +    if (event.type == "activate") {
   1.129 +      // Our window might have been in the background while we received the
   1.130 +      // sync:start notification. If still needed, show the doorhanger after
   1.131 +      // a short delay. Without this delay the doorhanger would not show up
   1.132 +      // or with a too small delay show up while we're still animating the
   1.133 +      // window.
   1.134 +      setTimeout(() => this.onSyncStart(), DOORHANGER_ACTIVATE_DELAY_MS);
   1.135 +    } else {
   1.136 +      this._inCustomizationMode = event.type == "customizationstarting";
   1.137 +      this.updateUI();
   1.138 +    }
   1.139 +  },
   1.140 +
   1.141 +  showDoorhanger: function (id) {
   1.142 +    let panel = document.getElementById(id);
   1.143 +    let anchor = document.getElementById("PanelUI-menu-button");
   1.144 +
   1.145 +    let iconAnchor =
   1.146 +      document.getAnonymousElementByAttribute(anchor, "class",
   1.147 +                                              "toolbarbutton-icon");
   1.148 +
   1.149 +    panel.hidden = false;
   1.150 +    panel.openPopup(iconAnchor || anchor, "bottomcenter topright");
   1.151 +  },
   1.152 +
   1.153 +  showSyncStartedDoorhanger: function () {
   1.154 +    this.showDoorhanger("sync-start-panel");
   1.155 +  },
   1.156 +
   1.157 +  showSyncFailedDoorhanger: function () {
   1.158 +    this.showDoorhanger("sync-error-panel");
   1.159 +  },
   1.160 +
   1.161 +  updateUI: function () {
   1.162 +    // Bail out if FxA is disabled.
   1.163 +    if (!this.weave.fxAccountsEnabled) {
   1.164 +      return;
   1.165 +    }
   1.166 +
   1.167 +    // FxA is enabled, show the widget.
   1.168 +    this.button.removeAttribute("hidden");
   1.169 +
   1.170 +    // Make sure the button is disabled in customization mode.
   1.171 +    if (this._inCustomizationMode) {
   1.172 +      this.button.setAttribute("disabled", "true");
   1.173 +    } else {
   1.174 +      this.button.removeAttribute("disabled");
   1.175 +    }
   1.176 +
   1.177 +    let defaultLabel = this.button.getAttribute("defaultlabel");
   1.178 +    let errorLabel = this.button.getAttribute("errorlabel");
   1.179 +
   1.180 +    // If the user is signed into their Firefox account and we are not
   1.181 +    // currently in customization mode, show their email address.
   1.182 +    let doUpdate = userData => {
   1.183 +      // Reset the button to its original state.
   1.184 +      this.button.setAttribute("label", defaultLabel);
   1.185 +      this.button.removeAttribute("tooltiptext");
   1.186 +      this.button.removeAttribute("signedin");
   1.187 +      this.button.removeAttribute("failed");
   1.188 +
   1.189 +      if (!this._inCustomizationMode) {
   1.190 +        if (this.loginFailed) {
   1.191 +          this.button.setAttribute("failed", "true");
   1.192 +          this.button.setAttribute("label", errorLabel);
   1.193 +        } else if (userData) {
   1.194 +          this.button.setAttribute("signedin", "true");
   1.195 +          this.button.setAttribute("label", userData.email);
   1.196 +          this.button.setAttribute("tooltiptext", userData.email);
   1.197 +        }
   1.198 +      }
   1.199 +    }
   1.200 +    fxAccounts.getSignedInUser().then(userData => {
   1.201 +      doUpdate(userData);
   1.202 +    }).then(null, error => {
   1.203 +      // This is most likely in tests, were we quickly log users in and out.
   1.204 +      // The most likely scenario is a user logged out, so reflect that.
   1.205 +      // Bug 995134 calls for better errors so we could retry if we were
   1.206 +      // sure this was the failure reason.
   1.207 +      doUpdate(null);
   1.208 +    });
   1.209 +  },
   1.210 +
   1.211 +  onMenuPanelCommand: function (event) {
   1.212 +    let button = event.originalTarget;
   1.213 +
   1.214 +    if (button.hasAttribute("signedin")) {
   1.215 +      this.openPreferences();
   1.216 +    } else if (button.hasAttribute("failed")) {
   1.217 +      this.openSignInAgainPage();
   1.218 +    } else {
   1.219 +      this.openAccountsPage();
   1.220 +    }
   1.221 +
   1.222 +    PanelUI.hide();
   1.223 +  },
   1.224 +
   1.225 +  openPreferences: function () {
   1.226 +    openPreferences("paneSync");
   1.227 +  },
   1.228 +
   1.229 +  openAccountsPage: function () {
   1.230 +    switchToTabHavingURI("about:accounts", true);
   1.231 +  },
   1.232 +
   1.233 +  openSignInAgainPage: function () {
   1.234 +    switchToTabHavingURI("about:accounts?action=reauth", true);
   1.235 +  }
   1.236 +};

mercurial