mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 1180587 - remove most error handling from browser-syncui now it is shown in the hamburger menu. r=adw
This commit is contained in:
parent
a425371327
commit
28ed82509d
@ -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,72 +211,18 @@ 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()) {
|
||||
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();
|
||||
// We don't show any login errors here; browser-fxaccounts shows them in
|
||||
// the hamburger menu.
|
||||
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() {
|
||||
this.updateUI();
|
||||
},
|
||||
@ -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();
|
||||
|
@ -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) {}
|
||||
|
||||
};
|
@ -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=""a.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=""a.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=""a.typeColumn.label;"
|
||||
flex="1"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="size"
|
||||
label=""a.sizeColumn.label;"
|
||||
flex="1"/>
|
||||
</treecols>
|
||||
<treechildren flex="1"/>
|
||||
</tree>
|
||||
<separator/>
|
||||
<description id="treeCaption"> </description>
|
||||
</vbox>
|
||||
|
||||
</dialog>
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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/>
|
||||
|
@ -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;
|
||||
|
@ -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;"
|
||||
|
@ -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…">
|
||||
|
@ -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.
|
||||
|
@ -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).");
|
||||
|
Loading…
Reference in New Issue
Block a user