browser/base/content/browser-fxaccounts.js

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

michael@0 1 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 4
michael@0 5 XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () {
michael@0 6 return Cu.import("resource://gre/modules/FxAccountsCommon.js", {});
michael@0 7 });
michael@0 8
michael@0 9 const PREF_SYNC_START_DOORHANGER = "services.sync.ui.showSyncStartDoorhanger";
michael@0 10 const DOORHANGER_ACTIVATE_DELAY_MS = 5000;
michael@0 11
michael@0 12 let gFxAccounts = {
michael@0 13
michael@0 14 _initialized: false,
michael@0 15 _inCustomizationMode: false,
michael@0 16
michael@0 17 get weave() {
michael@0 18 delete this.weave;
michael@0 19 return this.weave = Cc["@mozilla.org/weave/service;1"]
michael@0 20 .getService(Ci.nsISupports)
michael@0 21 .wrappedJSObject;
michael@0 22 },
michael@0 23
michael@0 24 get topics() {
michael@0 25 // Do all this dance to lazy-load FxAccountsCommon.
michael@0 26 delete this.topics;
michael@0 27 return this.topics = [
michael@0 28 "weave:service:ready",
michael@0 29 "weave:service:sync:start",
michael@0 30 "weave:service:login:error",
michael@0 31 "weave:service:setup-complete",
michael@0 32 FxAccountsCommon.ONVERIFIED_NOTIFICATION,
michael@0 33 FxAccountsCommon.ONLOGOUT_NOTIFICATION
michael@0 34 ];
michael@0 35 },
michael@0 36
michael@0 37 get button() {
michael@0 38 delete this.button;
michael@0 39 return this.button = document.getElementById("PanelUI-fxa-status");
michael@0 40 },
michael@0 41
michael@0 42 get loginFailed() {
michael@0 43 // Referencing Weave.Service will implicitly initialize sync, and we don't
michael@0 44 // want to force that - so first check if it is ready.
michael@0 45 let service = Cc["@mozilla.org/weave/service;1"]
michael@0 46 .getService(Components.interfaces.nsISupports)
michael@0 47 .wrappedJSObject;
michael@0 48 if (!service.ready) {
michael@0 49 return false;
michael@0 50 }
michael@0 51 // LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in".
michael@0 52 // All other login failures are assumed to be transient and should go
michael@0 53 // away by themselves, so aren't reflected here.
michael@0 54 return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
michael@0 55 },
michael@0 56
michael@0 57 get isActiveWindow() {
michael@0 58 let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
michael@0 59 return fm.activeWindow == window;
michael@0 60 },
michael@0 61
michael@0 62 init: function () {
michael@0 63 // Bail out if we're already initialized and for pop-up windows.
michael@0 64 if (this._initialized || !window.toolbar.visible) {
michael@0 65 return;
michael@0 66 }
michael@0 67
michael@0 68 for (let topic of this.topics) {
michael@0 69 Services.obs.addObserver(this, topic, false);
michael@0 70 }
michael@0 71
michael@0 72 addEventListener("activate", this);
michael@0 73 gNavToolbox.addEventListener("customizationstarting", this);
michael@0 74 gNavToolbox.addEventListener("customizationending", this);
michael@0 75
michael@0 76 this._initialized = true;
michael@0 77
michael@0 78 this.updateUI();
michael@0 79 },
michael@0 80
michael@0 81 uninit: function () {
michael@0 82 if (!this._initialized) {
michael@0 83 return;
michael@0 84 }
michael@0 85
michael@0 86 for (let topic of this.topics) {
michael@0 87 Services.obs.removeObserver(this, topic);
michael@0 88 }
michael@0 89
michael@0 90 this._initialized = false;
michael@0 91 },
michael@0 92
michael@0 93 observe: function (subject, topic) {
michael@0 94 switch (topic) {
michael@0 95 case FxAccountsCommon.ONVERIFIED_NOTIFICATION:
michael@0 96 Services.prefs.setBoolPref(PREF_SYNC_START_DOORHANGER, true);
michael@0 97 break;
michael@0 98 case "weave:service:sync:start":
michael@0 99 this.onSyncStart();
michael@0 100 break;
michael@0 101 default:
michael@0 102 this.updateUI();
michael@0 103 break;
michael@0 104 }
michael@0 105 },
michael@0 106
michael@0 107 onSyncStart: function () {
michael@0 108 if (!this.isActiveWindow) {
michael@0 109 return;
michael@0 110 }
michael@0 111
michael@0 112 let showDoorhanger = false;
michael@0 113
michael@0 114 try {
michael@0 115 showDoorhanger = Services.prefs.getBoolPref(PREF_SYNC_START_DOORHANGER);
michael@0 116 } catch (e) { /* The pref might not exist. */ }
michael@0 117
michael@0 118 if (showDoorhanger) {
michael@0 119 Services.prefs.clearUserPref(PREF_SYNC_START_DOORHANGER);
michael@0 120 this.showSyncStartedDoorhanger();
michael@0 121 }
michael@0 122 },
michael@0 123
michael@0 124 handleEvent: function (event) {
michael@0 125 if (event.type == "activate") {
michael@0 126 // Our window might have been in the background while we received the
michael@0 127 // sync:start notification. If still needed, show the doorhanger after
michael@0 128 // a short delay. Without this delay the doorhanger would not show up
michael@0 129 // or with a too small delay show up while we're still animating the
michael@0 130 // window.
michael@0 131 setTimeout(() => this.onSyncStart(), DOORHANGER_ACTIVATE_DELAY_MS);
michael@0 132 } else {
michael@0 133 this._inCustomizationMode = event.type == "customizationstarting";
michael@0 134 this.updateUI();
michael@0 135 }
michael@0 136 },
michael@0 137
michael@0 138 showDoorhanger: function (id) {
michael@0 139 let panel = document.getElementById(id);
michael@0 140 let anchor = document.getElementById("PanelUI-menu-button");
michael@0 141
michael@0 142 let iconAnchor =
michael@0 143 document.getAnonymousElementByAttribute(anchor, "class",
michael@0 144 "toolbarbutton-icon");
michael@0 145
michael@0 146 panel.hidden = false;
michael@0 147 panel.openPopup(iconAnchor || anchor, "bottomcenter topright");
michael@0 148 },
michael@0 149
michael@0 150 showSyncStartedDoorhanger: function () {
michael@0 151 this.showDoorhanger("sync-start-panel");
michael@0 152 },
michael@0 153
michael@0 154 showSyncFailedDoorhanger: function () {
michael@0 155 this.showDoorhanger("sync-error-panel");
michael@0 156 },
michael@0 157
michael@0 158 updateUI: function () {
michael@0 159 // Bail out if FxA is disabled.
michael@0 160 if (!this.weave.fxAccountsEnabled) {
michael@0 161 return;
michael@0 162 }
michael@0 163
michael@0 164 // FxA is enabled, show the widget.
michael@0 165 this.button.removeAttribute("hidden");
michael@0 166
michael@0 167 // Make sure the button is disabled in customization mode.
michael@0 168 if (this._inCustomizationMode) {
michael@0 169 this.button.setAttribute("disabled", "true");
michael@0 170 } else {
michael@0 171 this.button.removeAttribute("disabled");
michael@0 172 }
michael@0 173
michael@0 174 let defaultLabel = this.button.getAttribute("defaultlabel");
michael@0 175 let errorLabel = this.button.getAttribute("errorlabel");
michael@0 176
michael@0 177 // If the user is signed into their Firefox account and we are not
michael@0 178 // currently in customization mode, show their email address.
michael@0 179 let doUpdate = userData => {
michael@0 180 // Reset the button to its original state.
michael@0 181 this.button.setAttribute("label", defaultLabel);
michael@0 182 this.button.removeAttribute("tooltiptext");
michael@0 183 this.button.removeAttribute("signedin");
michael@0 184 this.button.removeAttribute("failed");
michael@0 185
michael@0 186 if (!this._inCustomizationMode) {
michael@0 187 if (this.loginFailed) {
michael@0 188 this.button.setAttribute("failed", "true");
michael@0 189 this.button.setAttribute("label", errorLabel);
michael@0 190 } else if (userData) {
michael@0 191 this.button.setAttribute("signedin", "true");
michael@0 192 this.button.setAttribute("label", userData.email);
michael@0 193 this.button.setAttribute("tooltiptext", userData.email);
michael@0 194 }
michael@0 195 }
michael@0 196 }
michael@0 197 fxAccounts.getSignedInUser().then(userData => {
michael@0 198 doUpdate(userData);
michael@0 199 }).then(null, error => {
michael@0 200 // This is most likely in tests, were we quickly log users in and out.
michael@0 201 // The most likely scenario is a user logged out, so reflect that.
michael@0 202 // Bug 995134 calls for better errors so we could retry if we were
michael@0 203 // sure this was the failure reason.
michael@0 204 doUpdate(null);
michael@0 205 });
michael@0 206 },
michael@0 207
michael@0 208 onMenuPanelCommand: function (event) {
michael@0 209 let button = event.originalTarget;
michael@0 210
michael@0 211 if (button.hasAttribute("signedin")) {
michael@0 212 this.openPreferences();
michael@0 213 } else if (button.hasAttribute("failed")) {
michael@0 214 this.openSignInAgainPage();
michael@0 215 } else {
michael@0 216 this.openAccountsPage();
michael@0 217 }
michael@0 218
michael@0 219 PanelUI.hide();
michael@0 220 },
michael@0 221
michael@0 222 openPreferences: function () {
michael@0 223 openPreferences("paneSync");
michael@0 224 },
michael@0 225
michael@0 226 openAccountsPage: function () {
michael@0 227 switchToTabHavingURI("about:accounts", true);
michael@0 228 },
michael@0 229
michael@0 230 openSignInAgainPage: function () {
michael@0 231 switchToTabHavingURI("about:accounts?action=reauth", true);
michael@0 232 }
michael@0 233 };

mercurial