browser/base/content/browser-syncui.js

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

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 // gSyncUI handles updating the tools menu and displaying notifications.
michael@0 6 let gSyncUI = {
michael@0 7 DEFAULT_EOL_URL: "https://www.mozilla.org/firefox/?utm_source=synceol",
michael@0 8
michael@0 9 _obs: ["weave:service:sync:start",
michael@0 10 "weave:service:quota:remaining",
michael@0 11 "weave:service:setup-complete",
michael@0 12 "weave:service:login:start",
michael@0 13 "weave:service:login:finish",
michael@0 14 "weave:service:logout:finish",
michael@0 15 "weave:service:start-over",
michael@0 16 "weave:service:start-over:finish",
michael@0 17 "weave:ui:login:error",
michael@0 18 "weave:ui:sync:error",
michael@0 19 "weave:ui:sync:finish",
michael@0 20 "weave:ui:clear-error",
michael@0 21 "weave:eol",
michael@0 22 ],
michael@0 23
michael@0 24 _unloaded: false,
michael@0 25
michael@0 26 init: function () {
michael@0 27 Cu.import("resource://services-common/stringbundle.js");
michael@0 28
michael@0 29 // Proceed to set up the UI if Sync has already started up.
michael@0 30 // Otherwise we'll do it when Sync is firing up.
michael@0 31 let xps = Components.classes["@mozilla.org/weave/service;1"]
michael@0 32 .getService(Components.interfaces.nsISupports)
michael@0 33 .wrappedJSObject;
michael@0 34 if (xps.ready) {
michael@0 35 this.initUI();
michael@0 36 return;
michael@0 37 }
michael@0 38
michael@0 39 Services.obs.addObserver(this, "weave:service:ready", true);
michael@0 40
michael@0 41 // Remove the observer if the window is closed before the observer
michael@0 42 // was triggered.
michael@0 43 window.addEventListener("unload", function onUnload() {
michael@0 44 gSyncUI._unloaded = true;
michael@0 45 window.removeEventListener("unload", onUnload, false);
michael@0 46 Services.obs.removeObserver(gSyncUI, "weave:service:ready");
michael@0 47
michael@0 48 if (Weave.Status.ready) {
michael@0 49 gSyncUI._obs.forEach(function(topic) {
michael@0 50 Services.obs.removeObserver(gSyncUI, topic);
michael@0 51 });
michael@0 52 }
michael@0 53 }, false);
michael@0 54 },
michael@0 55
michael@0 56 initUI: function SUI_initUI() {
michael@0 57 // If this is a browser window?
michael@0 58 if (gBrowser) {
michael@0 59 this._obs.push("weave:notification:added");
michael@0 60 }
michael@0 61
michael@0 62 this._obs.forEach(function(topic) {
michael@0 63 Services.obs.addObserver(this, topic, true);
michael@0 64 }, this);
michael@0 65
michael@0 66 if (gBrowser && Weave.Notifications.notifications.length) {
michael@0 67 this.initNotifications();
michael@0 68 }
michael@0 69 this.updateUI();
michael@0 70 },
michael@0 71
michael@0 72 initNotifications: function SUI_initNotifications() {
michael@0 73 const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
michael@0 74 let notificationbox = document.createElementNS(XULNS, "notificationbox");
michael@0 75 notificationbox.id = "sync-notifications";
michael@0 76 notificationbox.setAttribute("flex", "1");
michael@0 77
michael@0 78 let bottombox = document.getElementById("browser-bottombox");
michael@0 79 bottombox.insertBefore(notificationbox, bottombox.firstChild);
michael@0 80
michael@0 81 // Force a style flush to ensure that our binding is attached.
michael@0 82 notificationbox.clientTop;
michael@0 83
michael@0 84 // notificationbox will listen to observers from now on.
michael@0 85 Services.obs.removeObserver(this, "weave:notification:added");
michael@0 86 },
michael@0 87
michael@0 88 _needsSetup: function SUI__needsSetup() {
michael@0 89 // We want to treat "account needs verification" as "needs setup". So
michael@0 90 // "reach in" to Weave.Status._authManager to check whether we the signed-in
michael@0 91 // user is verified.
michael@0 92 // Referencing Weave.Status spins a nested event loop to initialize the
michael@0 93 // authManager, so this should always return a value directly.
michael@0 94 // This only applies to fxAccounts-based Sync.
michael@0 95 if (Weave.Status._authManager._signedInUser) {
michael@0 96 // If we have a signed in user already, and that user is not verified,
michael@0 97 // revert to the "needs setup" state.
michael@0 98 if (!Weave.Status._authManager._signedInUser.verified) {
michael@0 99 return true;
michael@0 100 }
michael@0 101 }
michael@0 102
michael@0 103 let firstSync = "";
michael@0 104 try {
michael@0 105 firstSync = Services.prefs.getCharPref("services.sync.firstSync");
michael@0 106 } catch (e) { }
michael@0 107
michael@0 108 return Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
michael@0 109 firstSync == "notReady";
michael@0 110 },
michael@0 111
michael@0 112 _loginFailed: function () {
michael@0 113 return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
michael@0 114 },
michael@0 115
michael@0 116 updateUI: function SUI_updateUI() {
michael@0 117 let needsSetup = this._needsSetup();
michael@0 118 let loginFailed = this._loginFailed();
michael@0 119
michael@0 120 // Start off with a clean slate
michael@0 121 document.getElementById("sync-reauth-state").hidden = true;
michael@0 122 document.getElementById("sync-setup-state").hidden = true;
michael@0 123 document.getElementById("sync-syncnow-state").hidden = true;
michael@0 124
michael@0 125 if (loginFailed) {
michael@0 126 document.getElementById("sync-reauth-state").hidden = false;
michael@0 127 } else if (needsSetup) {
michael@0 128 document.getElementById("sync-setup-state").hidden = false;
michael@0 129 } else {
michael@0 130 document.getElementById("sync-syncnow-state").hidden = false;
michael@0 131 }
michael@0 132
michael@0 133 if (!gBrowser)
michael@0 134 return;
michael@0 135
michael@0 136 let syncButton = document.getElementById("sync-button");
michael@0 137 let panelHorizontalButton = document.getElementById("PanelUI-fxa-status");
michael@0 138 [syncButton, panelHorizontalButton].forEach(function(button) {
michael@0 139 if (!button)
michael@0 140 return;
michael@0 141 button.removeAttribute("status");
michael@0 142 });
michael@0 143
michael@0 144 if (needsSetup && syncButton)
michael@0 145 syncButton.removeAttribute("tooltiptext");
michael@0 146
michael@0 147 this._updateLastSyncTime();
michael@0 148 },
michael@0 149
michael@0 150
michael@0 151 // Functions called by observers
michael@0 152 onActivityStart: function SUI_onActivityStart() {
michael@0 153 if (!gBrowser)
michael@0 154 return;
michael@0 155
michael@0 156 ["sync-button", "PanelUI-fxa-status"].forEach(function(id) {
michael@0 157 let button = document.getElementById(id);
michael@0 158 if (!button)
michael@0 159 return;
michael@0 160 button.setAttribute("status", "active");
michael@0 161 });
michael@0 162 },
michael@0 163
michael@0 164 onLoginFinish: function SUI_onLoginFinish() {
michael@0 165 // Clear out any login failure notifications
michael@0 166 let title = this._stringBundle.GetStringFromName("error.login.title");
michael@0 167 this.clearError(title);
michael@0 168 },
michael@0 169
michael@0 170 onSetupComplete: function SUI_onSetupComplete() {
michael@0 171 this.onLoginFinish();
michael@0 172 },
michael@0 173
michael@0 174 onLoginError: function SUI_onLoginError() {
michael@0 175 // if login fails, any other notifications are essentially moot
michael@0 176 Weave.Notifications.removeAll();
michael@0 177
michael@0 178 // if we haven't set up the client, don't show errors
michael@0 179 if (this._needsSetup()) {
michael@0 180 this.updateUI();
michael@0 181 return;
michael@0 182 }
michael@0 183 // if we are still waiting for the identity manager to initialize, don't show errors
michael@0 184 if (Weave.Status.login == Weave.LOGIN_FAILED_NOT_READY) {
michael@0 185 this.updateUI();
michael@0 186 return;
michael@0 187 }
michael@0 188
michael@0 189 let title = this._stringBundle.GetStringFromName("error.login.title");
michael@0 190
michael@0 191 let description;
michael@0 192 if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
michael@0 193 // Convert to days
michael@0 194 let lastSync =
michael@0 195 Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
michael@0 196 description =
michael@0 197 this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
michael@0 198 } else {
michael@0 199 let reason = Weave.Utils.getErrorString(Weave.Status.login);
michael@0 200 description =
michael@0 201 this._stringBundle.formatStringFromName("error.sync.description", [reason], 1);
michael@0 202 }
michael@0 203
michael@0 204 let buttons = [];
michael@0 205 buttons.push(new Weave.NotificationButton(
michael@0 206 this._stringBundle.GetStringFromName("error.login.prefs.label"),
michael@0 207 this._stringBundle.GetStringFromName("error.login.prefs.accesskey"),
michael@0 208 function() { gSyncUI.openPrefs(); return true; }
michael@0 209 ));
michael@0 210
michael@0 211 let notification = new Weave.Notification(title, description, null,
michael@0 212 Weave.Notifications.PRIORITY_WARNING, buttons);
michael@0 213 Weave.Notifications.replaceTitle(notification);
michael@0 214 this.updateUI();
michael@0 215 },
michael@0 216
michael@0 217 onLogout: function SUI_onLogout() {
michael@0 218 this.updateUI();
michael@0 219 },
michael@0 220
michael@0 221 onStartOver: function SUI_onStartOver() {
michael@0 222 this.clearError();
michael@0 223 },
michael@0 224
michael@0 225 onQuotaNotice: function onQuotaNotice(subject, data) {
michael@0 226 let title = this._stringBundle.GetStringFromName("warning.sync.quota.label");
michael@0 227 let description = this._stringBundle.GetStringFromName("warning.sync.quota.description");
michael@0 228 let buttons = [];
michael@0 229 buttons.push(new Weave.NotificationButton(
michael@0 230 this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.label"),
michael@0 231 this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.accesskey"),
michael@0 232 function() { gSyncUI.openQuotaDialog(); return true; }
michael@0 233 ));
michael@0 234
michael@0 235 let notification = new Weave.Notification(
michael@0 236 title, description, null, Weave.Notifications.PRIORITY_WARNING, buttons);
michael@0 237 Weave.Notifications.replaceTitle(notification);
michael@0 238 },
michael@0 239
michael@0 240 _getAppName: function () {
michael@0 241 let brand = new StringBundle("chrome://branding/locale/brand.properties");
michael@0 242 return brand.get("brandShortName");
michael@0 243 },
michael@0 244
michael@0 245 onEOLNotice: function (data) {
michael@0 246 let code = data.code;
michael@0 247 let kind = (code == "hard-eol") ? "error" : "warning";
michael@0 248 let url = data.url || gSyncUI.DEFAULT_EOL_URL;
michael@0 249
michael@0 250 let title = this._stringBundle.GetStringFromName(kind + ".sync.eol.label");
michael@0 251 let description = this._stringBundle.formatStringFromName(kind + ".sync.eol.description",
michael@0 252 [this._getAppName()],
michael@0 253 1);
michael@0 254
michael@0 255 let buttons = [];
michael@0 256 buttons.push(new Weave.NotificationButton(
michael@0 257 this._stringBundle.GetStringFromName("sync.eol.learnMore.label"),
michael@0 258 this._stringBundle.GetStringFromName("sync.eol.learnMore.accesskey"),
michael@0 259 function() {
michael@0 260 window.openUILinkIn(url, "tab");
michael@0 261 return true;
michael@0 262 }
michael@0 263 ));
michael@0 264
michael@0 265 let priority = (kind == "error") ? Weave.Notifications.PRIORITY_WARNING :
michael@0 266 Weave.Notifications.PRIORITY_INFO;
michael@0 267 let notification = new Weave.Notification(title, description, null, priority, buttons);
michael@0 268 Weave.Notifications.replaceTitle(notification);
michael@0 269 },
michael@0 270
michael@0 271 openServerStatus: function () {
michael@0 272 let statusURL = Services.prefs.getCharPref("services.sync.statusURL");
michael@0 273 window.openUILinkIn(statusURL, "tab");
michael@0 274 },
michael@0 275
michael@0 276 // Commands
michael@0 277 doSync: function SUI_doSync() {
michael@0 278 setTimeout(function() Weave.Service.errorHandler.syncAndReportErrors(), 0);
michael@0 279 },
michael@0 280
michael@0 281 handleToolbarButton: function SUI_handleStatusbarButton() {
michael@0 282 if (this._needsSetup())
michael@0 283 this.openSetup();
michael@0 284 else
michael@0 285 this.doSync();
michael@0 286 },
michael@0 287
michael@0 288 //XXXzpao should be part of syncCommon.js - which we might want to make a module...
michael@0 289 // To be fixed in a followup (bug 583366)
michael@0 290
michael@0 291 /**
michael@0 292 * Invoke the Sync setup wizard.
michael@0 293 *
michael@0 294 * @param wizardType
michael@0 295 * Indicates type of wizard to launch:
michael@0 296 * null -- regular set up wizard
michael@0 297 * "pair" -- pair a device first
michael@0 298 * "reset" -- reset sync
michael@0 299 */
michael@0 300
michael@0 301 openSetup: function SUI_openSetup(wizardType) {
michael@0 302 let xps = Components.classes["@mozilla.org/weave/service;1"]
michael@0 303 .getService(Components.interfaces.nsISupports)
michael@0 304 .wrappedJSObject;
michael@0 305 if (xps.fxAccountsEnabled) {
michael@0 306 fxAccounts.getSignedInUser().then(userData => {
michael@0 307 if (userData) {
michael@0 308 this.openPrefs();
michael@0 309 } else {
michael@0 310 switchToTabHavingURI("about:accounts", true);
michael@0 311 }
michael@0 312 });
michael@0 313 } else {
michael@0 314 let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
michael@0 315 if (win)
michael@0 316 win.focus();
michael@0 317 else {
michael@0 318 window.openDialog("chrome://browser/content/sync/setup.xul",
michael@0 319 "weaveSetup", "centerscreen,chrome,resizable=no",
michael@0 320 wizardType);
michael@0 321 }
michael@0 322 }
michael@0 323 },
michael@0 324
michael@0 325 openAddDevice: function () {
michael@0 326 if (!Weave.Utils.ensureMPUnlocked())
michael@0 327 return;
michael@0 328
michael@0 329 let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
michael@0 330 if (win)
michael@0 331 win.focus();
michael@0 332 else
michael@0 333 window.openDialog("chrome://browser/content/sync/addDevice.xul",
michael@0 334 "syncAddDevice", "centerscreen,chrome,resizable=no");
michael@0 335 },
michael@0 336
michael@0 337 openQuotaDialog: function SUI_openQuotaDialog() {
michael@0 338 let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
michael@0 339 if (win)
michael@0 340 win.focus();
michael@0 341 else
michael@0 342 Services.ww.activeWindow.openDialog(
michael@0 343 "chrome://browser/content/sync/quota.xul", "",
michael@0 344 "centerscreen,chrome,dialog,modal");
michael@0 345 },
michael@0 346
michael@0 347 openPrefs: function SUI_openPrefs() {
michael@0 348 openPreferences("paneSync");
michael@0 349 },
michael@0 350
michael@0 351 openSignInAgainPage: function () {
michael@0 352 switchToTabHavingURI("about:accounts?action=reauth", true);
michael@0 353 },
michael@0 354
michael@0 355 // Helpers
michael@0 356 _updateLastSyncTime: function SUI__updateLastSyncTime() {
michael@0 357 if (!gBrowser)
michael@0 358 return;
michael@0 359
michael@0 360 let syncButton = document.getElementById("sync-button");
michael@0 361 if (!syncButton)
michael@0 362 return;
michael@0 363
michael@0 364 let lastSync;
michael@0 365 try {
michael@0 366 lastSync = Services.prefs.getCharPref("services.sync.lastSync");
michael@0 367 }
michael@0 368 catch (e) { };
michael@0 369 if (!lastSync || this._needsSetup()) {
michael@0 370 syncButton.removeAttribute("tooltiptext");
michael@0 371 return;
michael@0 372 }
michael@0 373
michael@0 374 // Show the day-of-week and time (HH:MM) of last sync
michael@0 375 let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
michael@0 376 let lastSyncLabel =
michael@0 377 this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDate], 1);
michael@0 378
michael@0 379 syncButton.setAttribute("tooltiptext", lastSyncLabel);
michael@0 380 },
michael@0 381
michael@0 382 clearError: function SUI_clearError(errorString) {
michael@0 383 Weave.Notifications.removeAll(errorString);
michael@0 384 this.updateUI();
michael@0 385 },
michael@0 386
michael@0 387 onSyncFinish: function SUI_onSyncFinish() {
michael@0 388 let title = this._stringBundle.GetStringFromName("error.sync.title");
michael@0 389
michael@0 390 // Clear out sync failures on a successful sync
michael@0 391 this.clearError(title);
michael@0 392 },
michael@0 393
michael@0 394 onSyncError: function SUI_onSyncError() {
michael@0 395 let title = this._stringBundle.GetStringFromName("error.sync.title");
michael@0 396
michael@0 397 if (Weave.Status.login != Weave.LOGIN_SUCCEEDED) {
michael@0 398 this.onLoginError();
michael@0 399 return;
michael@0 400 }
michael@0 401
michael@0 402 let description;
michael@0 403 if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
michael@0 404 // Convert to days
michael@0 405 let lastSync =
michael@0 406 Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
michael@0 407 description =
michael@0 408 this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
michael@0 409 } else {
michael@0 410 let error = Weave.Utils.getErrorString(Weave.Status.sync);
michael@0 411 description =
michael@0 412 this._stringBundle.formatStringFromName("error.sync.description", [error], 1);
michael@0 413 }
michael@0 414 let priority = Weave.Notifications.PRIORITY_WARNING;
michael@0 415 let buttons = [];
michael@0 416
michael@0 417 // Check if the client is outdated in some way
michael@0 418 let outdated = Weave.Status.sync == Weave.VERSION_OUT_OF_DATE;
michael@0 419 for (let [engine, reason] in Iterator(Weave.Status.engines))
michael@0 420 outdated = outdated || reason == Weave.VERSION_OUT_OF_DATE;
michael@0 421
michael@0 422 if (outdated) {
michael@0 423 description = this._stringBundle.GetStringFromName(
michael@0 424 "error.sync.needUpdate.description");
michael@0 425 buttons.push(new Weave.NotificationButton(
michael@0 426 this._stringBundle.GetStringFromName("error.sync.needUpdate.label"),
michael@0 427 this._stringBundle.GetStringFromName("error.sync.needUpdate.accesskey"),
michael@0 428 function() { window.openUILinkIn("https://services.mozilla.com/update/", "tab"); return true; }
michael@0 429 ));
michael@0 430 }
michael@0 431 else if (Weave.Status.sync == Weave.OVER_QUOTA) {
michael@0 432 description = this._stringBundle.GetStringFromName(
michael@0 433 "error.sync.quota.description");
michael@0 434 buttons.push(new Weave.NotificationButton(
michael@0 435 this._stringBundle.GetStringFromName(
michael@0 436 "error.sync.viewQuotaButton.label"),
michael@0 437 this._stringBundle.GetStringFromName(
michael@0 438 "error.sync.viewQuotaButton.accesskey"),
michael@0 439 function() { gSyncUI.openQuotaDialog(); return true; } )
michael@0 440 );
michael@0 441 }
michael@0 442 else if (Weave.Status.enforceBackoff) {
michael@0 443 priority = Weave.Notifications.PRIORITY_INFO;
michael@0 444 buttons.push(new Weave.NotificationButton(
michael@0 445 this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
michael@0 446 this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
michael@0 447 function() { gSyncUI.openServerStatus(); return true; }
michael@0 448 ));
michael@0 449 }
michael@0 450 else {
michael@0 451 priority = Weave.Notifications.PRIORITY_INFO;
michael@0 452 buttons.push(new Weave.NotificationButton(
michael@0 453 this._stringBundle.GetStringFromName("error.sync.tryAgainButton.label"),
michael@0 454 this._stringBundle.GetStringFromName("error.sync.tryAgainButton.accesskey"),
michael@0 455 function() { gSyncUI.doSync(); return true; }
michael@0 456 ));
michael@0 457 }
michael@0 458
michael@0 459 let notification =
michael@0 460 new Weave.Notification(title, description, null, priority, buttons);
michael@0 461 Weave.Notifications.replaceTitle(notification);
michael@0 462
michael@0 463 this.updateUI();
michael@0 464 },
michael@0 465
michael@0 466 observe: function SUI_observe(subject, topic, data) {
michael@0 467 if (this._unloaded) {
michael@0 468 Cu.reportError("SyncUI observer called after unload: " + topic);
michael@0 469 return;
michael@0 470 }
michael@0 471
michael@0 472 // Unwrap, just like Svc.Obs, but without pulling in that dependency.
michael@0 473 if (subject && typeof subject == "object" &&
michael@0 474 ("wrappedJSObject" in subject) &&
michael@0 475 ("observersModuleSubjectWrapper" in subject.wrappedJSObject)) {
michael@0 476 subject = subject.wrappedJSObject.object;
michael@0 477 }
michael@0 478
michael@0 479 switch (topic) {
michael@0 480 case "weave:service:sync:start":
michael@0 481 this.onActivityStart();
michael@0 482 break;
michael@0 483 case "weave:ui:sync:finish":
michael@0 484 this.onSyncFinish();
michael@0 485 break;
michael@0 486 case "weave:ui:sync:error":
michael@0 487 this.onSyncError();
michael@0 488 break;
michael@0 489 case "weave:service:quota:remaining":
michael@0 490 this.onQuotaNotice();
michael@0 491 break;
michael@0 492 case "weave:service:setup-complete":
michael@0 493 this.onSetupComplete();
michael@0 494 break;
michael@0 495 case "weave:service:login:start":
michael@0 496 this.onActivityStart();
michael@0 497 break;
michael@0 498 case "weave:service:login:finish":
michael@0 499 this.onLoginFinish();
michael@0 500 break;
michael@0 501 case "weave:ui:login:error":
michael@0 502 this.onLoginError();
michael@0 503 break;
michael@0 504 case "weave:service:logout:finish":
michael@0 505 this.onLogout();
michael@0 506 break;
michael@0 507 case "weave:service:start-over":
michael@0 508 this.onStartOver();
michael@0 509 break;
michael@0 510 case "weave:service:start-over:finish":
michael@0 511 this.updateUI();
michael@0 512 break;
michael@0 513 case "weave:service:ready":
michael@0 514 this.initUI();
michael@0 515 break;
michael@0 516 case "weave:notification:added":
michael@0 517 this.initNotifications();
michael@0 518 break;
michael@0 519 case "weave:ui:clear-error":
michael@0 520 this.clearError();
michael@0 521 break;
michael@0 522 case "weave:eol":
michael@0 523 this.onEOLNotice(subject);
michael@0 524 break;
michael@0 525 }
michael@0 526 },
michael@0 527
michael@0 528 QueryInterface: XPCOMUtils.generateQI([
michael@0 529 Ci.nsIObserver,
michael@0 530 Ci.nsISupportsWeakReference
michael@0 531 ])
michael@0 532 };
michael@0 533
michael@0 534 XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() {
michael@0 535 //XXXzpao these strings should probably be moved from /services to /browser... (bug 583381)
michael@0 536 // but for now just make it work
michael@0 537 return Cc["@mozilla.org/intl/stringbundle;1"].
michael@0 538 getService(Ci.nsIStringBundleService).
michael@0 539 createBundle("chrome://weave/locale/services/sync.properties");
michael@0 540 });
michael@0 541

mercurial