mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
7057cfae6c
Notify remotetabs-list that a network error ocurred so that the 'loading' ui (i.e. the throbber) is hidden accordingly. Otherwise the user will get the impression that something is still happening after the error is shown.
560 lines
21 KiB
JavaScript
560 lines
21 KiB
JavaScript
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is Bookmarks sync code.
|
|
*
|
|
* The Initial Developer of the Original Code is Mozilla.
|
|
* Portions created by the Initial Developer are Copyright (C) 2007
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Mark Finkle <mfinkle@mozila.com>
|
|
* Matt Brubeck <mbrubeck@mozila.com>
|
|
* Jono DiCarlo <jdicarlo@mozilla.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
let WeaveGlue = {
|
|
setupData: null,
|
|
jpake: null,
|
|
|
|
init: function init() {
|
|
this._bundle = Services.strings.createBundle("chrome://browser/locale/sync.properties");
|
|
this._msg = document.getElementById("prefs-messages");
|
|
|
|
this._addListeners();
|
|
|
|
this.setupData = { account: "", password: "" , synckey: "", serverURL: "" };
|
|
|
|
let enableSync = Services.prefs.getBoolPref("browser.sync.enabled");
|
|
if (enableSync)
|
|
this._elements.connect.collapsed = false;
|
|
|
|
// Generating keypairs is expensive on mobile, so disable it
|
|
if (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED) {
|
|
if (enableSync) {
|
|
// Put the settings UI into a state of "connecting..." if we are going to auto-connect
|
|
this._elements.connect.firstChild.disabled = true;
|
|
this._elements.connect.setAttribute("title", this._bundle.GetStringFromName("connecting.label"));
|
|
|
|
try {
|
|
this._elements.device.value = Services.prefs.getCharPref("services.sync.client.name");
|
|
} catch(e) {}
|
|
}
|
|
} else if (Weave.Status.login != Weave.LOGIN_FAILED_NO_USERNAME) {
|
|
this.loadSetupData();
|
|
}
|
|
},
|
|
|
|
abortEasySetup: function abortEasySetup() {
|
|
document.getElementById("syncsetup-code1").value = "....";
|
|
document.getElementById("syncsetup-code2").value = "....";
|
|
document.getElementById("syncsetup-code3").value = "....";
|
|
if (!this.jpake)
|
|
return;
|
|
|
|
this.jpake.abort();
|
|
this.jpake = null;
|
|
},
|
|
|
|
_resetScrollPosition: function _resetScrollPosition() {
|
|
let scrollboxes = document.getElementsByClassName("syncsetup-scrollbox");
|
|
for (let i = 0; i < scrollboxes.length; i++) {
|
|
let sbo = scrollboxes[i].boxObject.QueryInterface(Ci.nsIScrollBoxObject);
|
|
try {
|
|
sbo.scrollTo(0, 0);
|
|
} catch(e) {}
|
|
}
|
|
},
|
|
|
|
open: function open() {
|
|
let container = document.getElementById("syncsetup-container");
|
|
if (!container.hidden)
|
|
return;
|
|
|
|
// Services.io.offline is lying to us, so we use the NetworkLinkService instead
|
|
let nls = Cc["@mozilla.org/network/network-link-service;1"].getService(Ci.nsINetworkLinkService);
|
|
if (!nls.isLinkUp) {
|
|
Services.obs.notifyObservers(null, "browser:sync:setup:networkerror", "");
|
|
Services.prompt.alert(window,
|
|
this._bundle.GetStringFromName("sync.setup.error.title"),
|
|
this._bundle.GetStringFromName("sync.setup.error.network"));
|
|
return;
|
|
}
|
|
|
|
// Clear up any previous JPAKE codes
|
|
this.abortEasySetup();
|
|
|
|
// Show the connect UI
|
|
container.hidden = false;
|
|
document.getElementById("syncsetup-simple").hidden = false;
|
|
document.getElementById("syncsetup-fallback").hidden = true;
|
|
|
|
BrowserUI.pushDialog(this);
|
|
|
|
let self = this;
|
|
this.jpake = new Weave.JPAKEClient({
|
|
displayPIN: function displayPIN(aPin) {
|
|
document.getElementById("syncsetup-code1").value = aPin.slice(0, 4);
|
|
document.getElementById("syncsetup-code2").value = aPin.slice(4, 8);
|
|
document.getElementById("syncsetup-code3").value = aPin.slice(8);
|
|
},
|
|
|
|
onComplete: function onComplete(aCredentials) {
|
|
self.jpake = null;
|
|
self.close();
|
|
self.setupData = aCredentials;
|
|
self.connect();
|
|
},
|
|
|
|
onAbort: function onAbort(aError) {
|
|
self.jpake = null;
|
|
|
|
if (aError == "jpake.error.userabort" || container.hidden) {
|
|
Services.obs.notifyObservers(null, "browser:sync:setup:userabort", "");
|
|
return;
|
|
}
|
|
|
|
// Automatically go to manual setup if we couldn't acquire a channel.
|
|
let brandShortName = Strings.brand.GetStringFromName("brandShortName");
|
|
let tryAgain = self._bundle.GetStringFromName("sync.setup.tryagain");
|
|
let manualSetup = self._bundle.GetStringFromName("sync.setup.manual");
|
|
let buttonFlags = Ci.nsIPrompt.BUTTON_POS_1_DEFAULT +
|
|
(Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) +
|
|
(Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1) +
|
|
(Ci.nsIPrompt.BUTTON_TITLE_CANCEL * Ci.nsIPrompt.BUTTON_POS_2);
|
|
|
|
let button = Services.prompt.confirmEx(window,
|
|
self._bundle.GetStringFromName("sync.setup.error.title"),
|
|
self._bundle.formatStringFromName("sync.setup.error.nodata", [brandShortName], 1),
|
|
buttonFlags, tryAgain, manualSetup, null, "", {});
|
|
switch (button) {
|
|
case 0:
|
|
// we have to build a new JPAKEClient here rather than reuse the old one
|
|
container.hidden = true;
|
|
self.open();
|
|
break;
|
|
case 1:
|
|
self.openManual();
|
|
break;
|
|
case 2:
|
|
default:
|
|
self.close();
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
this.jpake.receiveNoPIN();
|
|
},
|
|
|
|
openManual: function openManual() {
|
|
this.abortEasySetup();
|
|
|
|
// Reset the scroll since the previous page might have been scrolled
|
|
this._resetScrollPosition();
|
|
|
|
document.getElementById("syncsetup-simple").hidden = true;
|
|
document.getElementById("syncsetup-fallback").hidden = false;
|
|
|
|
// Push the current setup data into the UI
|
|
if (this.setupData && "account" in this.setupData) {
|
|
this._elements.account.value = this.setupData.account;
|
|
this._elements.password.value = this.setupData.password;
|
|
let pp = this.setupData.synckey;
|
|
if (Weave.Utils.isPassphrase(pp))
|
|
pp = Weave.Utils.hyphenatePassphrase(pp);
|
|
this._elements.synckey.value = pp;
|
|
if (this.setupData.serverURL && this.setupData.serverURL.length) {
|
|
this._elements.usecustomserver.checked = true;
|
|
this._elements.customserver.disabled = false;
|
|
this._elements.customserver.value = this.setupData.serverURL;
|
|
} else {
|
|
this._elements.usecustomserver.checked = false;
|
|
this._elements.customserver.disabled = true;
|
|
this._elements.customserver.value = "";
|
|
}
|
|
}
|
|
|
|
this.canConnect();
|
|
},
|
|
|
|
close: function close() {
|
|
if (this.jpake)
|
|
this.abortEasySetup();
|
|
|
|
// Reset the scroll since the previous page might have been scrolled
|
|
this._resetScrollPosition();
|
|
|
|
// Save current setup data
|
|
this.setupData = {
|
|
account: this._elements.account.value.trim(),
|
|
password: this._elements.password.value.trim(),
|
|
synckey: Weave.Utils.normalizePassphrase(this._elements.synckey.value.trim()),
|
|
serverURL: this._validateServer(this._elements.customserver.value.trim())
|
|
};
|
|
|
|
// Clear the UI so it's ready for next time
|
|
this._elements.account.value = "";
|
|
this._elements.password.value = "";
|
|
this._elements.synckey.value = "";
|
|
this._elements.usecustomserver.checked = false;
|
|
this._elements.customserver.disabled = true;
|
|
this._elements.customserver.value = "";
|
|
|
|
// Close the connect UI
|
|
document.getElementById("syncsetup-container").hidden = true;
|
|
BrowserUI.popDialog();
|
|
},
|
|
|
|
toggleCustomServer: function toggleCustomServer() {
|
|
let useCustomServer = this._elements.usecustomserver.checked;
|
|
this._elements.customserver.disabled = !useCustomServer;
|
|
if (!useCustomServer)
|
|
this._elements.customserver.value = "";
|
|
},
|
|
|
|
canConnect: function canConnect() {
|
|
let account = this._elements.account.value;
|
|
let password = this._elements.password.value;
|
|
let synckey = this._elements.synckey.value;
|
|
|
|
let disabled = !(account && password && synckey);
|
|
document.getElementById("syncsetup-button-connect").disabled = disabled;
|
|
},
|
|
|
|
showDetails: function showDetails() {
|
|
// Show the connect UI detail settings
|
|
let show = this._elements.sync.collapsed;
|
|
this._elements.details.checked = show;
|
|
this._elements.sync.collapsed = !show;
|
|
this._elements.device.collapsed = !show;
|
|
this._elements.disconnect.collapsed = !show;
|
|
},
|
|
|
|
toggleSyncEnabled: function toggleSyncEnabled() {
|
|
let enabled = this._elements.autosync.value;
|
|
if (enabled) {
|
|
// Attempt to go back online
|
|
if (this.setupData) {
|
|
if (this.setupData.serverURL && this.setupData.serverURL.length)
|
|
Weave.Service.serverURL = this.setupData.serverURL;
|
|
|
|
// We might still be in the middle of a sync from before Sync was disabled, so
|
|
// let's force the UI into a state that the Sync code feels comfortable
|
|
this.observe(null, "", "");
|
|
|
|
// Now try to re-connect. If successful, this will reset the UI into the
|
|
// correct state automatically.
|
|
Weave.Service.login(Weave.Service.username, this.setupData.password, this.setupData.synckey);
|
|
} else {
|
|
// We can't just go back online. We need to be setup again.
|
|
this._elements.connected.collapsed = true;
|
|
this._elements.connect.collapsed = false;
|
|
}
|
|
} else {
|
|
this._elements.connect.collapsed = true;
|
|
this._elements.connected.collapsed = true;
|
|
Weave.Service.logout();
|
|
}
|
|
|
|
// Close any 'Undo' notification, if one is present
|
|
let notification = this._msg.getNotificationWithValue("undo-disconnect");
|
|
if (notification)
|
|
notification.close();
|
|
},
|
|
|
|
connect: function connect(aSetupData) {
|
|
// Use setup data to pre-configure manual fields
|
|
if (aSetupData)
|
|
this.setupData = aSetupData;
|
|
|
|
// Cause the Sync system to reset internals if we seem to be switching accounts
|
|
if (this.setupData.account != Weave.Service.account)
|
|
Weave.Service.startOver();
|
|
|
|
// Remove any leftover connection error string
|
|
this._elements.connect.removeAttribute("desc");
|
|
|
|
// Reset the custom server URL, if we have one
|
|
if (this.setupData.serverURL && this.setupData.serverURL.length)
|
|
Weave.Service.serverURL = this.setupData.serverURL;
|
|
|
|
// Sync will use the account value and munge it into a username, as needed
|
|
Weave.Service.account = this.setupData.account;
|
|
Weave.Service.login(Weave.Service.username, this.setupData.password, this.setupData.synckey);
|
|
Weave.Service.persistLogin();
|
|
},
|
|
|
|
disconnect: function disconnect() {
|
|
// Save credentials for undo
|
|
let undoData = this.setupData;
|
|
|
|
// Remove all credentials
|
|
this.setupData = null;
|
|
Weave.Service.startOver();
|
|
|
|
let message = this._bundle.GetStringFromName("notificationDisconnect.label");
|
|
let button = this._bundle.GetStringFromName("notificationDisconnect.button");
|
|
let buttons = [ {
|
|
label: button,
|
|
accessKey: "",
|
|
callback: function() { WeaveGlue.connect(undoData); }
|
|
} ];
|
|
this.showMessage(message, "undo-disconnect", buttons);
|
|
|
|
// Hide the notification when the panel is changed or closed.
|
|
let panel = document.getElementById("prefs-container");
|
|
panel.addEventListener("ToolPanelHidden", function onHide(aEvent) {
|
|
panel.removeEventListener(aEvent.type, onHide, false);
|
|
let notification = WeaveGlue._msg.getNotificationWithValue("undo-disconnect");
|
|
if (notification)
|
|
notification.close();
|
|
}, false);
|
|
|
|
Weave.Service.logout();
|
|
},
|
|
|
|
sync: function sync() {
|
|
Weave.Service.sync();
|
|
},
|
|
|
|
_addListeners: function _addListeners() {
|
|
let topics = ["weave:service:sync:start", "weave:service:sync:finish",
|
|
"weave:service:sync:error", "weave:service:login:start",
|
|
"weave:service:login:finish", "weave:service:login:error",
|
|
"weave:service:logout:finish"];
|
|
|
|
// For each topic, add WeaveGlue the observer
|
|
topics.forEach(function(topic) {
|
|
Services.obs.addObserver(WeaveGlue, topic, false);
|
|
});
|
|
|
|
// Remove them on unload
|
|
addEventListener("unload", function() {
|
|
topics.forEach(function(topic) {
|
|
Services.obs.removeObserver(WeaveGlue, topic, false);
|
|
});
|
|
}, false);
|
|
},
|
|
|
|
get _elements() {
|
|
// Do a quick test to see if the options exist yet
|
|
let syncButton = document.getElementById("sync-syncButton");
|
|
if (syncButton == null)
|
|
return null;
|
|
|
|
// Get all the setting nodes from the add-ons display
|
|
let elements = {};
|
|
let setupids = ["account", "password", "synckey", "usecustomserver", "customserver"];
|
|
setupids.forEach(function(id) {
|
|
elements[id] = document.getElementById("syncsetup-" + id);
|
|
});
|
|
|
|
let settingids = ["device", "connect", "connected", "disconnect", "sync", "autosync", "details"];
|
|
settingids.forEach(function(id) {
|
|
elements[id] = document.getElementById("sync-" + id);
|
|
});
|
|
|
|
// Replace the getter with the collection of settings
|
|
delete this._elements;
|
|
return this._elements = elements;
|
|
},
|
|
|
|
observe: function observe(aSubject, aTopic, aData) {
|
|
// Make sure we're online when connecting/syncing
|
|
Util.forceOnline();
|
|
|
|
// Can't do anything before settings are loaded
|
|
if (this._elements == null)
|
|
return;
|
|
|
|
// Make some aliases
|
|
let connect = this._elements.connect;
|
|
let connected = this._elements.connected;
|
|
let autosync = this._elements.autosync;
|
|
let details = this._elements.details;
|
|
let device = this._elements.device;
|
|
let disconnect = this._elements.disconnect;
|
|
let sync = this._elements.sync;
|
|
|
|
let syncEnabled = autosync.value;
|
|
let loggedIn = Weave.Service.isLoggedIn;
|
|
|
|
// Sync may successfully log in after it was temporarily disabled by a
|
|
// canceled master password entry. If so, then re-enable it.
|
|
if (loggedIn && !syncEnabled)
|
|
syncEnabled = autosync.value = true;
|
|
|
|
// If Sync is not enabled, hide the connection row visibility
|
|
if (syncEnabled) {
|
|
connect.collapsed = loggedIn;
|
|
connected.collapsed = !loggedIn;
|
|
} else {
|
|
connect.collapsed = true;
|
|
connected.collapsed = true;
|
|
}
|
|
|
|
if (!loggedIn) {
|
|
connect.setAttribute("title", this._bundle.GetStringFromName("notconnected.label"));
|
|
connect.firstChild.disabled = false;
|
|
details.checked = false;
|
|
sync.collapsed = true;
|
|
device.collapsed = true;
|
|
disconnect.collapsed = true;
|
|
}
|
|
|
|
// Check the lock on a timeout because it's set just after notifying
|
|
setTimeout(function(self) {
|
|
// Prevent certain actions when the service is locked
|
|
if (Weave.Service.locked) {
|
|
connect.firstChild.disabled = true;
|
|
sync.firstChild.disabled = true;
|
|
|
|
if (aTopic == "weave:service:login:start")
|
|
connect.setAttribute("title", self._bundle.GetStringFromName("connecting.label"));
|
|
|
|
if (aTopic == "weave:service:sync:start")
|
|
sync.setAttribute("title", self._bundle.GetStringFromName("lastSyncInProgress2.label"));
|
|
} else {
|
|
connect.firstChild.disabled = false;
|
|
sync.firstChild.disabled = false;
|
|
}
|
|
}, 0, this);
|
|
|
|
// Dynamically generate some strings
|
|
let accountStr = this._bundle.formatStringFromName("account.label", [Weave.Service.account], 1);
|
|
disconnect.setAttribute("title", accountStr);
|
|
|
|
// Show the day-of-week and time (HH:MM) of last sync
|
|
let lastSync = Weave.Svc.Prefs.get("lastSync");
|
|
if (lastSync != null) {
|
|
let syncDate = new Date(lastSync).toLocaleFormat("%a %R");
|
|
let dateStr = this._bundle.formatStringFromName("lastSync2.label", [syncDate], 1);
|
|
sync.setAttribute("title", dateStr);
|
|
}
|
|
|
|
// Show what went wrong with login if necessary
|
|
if (aTopic == "weave:service:login:error") {
|
|
if (Weave.Status.login == "service.master_password_locked") {
|
|
// Disable sync temporarily. Sync will try again after a set interval,
|
|
// or if the user presses the button to enable it again.
|
|
autosync.value = false;
|
|
this.toggleSyncEnabled();
|
|
} else {
|
|
connect.setAttribute("desc", Weave.Utils.getErrorString(Weave.Status.login));
|
|
}
|
|
} else {
|
|
connect.removeAttribute("desc");
|
|
}
|
|
|
|
// Init the setup data if we just logged in
|
|
if (!this.setupData && aTopic == "weave:service:login:finish")
|
|
this.loadSetupData();
|
|
|
|
// Check for a storage format update, update the user and load the Sync update page
|
|
if (aTopic =="weave:service:sync:error") {
|
|
let clientOutdated = false, remoteOutdated = false;
|
|
if (Weave.Status.sync == Weave.VERSION_OUT_OF_DATE) {
|
|
clientOutdated = true;
|
|
} else if (Weave.Status.sync == Weave.DESKTOP_VERSION_OUT_OF_DATE) {
|
|
remoteOutdated = true;
|
|
} else if (Weave.Status.service == Weave.SYNC_FAILED_PARTIAL) {
|
|
// Some engines failed, check for per-engine compat
|
|
for (let [engine, reason] in Iterator(Weave.Status.engines)) {
|
|
clientOutdated = clientOutdated || reason == Weave.VERSION_OUT_OF_DATE;
|
|
remoteOutdated = remoteOutdated || reason == Weave.DESKTOP_VERSION_OUT_OF_DATE;
|
|
}
|
|
}
|
|
|
|
if (clientOutdated || remoteOutdated) {
|
|
let brand = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
|
let brandName = brand.GetStringFromName("brandShortName");
|
|
|
|
let type = clientOutdated ? "client" : "remote";
|
|
let message = this._bundle.GetStringFromName("sync.update." + type);
|
|
message = message.replace("#1", brandName);
|
|
message = message.replace("#2", Services.appinfo.version);
|
|
let title = this._bundle.GetStringFromName("sync.update.title")
|
|
let button = this._bundle.GetStringFromName("sync.update.button")
|
|
let close = this._bundle.GetStringFromName("sync.update.close")
|
|
|
|
let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING +
|
|
Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_IS_STRING;
|
|
let choice = Services.prompt.confirmEx(window, title, message, flags, button, close, null, null, {});
|
|
if (choice == 0)
|
|
Browser.addTab("https://services.mozilla.com/update/", true, Browser.selectedTab);
|
|
}
|
|
}
|
|
|
|
device.value = Weave.Clients.localName || "";
|
|
},
|
|
|
|
changeName: function changeName(aInput) {
|
|
// Make sure to update to a modified name, e.g., empty-string -> default
|
|
Weave.Clients.localName = aInput.value;
|
|
aInput.value = Weave.Clients.localName;
|
|
},
|
|
|
|
showMessage: function showMessage(aMsg, aValue, aButtons) {
|
|
let notification = this._msg.getNotificationWithValue(aValue);
|
|
if (notification)
|
|
return;
|
|
|
|
this._msg.appendNotification(aMsg, aValue, "", this._msg.PRIORITY_WARNING_LOW, aButtons);
|
|
},
|
|
|
|
_validateServer: function _validateServer(aURL) {
|
|
let uri = Weave.Utils.makeURI(aURL);
|
|
|
|
if (!uri && aURL)
|
|
uri = Weave.Utils.makeURI("https://" + aURL);
|
|
|
|
if (!uri)
|
|
return "";
|
|
return uri.spec;
|
|
},
|
|
|
|
openTutorial: function _openTutorial() {
|
|
WeaveGlue.close();
|
|
|
|
let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
|
|
let url = formatter.formatURLPref("app.sync.tutorialURL");
|
|
BrowserUI.newTab(url, Browser.selectedTab);
|
|
},
|
|
|
|
loadSetupData: function _loadSetupData() {
|
|
this.setupData = {};
|
|
this.setupData.account = Weave.Service.account || "";
|
|
this.setupData.password = Weave.Service.password || "";
|
|
this.setupData.synckey = Weave.Service.passphrase || "";
|
|
|
|
let serverURL = Weave.Service.serverURL;
|
|
let defaultPrefs = Services.prefs.getDefaultBranch(null);
|
|
if (serverURL == defaultPrefs.getCharPref("services.sync.serverURL"))
|
|
serverURL = "";
|
|
this.setupData.serverURL = serverURL;
|
|
}
|
|
};
|