Bug 1180587 - remove most error handling from browser-syncui now it is shown in the hamburger menu. r=adw

This commit is contained in:
Mark Hammond 2015-08-06 14:47:31 +10:00
parent a425371327
commit 28ed82509d
12 changed files with 36 additions and 629 deletions

View File

@ -16,7 +16,6 @@ let gSyncUI = {
_obs: ["weave:service:sync:start",
"weave:service:sync:finish",
"weave:service:sync:error",
"weave:service:quota:remaining",
"weave:service:setup-complete",
"weave:service:login:start",
"weave:service:login:finish",
@ -124,6 +123,9 @@ let gSyncUI = {
firstSync == "notReady";
},
// 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 () {
this.log.debug("_loginFailed has sync state=${sync}",
{ sync: Weave.Status.login});
@ -142,8 +144,8 @@ let gSyncUI = {
if (CloudSync && CloudSync.ready && CloudSync().adapters.count) {
document.getElementById("sync-syncnow-state").hidden = false;
} else if (loginFailed) {
// unhiding this element makes the menubar show the login failure state.
document.getElementById("sync-reauth-state").hidden = false;
this.showLoginError();
} else if (needsSetup) {
document.getElementById("sync-setup-state").hidden = false;
} else {
@ -167,7 +169,6 @@ let gSyncUI = {
this._updateLastSyncTime();
},
// Functions called by observers
onActivityStart() {
if (!gBrowser)
@ -184,6 +185,7 @@ let gSyncUI = {
container.setAttribute("syncstatus", "active");
}
}
this.updateUI();
},
onActivityStop() {
@ -209,70 +211,16 @@ let gSyncUI = {
if (fxaContainer) {
fxaContainer.removeAttribute("syncstatus");
}
},
onLoginFinish: function SUI_onLoginFinish() {
// Clear out any login failure notifications
let title = this._stringBundle.GetStringFromName("error.login.title");
this.clearError(title);
},
onSetupComplete: function SUI_onSetupComplete() {
this.onLoginFinish();
this.updateUI();
},
onLoginError: function SUI_onLoginError() {
this.log.debug("onLoginError: login=${login}, sync=${sync}", Weave.Status);
Weave.Notifications.removeAll();
// if we haven't set up the client, don't show errors
if (this._needsSetup()) {
// We don't show any login errors here; browser-fxaccounts shows them in
// the hamburger menu.
this.updateUI();
return;
}
// if we are still waiting for the identity manager to initialize, or it's
// a network/server error, don't show errors. If it weren't for the legacy
// provider we could just check LOGIN_FAILED_LOGIN_REJECTED, but the legacy
// provider has states like LOGIN_FAILED_INVALID_PASSPHRASE which we
// probably do want to surface.
if (Weave.Status.login == Weave.LOGIN_FAILED_NOT_READY ||
Weave.Status.login == Weave.LOGIN_FAILED_NETWORK_ERROR ||
Weave.Status.login == Weave.LOGIN_FAILED_SERVER_ERROR) {
this.updateUI();
return;
}
this.showLoginError();
this.updateUI();
},
showLoginError() {
let title = this._stringBundle.GetStringFromName("error.login.title");
let description;
if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
this.log.debug("showLoginError has a prolonged login error");
// 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 reason = Weave.Utils.getErrorString(Weave.Status.login);
description =
this._stringBundle.formatStringFromName("error.sync.description", [reason], 1);
this.log.debug("showLoginError has a non-prolonged error", reason);
}
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; }
));
let notification = new Weave.Notification(title, description, null,
Weave.Notifications.PRIORITY_WARNING, buttons);
Weave.Notifications.replaceTitle(notification);
},
onLogout: function SUI_onLogout() {
@ -283,31 +231,11 @@ let gSyncUI = {
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");
let buttons = [];
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.label"),
this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.accesskey"),
function() { gSyncUI.openQuotaDialog(); return true; }
));
let notification = new Weave.Notification(
title, description, null, Weave.Notifications.PRIORITY_WARNING, buttons);
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: function SUI_doSync() {
let needsSetup = this._needsSetup();
@ -326,9 +254,6 @@ let gSyncUI = {
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.
*
@ -384,16 +309,6 @@ let gSyncUI = {
"syncAddDevice", "centerscreen,chrome,resizable=no");
},
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");
},
openPrefs: function SUI_openPrefs() {
openPreferences("paneSync");
},
@ -450,81 +365,6 @@ let gSyncUI = {
this.clearError(title);
},
onSyncError: function SUI_onSyncError() {
this.log.debug("onSyncError: login=${login}, sync=${sync}", Weave.Status);
let title = this._stringBundle.GetStringFromName("error.sync.title");
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 = [];
// Check if the client is outdated in some way (but note: we've never in the
// past, and probably never will, bump the relevent version numbers, so
// this is effectively dead code!)
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.needUpdate.label"),
this._stringBundle.GetStringFromName("error.sync.needUpdate.accesskey"),
function() { window.openUILinkIn("https://services.mozilla.com/update/", "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; } )
);
}
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);
this.updateUI();
},
observe: function SUI_observe(subject, topic, data) {
this.log.debug("observed", topic);
if (this._unloaded) {
@ -559,16 +399,8 @@ let gSyncUI = {
this.onSyncFinish();
break;
case "weave:ui:sync:error":
this.onSyncError();
break;
case "weave:service:quota:remaining":
this.onQuotaNotice();
break;
case "weave:service:setup-complete":
this.onSetupComplete();
break;
case "weave:service:login:finish":
this.onLoginFinish();
this.updateUI();
break;
case "weave:ui:login:error":
this.onLoginError();

View File

@ -1,267 +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/. */
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cr = Components.results;
const Cu = Components.utils;
Cu.import("resource://services-sync/main.js");
Cu.import("resource://gre/modules/DownloadUtils.jsm");
let gSyncQuota = {
init: function init() {
this.bundle = document.getElementById("quotaStrings");
let caption = document.getElementById("treeCaption");
caption.firstChild.nodeValue = this.bundle.getString("quota.treeCaption.label");
gUsageTreeView.init();
this.tree = document.getElementById("usageTree");
this.tree.view = gUsageTreeView;
this.loadData();
},
loadData: function loadData() {
this._usage_req = Weave.Service.getStorageInfo(Weave.INFO_COLLECTION_USAGE,
function (error, usage) {
delete gSyncQuota._usage_req;
// displayUsageData handles null values, so no need to check 'error'.
gUsageTreeView.displayUsageData(usage);
});
let usageLabel = document.getElementById("usageLabel");
let bundle = this.bundle;
this._quota_req = Weave.Service.getStorageInfo(Weave.INFO_QUOTA,
function (error, quota) {
delete gSyncQuota._quota_req;
if (error) {
usageLabel.value = bundle.getString("quota.usageError.label");
return;
}
let used = gSyncQuota.convertKB(quota[0]);
if (!quota[1]) {
// No quota on the server.
usageLabel.value = bundle.getFormattedString(
"quota.usageNoQuota.label", used);
return;
}
let percent = Math.round(100 * quota[0] / quota[1]);
let total = gSyncQuota.convertKB(quota[1]);
usageLabel.value = bundle.getFormattedString(
"quota.usagePercentage.label", [percent].concat(used).concat(total));
});
},
onCancel: function onCancel() {
if (this._usage_req) {
this._usage_req.abort();
}
if (this._quota_req) {
this._quota_req.abort();
}
return true;
},
onAccept: function onAccept() {
let engines = gUsageTreeView.getEnginesToDisable();
for each (let engine in engines) {
Weave.Service.engineManager.get(engine).enabled = false;
}
if (engines.length) {
// The 'Weave' object will disappear once the window closes.
let Service = Weave.Service;
Weave.Utils.nextTick(function() { Service.sync(); });
}
return this.onCancel();
},
convertKB: function convertKB(value) {
return DownloadUtils.convertByteUnits(value * 1024);
}
};
let gUsageTreeView = {
_ignored: {keys: true,
meta: true,
clients: true},
/*
* Internal data structures underlaying the tree.
*/
_collections: [],
_byname: {},
init: function init() {
let retrievingLabel = gSyncQuota.bundle.getString("quota.retrieving.label");
for each (let engine in Weave.Service.engineManager.getEnabled()) {
if (this._ignored[engine.name])
continue;
// Some engines use the same pref, which means they can only be turned on
// and off together. We need to combine them here as well.
let existing = this._byname[engine.prefName];
if (existing) {
existing.engines.push(engine.name);
continue;
}
let obj = {name: engine.prefName,
title: this._collectionTitle(engine),
engines: [engine.name],
enabled: true,
sizeLabel: retrievingLabel};
this._collections.push(obj);
this._byname[engine.prefName] = obj;
}
},
_collectionTitle: function _collectionTitle(engine) {
try {
return gSyncQuota.bundle.getString(
"collection." + engine.prefName + ".label");
} catch (ex) {
return engine.Name;
}
},
/*
* Process the quota information as returned by info/collection_usage.
*/
displayUsageData: function displayUsageData(data) {
for each (let coll in this._collections) {
coll.size = 0;
// If we couldn't retrieve any data, just blank out the label.
if (!data) {
coll.sizeLabel = "";
continue;
}
for each (let engineName in coll.engines)
coll.size += data[engineName] || 0;
let sizeLabel = "";
sizeLabel = gSyncQuota.bundle.getFormattedString(
"quota.sizeValueUnit.label", gSyncQuota.convertKB(coll.size));
coll.sizeLabel = sizeLabel;
}
let sizeColumn = this.treeBox.columns.getNamedColumn("size");
this.treeBox.invalidateColumn(sizeColumn);
},
/*
* Handle click events on the tree.
*/
onTreeClick: function onTreeClick(event) {
if (event.button == 2)
return;
let cell = this.treeBox.getCellAt(event.clientX, event.clientY);
if (cell.col && cell.col.id == "enabled")
this.toggle(cell.row);
},
/*
* Toggle enabled state of an engine.
*/
toggle: function toggle(row) {
// Update the tree
let collection = this._collections[row];
collection.enabled = !collection.enabled;
this.treeBox.invalidateRow(row);
// Display which ones will be removed
let freeup = 0;
let toremove = [];
for each (collection in this._collections) {
if (collection.enabled)
continue;
toremove.push(collection.name);
freeup += collection.size;
}
let caption = document.getElementById("treeCaption");
if (!toremove.length) {
caption.className = "";
caption.firstChild.nodeValue = gSyncQuota.bundle.getString(
"quota.treeCaption.label");
return;
}
toremove = [this._byname[coll].title for each (coll in toremove)];
toremove = toremove.join(gSyncQuota.bundle.getString("quota.list.separator"));
caption.firstChild.nodeValue = gSyncQuota.bundle.getFormattedString(
"quota.removal.label", [toremove]);
if (freeup)
caption.firstChild.nodeValue += gSyncQuota.bundle.getFormattedString(
"quota.freeup.label", gSyncQuota.convertKB(freeup));
caption.className = "captionWarning";
},
/*
* Return a list of engines (or rather their pref names) that should be
* disabled.
*/
getEnginesToDisable: function getEnginesToDisable() {
return [coll.name for each (coll in this._collections) if (!coll.enabled)];
},
// nsITreeView
get rowCount() {
return this._collections.length;
},
getRowProperties: function(index) { return ""; },
getCellProperties: function(row, col) { return ""; },
getColumnProperties: function(col) { return ""; },
isContainer: function(index) { return false; },
isContainerOpen: function(index) { return false; },
isContainerEmpty: function(index) { return false; },
isSeparator: function(index) { return false; },
isSorted: function() { return false; },
canDrop: function(index, orientation, dataTransfer) { return false; },
drop: function(row, orientation, dataTransfer) {},
getParentIndex: function(rowIndex) {},
hasNextSibling: function(rowIndex, afterIndex) { return false; },
getLevel: function(index) { return 0; },
getImageSrc: function(row, col) {},
getCellValue: function(row, col) {
return this._collections[row].enabled;
},
getCellText: function getCellText(row, col) {
let collection = this._collections[row];
switch (col.id) {
case "collection":
return collection.title;
case "size":
return collection.sizeLabel;
default:
return "";
}
},
setTree: function setTree(tree) {
this.treeBox = tree;
},
toggleOpenState: function(index) {},
cycleHeader: function(col) {},
selectionChanged: function() {},
cycleCell: function(row, col) {},
isEditable: function(row, col) { return false; },
isSelectable: function (row, col) { return false; },
setCellValue: function(row, col, value) {},
setCellText: function(row, col, value) {},
performAction: function(action) {},
performActionOnRow: function(action, row) {},
performActionOnCell: function(action, row, col) {}
};

View File

@ -1,65 +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/skin/syncQuota.css"?>
<!DOCTYPE dialog [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
<!ENTITY % syncQuotaDTD SYSTEM "chrome://browser/locale/syncQuota.dtd">
%brandDTD;
%syncBrandDTD;
%syncQuotaDTD;
]>
<dialog id="quotaDialog"
windowtype="Sync:ViewQuota"
persist="screenX screenY width height"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
onload="gSyncQuota.init()"
buttons="accept,cancel"
title="&quota.dialogTitle.label;"
ondialogcancel="return gSyncQuota.onCancel();"
ondialogaccept="return gSyncQuota.onAccept();">
<script type="application/javascript"
src="chrome://browser/content/sync/quota.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="quotaStrings"
src="chrome://browser/locale/syncQuota.properties"/>
</stringbundleset>
<vbox flex="1">
<label id="usageLabel"
value="&quota.retrievingInfo.label;"/>
<separator/>
<tree id="usageTree"
seltype="single"
hidecolumnpicker="true"
onclick="gUsageTreeView.onTreeClick(event);"
flex="1">
<treecols>
<treecol id="enabled"
type="checkbox"
fixed="true"/>
<splitter class="tree-splitter"/>
<treecol id="collection"
label="&quota.typeColumn.label;"
flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="size"
label="&quota.sizeColumn.label;"
flex="1"/>
</treecols>
<treechildren flex="1"/>
</tree>
<separator/>
<description id="treeCaption"> </description>
</vbox>
</dialog>

View File

@ -12,6 +12,18 @@ let stringBundle = Cc["@mozilla.org/intl/stringbundle;1"]
// ensure test output sees log messages.
Log.repository.getLogger("browserwindow.syncui").addAppender(new Log.DumpAppender());
// Sync manages 3 broadcasters so the menus correctly reflect the Sync state.
// Only one of these 3 should ever be visible - pass the ID of the broadcaster
// you expect to be visible and it will check it's the only one that is.
function checkBroadcasterVisible(broadcasterId) {
let all = ["sync-reauth-state", "sync-setup-state", "sync-syncnow-state"];
Assert.ok(all.indexOf(broadcasterId) >= 0, "valid id");
for (let check of all) {
let eltHidden = document.getElementById(check).hidden;
Assert.equal(eltHidden, check == broadcasterId ? false : true, check);
}
}
function promiseObserver(topic) {
return new Promise(resolve => {
let obs = (subject, topic, data) => {
@ -27,105 +39,39 @@ add_task(function* prepare() {
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
yield xps.whenLoaded();
checkBroadcasterVisible("sync-setup-state");
// mock out the "_needsSetup()" function so we don't short-circuit.
let oldNeedsSetup = window.gSyncUI._needsSetup;
window.gSyncUI._needsSetup = () => false;
registerCleanupFunction(() => {
window.gSyncUI._needsSetup = oldNeedsSetup;
});
});
add_task(function* testProlongedSyncError() {
let promiseNotificationAdded = promiseObserver("weave:notification:added");
Assert.equal(Notifications.notifications.length, 0, "start with no notifications");
// Pretend we are in the "prolonged error" state.
Weave.Status.sync = Weave.PROLONGED_SYNC_FAILURE;
Weave.Status.login = Weave.LOGIN_SUCCEEDED;
Services.obs.notifyObservers(null, "weave:ui:sync:error", null);
let subject = yield promiseNotificationAdded;
let notification = subject.wrappedJSObject.object; // sync's observer abstraction is abstract!
Assert.equal(notification.title, stringBundle.GetStringFromName("error.sync.title"));
Assert.equal(Notifications.notifications.length, 1, "exactly 1 notification");
// Now pretend we just had a successful sync - the error notification should go away.
let promiseNotificationRemoved = promiseObserver("weave:notification:removed");
Weave.Status.sync = Weave.STATUS_OK;
Services.obs.notifyObservers(null, "weave:ui:sync:finish", null);
yield promiseNotificationRemoved;
Assert.equal(Notifications.notifications.length, 0, "no notifications left");
// and a notification to have the state change away from "needs setup"
Services.obs.notifyObservers(null, "weave:ui:clear-error", null);
checkBroadcasterVisible("sync-syncnow-state");
});
add_task(function* testSyncLoginError() {
let promiseNotificationAdded = promiseObserver("weave:notification:added");
Assert.equal(Notifications.notifications.length, 0, "start with no notifications");
checkBroadcasterVisible("sync-syncnow-state");
// Pretend we are in the "prolonged error" state.
// Pretend we are in a "login failed" error state
Weave.Status.sync = Weave.LOGIN_FAILED;
Weave.Status.login = Weave.LOGIN_FAILED_LOGIN_REJECTED;
Services.obs.notifyObservers(null, "weave:ui:sync:error", null);
let subject = yield promiseNotificationAdded;
let notification = subject.wrappedJSObject.object; // sync's observer abstraction is abstract!
Assert.equal(notification.title, stringBundle.GetStringFromName("error.login.title"));
Assert.equal(Notifications.notifications.length, 1, "exactly 1 notification");
Assert.equal(Notifications.notifications.length, 0, "no notifications shown on login error");
// But the menu *should* reflect the login error.
checkBroadcasterVisible("sync-reauth-state");
// Now pretend we just had a successful login - the error notification should go away.
Weave.Status.sync = Weave.STATUS_OK;
Weave.Status.login = Weave.LOGIN_SUCCEEDED;
let promiseNotificationRemoved = promiseObserver("weave:notification:removed");
Services.obs.notifyObservers(null, "weave:service:login:start", null);
Services.obs.notifyObservers(null, "weave:service:login:finish", null);
yield promiseNotificationRemoved;
Assert.equal(Notifications.notifications.length, 0, "no notifications left");
});
add_task(function* testSyncLoginNetworkError() {
Assert.equal(Notifications.notifications.length, 0, "start with no notifications");
// This test relies on the fact that observers are synchronous, and that error
// notifications synchronously create the error notification, which itself
// fires an observer notification.
// ie, we should see the error notification *during* the notifyObservers call.
// To prove that, we cause a notification that *does* show an error and make
// sure we see the error notification during that call. We then cause a
// notification that *should not* show an error, and the lack of the
// notification during the call implies the error was ignored.
// IOW, if this first part of the test fails in the future, it means the
// above is no longer true and we need a different strategy to check for
// ignored errors.
let sawNotificationAdded = false;
let obs = (subject, topic, data) => {
sawNotificationAdded = true;
}
Services.obs.addObserver(obs, "weave:notification:added", false);
try {
// notify of a display-able error - we should synchronously see our flag set.
Weave.Status.sync = Weave.LOGIN_FAILED;
Weave.Status.login = Weave.LOGIN_FAILED_LOGIN_REJECTED;
Services.obs.notifyObservers(null, "weave:ui:login:error", null);
Assert.ok(sawNotificationAdded);
// reset the flag and test what should *not* show an error.
sawNotificationAdded = false;
Weave.Status.sync = Weave.LOGIN_FAILED;
Weave.Status.login = Weave.LOGIN_FAILED_NETWORK_ERROR;
Services.obs.notifyObservers(null, "weave:ui:login:error", null);
Assert.ok(!sawNotificationAdded);
// ditto for LOGIN_FAILED_SERVER_ERROR
Weave.Status.sync = Weave.LOGIN_FAILED;
Weave.Status.login = Weave.LOGIN_FAILED_SERVER_ERROR;
Services.obs.notifyObservers(null, "weave:ui:login:error", null);
Assert.ok(!sawNotificationAdded);
// we are done.
} finally {
Services.obs.removeObserver(obs, "weave:notification:added");
}
// The menus should be back to "all good"
checkBroadcasterVisible("sync-syncnow-state");
});
function checkButtonsStatus(shouldBeActive) {

View File

@ -130,8 +130,6 @@ browser.jar:
content/browser/sync/genericChange.js (content/sync/genericChange.js)
content/browser/sync/key.xhtml (content/sync/key.xhtml)
content/browser/sync/notification.xml (content/sync/notification.xml)
content/browser/sync/quota.xul (content/sync/quota.xul)
content/browser/sync/quota.js (content/sync/quota.js)
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)

View File

@ -193,7 +193,6 @@ let gSyncPane = {
aEvent.stopPropagation();
gSyncPane.openSetup('pair');
});
setEventListener("syncViewQuota", "command", gSyncPane.openQuotaDialog);
setEventListener("syncChangePassword", "command",
() => gSyncUtils.changePassword());
setEventListener("syncResetPassphrase", "command",
@ -714,15 +713,6 @@ let gSyncPane = {
});
},
openQuotaDialog: function () {
let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
if (win)
win.focus();
else
window.openDialog("chrome://browser/content/sync/quota.xul", "",
"centerscreen,chrome,dialog,modal");
},
openAddDevice: function () {
if (!Weave.Utils.ensureMPUnlocked())
return;

View File

@ -97,8 +97,6 @@
label="&manageAccount.label;"
accesskey="&manageAccount.accesskey;">
<menupopup>
<menuitem id="syncViewQuota" label="&viewQuota.label;"/>
<menuseparator/>
<menuitem id="syncChangePassword" label="&changePassword2.label;"/>
<menuitem id="syncResetPassphrase" label="&myRecoveryKey.label;"/>
<menuseparator/>

View File

@ -454,16 +454,6 @@ let gSyncPane = {
});
},
openQuotaDialog: function () {
let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
if (win) {
win.focus();
} else {
window.openDialog("chrome://browser/content/sync/quota.xul", "",
"centerscreen,chrome,dialog,modal");
}
},
openAddDevice: function () {
if (!Weave.Utils.ensureMPUnlocked()) {
return;

View File

@ -95,9 +95,6 @@
label="&manageAccount.label;"
accesskey="&manageAccount.accesskey;">
<menupopup>
<menuitem label="&viewQuota.label;"
oncommand="gSyncPane.openQuotaDialog();"/>
<menuseparator/>
<menuitem label="&changePassword2.label;"
oncommand="gSyncUtils.changePassword();"/>
<menuitem label="&myRecoveryKey.label;"

View File

@ -16,7 +16,6 @@
<!-- Manage Account -->
<!ENTITY manageAccount.label "Manage Account">
<!ENTITY manageAccount.accesskey "n">
<!ENTITY viewQuota.label "View Quota">
<!ENTITY changePassword2.label "Change Password…">
<!ENTITY myRecoveryKey.label "My Recovery Key">
<!ENTITY resetSync2.label "Reset Sync…">

View File

@ -24,20 +24,6 @@ error.logout.title = Error While Signing Out
error.logout.description = Sync encountered an error while connecting. It's probably ok, and you don't have to do anything about it.
error.sync.title = Error While Syncing
error.sync.description = Sync encountered an error while syncing: %1$S. Sync will automatically retry this action.
error.sync.prolonged_failure = Sync has not been able to complete during the last %1$S days. Please check your network settings.
error.sync.serverStatusButton.label = Server Status
error.sync.serverStatusButton.accesskey = V
error.sync.needUpdate.description = You need to update Firefox Sync to continue syncing your data.
error.sync.needUpdate.label = Update Firefox Sync
error.sync.needUpdate.accesskey = U
error.sync.tryAgainButton.label = Sync Now
error.sync.tryAgainButton.accesskey = S
warning.sync.quota.label = Approaching Server Quota
warning.sync.quota.description = You are approaching the server quota. Please review which data to sync.
error.sync.quota.label = Server Quota Exceeded
error.sync.quota.description = Sync failed because it exceeded the server quota. Please review which data to sync.
error.sync.viewQuotaButton.label = View Quota
error.sync.viewQuotaButton.accesskey = V
warning.sync.eol.label = Service Shutting Down
# %1: the app name (Firefox)
warning.sync.eol.description = Your Firefox Sync service is shutting down soon. Upgrade %1$S to keep syncing.

View File

@ -575,7 +575,7 @@ ErrorHandler.prototype = {
root.level = Log.Level[Svc.Prefs.get("log.rootLogger")];
let logs = ["Sync", "FirefoxAccounts", "Hawk", "Common.TokenServerClient",
"Sync.SyncMigration"];
"Sync.SyncMigration", "browserwindow.syncui"];
this._logManager = new LogManager(Svc.Prefs, logs, "sync");
},
@ -728,6 +728,9 @@ ErrorHandler.prototype = {
}
},
// A function to indicate if Sync errors should be "reported" - which in this
// context really means "should be notify observers of an error" - but note
// that since bug 1180587, no one is going to surface an error to the user.
shouldReportError: function shouldReportError() {
if (Status.login == MASTER_PASSWORD_LOCKED) {
this._log.trace("shouldReportError: false (master password locked).");