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