1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/metro/base/content/flyoutpanels/SyncFlyoutPanel.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,367 @@ 1.4 +// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 +"use strict"; 1.9 + 1.10 +Components.utils.import("resource://gre/modules/Services.jsm"); 1.11 + 1.12 +let SyncFlyoutPanel = { 1.13 + init: function() { 1.14 + if (this._isInitialized) { 1.15 + Cu.reportError("Attempted to initialize SyncFlyoutPanel more than once"); 1.16 + return; 1.17 + } 1.18 + 1.19 + this._isInitialized = true; 1.20 + this._bundle = Services.strings.createBundle("chrome://browser/locale/sync.properties"); 1.21 + Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); 1.22 + let self = this; 1.23 + 1.24 + this._elements = {}; 1.25 + [ 1.26 + ['outer', 'sync-flyoutpanel'], 1.27 + ['preSetup', 'sync-presetup-container'], 1.28 + ['easySetup', 'sync-setup-container'], 1.29 + ['manualSetup', 'sync-manualsetup-container'], 1.30 + ['setupSuccess', 'sync-setupsuccess-container'], 1.31 + ['setupFailure', 'sync-setupfailure-container'], 1.32 + ['connected', 'sync-connected-container'], 1.33 + ['pairNewDevice', 'sync-pair-container'], 1.34 + ['pairSuccess', 'sync-pair-success-container'], 1.35 + ['setupCode1', 'sync-setup-code1'], 1.36 + ['setupCode2', 'sync-setup-code2'], 1.37 + ['setupCode3', 'sync-setup-code3'], 1.38 + ['setupThrobber', 'sync-setup-throbber'], 1.39 + ['account', 'sync-manualsetup-account'], 1.40 + ['password', 'sync-manualsetup-password'], 1.41 + ['syncKey', 'sync-manualsetup-syncKey'], 1.42 + ['manualSetupConnect', 'sync-manualsetup-connect'], 1.43 + ['manualSetupFailure', 'sync-manualsetup-failure'], 1.44 + ['connectedAccount', 'sync-connected-account'], 1.45 + ['deviceName', 'sync-connected-device'], 1.46 + ['lastSync', 'sync-connected-lastSynced'], 1.47 + ['connectedThrobber', 'sync-connected-throbber'], 1.48 + ['disconnectLink', 'sync-disconnect-label'], 1.49 + ['disconnectWarning', 'sync-disconnect-warning'], 1.50 + ['pairCode1', 'sync-pair-entry1'], 1.51 + ['pairCode2', 'sync-pair-entry2'], 1.52 + ['pairCode3', 'sync-pair-entry3'], 1.53 + ['pairButton', 'sync-pair-button'], 1.54 + ['pairFailureMessage', 'sync-pair-failure'], 1.55 + ].forEach(function (aContainer) { 1.56 + let [name, id] = aContainer; 1.57 + XPCOMUtils.defineLazyGetter(self._elements, name, function() { 1.58 + return document.getElementById(id); 1.59 + }); 1.60 + }); 1.61 + 1.62 + this._topmostElement = this._elements.outer; 1.63 + 1.64 + let xps = Components.classes["@mozilla.org/weave/service;1"] 1.65 + .getService(Components.interfaces.nsISupports) 1.66 + .wrappedJSObject; 1.67 + 1.68 + if (xps.ready) { 1.69 + this._onServiceReady(); 1.70 + } else { 1.71 + Services.obs.addObserver(this._onServiceReady.bind(this), 1.72 + "weave:service:ready", 1.73 + false); 1.74 + xps.ensureLoaded(); 1.75 + } 1.76 + }, 1.77 + 1.78 + _hide: function() { 1.79 + this._elements.outer.hide(); 1.80 + this.showInitialScreen(); 1.81 + }, 1.82 + 1.83 + _hideVisibleContainer: function() { 1.84 + if (this._currentlyVisibleContainer) { 1.85 + this._currentlyVisibleContainer.collapsed = true; 1.86 + delete this._currentlyVisibleContainer; 1.87 + delete this._onBackButton; 1.88 + } 1.89 + }, 1.90 + 1.91 + _onServiceReady: function(aEvent) { 1.92 + if (aEvent) { 1.93 + Services.obs.removeObserver(this._onServiceReady, "weave:service:ready"); 1.94 + } 1.95 + 1.96 + this.showInitialScreen(); 1.97 + Services.obs.addObserver(this._onSyncStart.bind(this), "weave:service:sync:start", false); 1.98 + Services.obs.addObserver(this._onSyncEnd.bind(this), "weave:ui:sync:finish", false); 1.99 + Services.obs.addObserver(this._onSyncEnd.bind(this), "weave:ui:sync:error", false); 1.100 + Weave.Service.scheduler.scheduleNextSync(10*1000); 1.101 + }, 1.102 + 1.103 + _onSyncStart: function() { 1.104 + this._isSyncing = true; 1.105 + this._updateConnectedPage(); 1.106 + }, 1.107 + 1.108 + _onSyncEnd: function() { 1.109 + this._isSyncing = false; 1.110 + this._updateConnectedPage(); 1.111 + }, 1.112 + 1.113 + showInitialScreen: function() { 1.114 + if (Weave.Status.login == Weave.LOGIN_SUCCEEDED) { 1.115 + this.showConnected(); 1.116 + } else { 1.117 + this.showPreSetup(); 1.118 + } 1.119 + }, 1.120 + 1.121 + abortEasySetup: function() { 1.122 + if (this._setupJpake) { 1.123 + this._setupJpake.abort(); 1.124 + } 1.125 + this._cleanUpEasySetup(); 1.126 + }, 1.127 + 1.128 + _cleanUpEasySetup: function() { 1.129 + this._elements.setupCode1.value = ""; 1.130 + this._elements.setupCode2.value = ""; 1.131 + this._elements.setupCode3.value = ""; 1.132 + delete this._setupJpake; 1.133 + this._elements.setupThrobber.collapsed = true; 1.134 + this._elements.setupThrobber.enabled = false; 1.135 + }, 1.136 + 1.137 + _updateConnectedPage: function() { 1.138 + // Show the day-of-week and time (HH:MM) of last sync 1.139 + let lastSync = Weave.Svc.Prefs.get("lastSync"); 1.140 + let syncDate = ''; 1.141 + if (lastSync != null) { 1.142 + syncDate = new Date(lastSync).toLocaleFormat("%A %I:%M %p"); 1.143 + } 1.144 + 1.145 + let device = Weave.Service.clientsEngine.localName; 1.146 + let account = Weave.Service.identity.account; 1.147 + this._elements.deviceName.textContent = 1.148 + this._bundle.formatStringFromName("sync.flyout.connected.device", 1.149 + [device], 1); 1.150 + this._elements.connectedAccount.textContent = 1.151 + this._bundle.formatStringFromName("sync.flyout.connected.account", 1.152 + [account], 1); 1.153 + this._elements.lastSync.textContent = 1.154 + this._bundle.formatStringFromName("sync.flyout.connected.lastSynced", 1.155 + [syncDate], 1); 1.156 + 1.157 + if (this._currentlyVisibleContainer == this._elements.connected 1.158 + && this._isSyncing) { 1.159 + this._elements.connectedThrobber.collapsed = false; 1.160 + this._elements.connectedThrobber.enabled = true; 1.161 + } else { 1.162 + this._elements.connectedThrobber.collapsed = true; 1.163 + this._elements.connectedThrobber.enabled = false; 1.164 + } 1.165 + }, 1.166 + 1.167 + showConnected: function() { 1.168 + // Reset state of the connected screen 1.169 + this._elements.disconnectWarning.collapsed = true; 1.170 + this._elements.disconnectLink.collapsed = false; 1.171 + 1.172 + this._updateConnectedPage(); 1.173 + this._showContainer(this._elements.connected); 1.174 + }, 1.175 + 1.176 + startEasySetup: function() { 1.177 + let self = this; 1.178 + 1.179 + this._showContainer(this._elements.easySetup); 1.180 + 1.181 + // Set up our back button to do the appropriate action 1.182 + this._onBackButton = function() { 1.183 + self.abortEasySetup(); 1.184 + self.showInitialScreen(); 1.185 + }; 1.186 + 1.187 + this._setupJpake = new Weave.JPAKEClient({ 1.188 + displayPIN: function displayPIN(aPin) { 1.189 + self._elements.setupCode1.value = aPin.slice(0, 4); 1.190 + self._elements.setupCode2.value = aPin.slice(4, 8); 1.191 + self._elements.setupCode3.value = aPin.slice(8); 1.192 + }, 1.193 + 1.194 + onPairingStart: function onPairingStart() { 1.195 + self._elements.setupThrobber.collapsed = false; 1.196 + self._elements.setupThrobber.enabled = true; 1.197 + }, 1.198 + 1.199 + onComplete: function onComplete(aCredentials) { 1.200 + Weave.Service.identity.account = aCredentials.account; 1.201 + Weave.Service.identity.basicPassword = aCredentials.password; 1.202 + Weave.Service.identity.syncKey = aCredentials.synckey; 1.203 + Weave.Service.serverURL = aCredentials.serverURL; 1.204 + Weave.Service.persistLogin(); 1.205 + Weave.Service.scheduler.scheduleNextSync(0); 1.206 + 1.207 + if (self._currentlyVisibleContainer == self._elements.easySetup) { 1.208 + self.showSetupSuccess(); 1.209 + } 1.210 + self._cleanUpEasySetup(); 1.211 + }, 1.212 + 1.213 + onAbort: function onAbort(aError) { 1.214 + if (aError == "jpake.error.userabort") { 1.215 + Services.obs.notifyObservers(null, "browser:sync:setup:userabort", ""); 1.216 + self._cleanUpEasySetup(); 1.217 + return; 1.218 + } else if (aError == "jpake.error.network") { 1.219 + Services.obs.notifyObservers(null, "browser:sync:setup:networkerror", ""); 1.220 + } 1.221 + 1.222 + if (self._currentlyVisibleContainer == self._elements.easySetup) { 1.223 + self.showSetupFailure(); 1.224 + self._cleanUpEasySetup(); 1.225 + } 1.226 + } 1.227 + }); 1.228 + 1.229 + this._setupJpake.receiveNoPIN(); 1.230 + }, 1.231 + 1.232 + _showContainer: function(aContainer) { 1.233 + this._hideVisibleContainer(); 1.234 + this._currentlyVisibleContainer = aContainer; 1.235 + this._currentlyVisibleContainer.collapsed = false; 1.236 + }, 1.237 + 1.238 + showSetupSuccess: function() { 1.239 + this._showContainer(this._elements.setupSuccess); 1.240 + this._onBackButton = this.showInitialScreen; 1.241 + }, 1.242 + 1.243 + showSetupFailure: function() { 1.244 + this._showContainer(this._elements.setupFailure); 1.245 + this._onBackButton = this.showInitialScreen; 1.246 + }, 1.247 + 1.248 + showPreSetup: function() { 1.249 + this._showContainer(this._elements.preSetup); 1.250 + delete this._onBackButton; 1.251 + }, 1.252 + 1.253 + showManualSetup: function() { 1.254 + this._showContainer(this._elements.manualSetup); 1.255 + this._onBackButton = this.showInitialScreen; 1.256 + 1.257 + this._elements.account.value = Weave.Service.identity.account; 1.258 + this._elements.password.value = Weave.Service.identity.basicPassword; 1.259 + this._elements.syncKey.value = 1.260 + Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey); 1.261 + this.updateManualSetupConnectButtonState(); 1.262 + }, 1.263 + 1.264 + updateManualSetupConnectButtonState: function() { 1.265 + this._elements.manualSetupConnect.disabled = !this._elements.account.value 1.266 + || !this._elements.password.value 1.267 + || !this._elements.syncKey.value; 1.268 + }, 1.269 + 1.270 + manualSetupConnect: function() { 1.271 + delete this._onBackButton; 1.272 + this._elements.manualSetupConnect.disabled = true; 1.273 + Weave.Service.identity.account = this._elements.account.value; 1.274 + Weave.Service.identity.basicPassword = this._elements.password.value; 1.275 + Weave.Service.identity.syncKey = Weave.Utils.normalizePassphrase(this._elements.syncKey.value); 1.276 + if (Weave.Service.login()) { 1.277 + Weave.Service.persistLogin(); 1.278 + if (this._currentlyVisibleContainer == this._elements.manualSetup) { 1.279 + this.showSetupSuccess(); 1.280 + } 1.281 + Weave.Service.scheduler.scheduleNextSync(0); 1.282 + } else { 1.283 + this._elements.manualSetupFailure.textContent = Weave.Utils.getErrorString(Weave.Status.login); 1.284 + this._elements.manualSetupFailure.collapsed = false; 1.285 + this.updateManualSetupConnectButtonState(); 1.286 + } 1.287 + }, 1.288 + 1.289 + onDisconnectLink: function() { 1.290 + this._elements.disconnectWarning.collapsed = false; 1.291 + this._elements.disconnectLink.collapsed = true; 1.292 + }, 1.293 + 1.294 + onDisconnectCancel: function() { 1.295 + this._elements.disconnectWarning.collapsed = true; 1.296 + this._elements.disconnectLink.collapsed = false; 1.297 + }, 1.298 + 1.299 + onDisconnectButton: function() { 1.300 + Weave.Service.startOver(); 1.301 + this.showInitialScreen(); 1.302 + }, 1.303 + 1.304 + onPairDeviceLink: function() { 1.305 + // Reset state 1.306 + this._elements.pairCode1.value = ""; 1.307 + this._elements.pairCode2.value = ""; 1.308 + this._elements.pairCode3.value = ""; 1.309 + this.updatePairButtonState(); 1.310 + this._elements.pairFailureMessage.collapsed = true; 1.311 + this._elements.pairNewDevice.collapsed = false; 1.312 + 1.313 + this._showContainer(this._elements.pairNewDevice); 1.314 + this._onBackButton = this.showInitialScreen; 1.315 + }, 1.316 + 1.317 + updatePairButtonState: function () { 1.318 + this._elements.pairButton.disabled = !this._elements.pairCode1.value 1.319 + || !this._elements.pairCode2.value 1.320 + || !this._elements.pairCode3.value; 1.321 + }, 1.322 + 1.323 + onCancelButton: function() { 1.324 + this.showInitialContainer(); 1.325 + }, 1.326 + 1.327 + onTryAgainButton: function() { 1.328 + this.startEasySetup(); 1.329 + }, 1.330 + 1.331 + onPairButton: function() { 1.332 + this._elements.pairButton.disabled = true; 1.333 + this._elements.pairFailureMessage.collapsed = true; 1.334 + let self = this; 1.335 + this._pairJpake = new Weave.JPAKEClient({ 1.336 + onPaired: function() { 1.337 + self._pairJpake.sendAndComplete({ 1.338 + account: Weave.Service.identity.account, 1.339 + password: Weave.Service.identity.basicPassword, 1.340 + synckey: Weave.Service.identity.syncKey, 1.341 + serverURL: Weave.Service.serverURL 1.342 + }); 1.343 + }, 1.344 + 1.345 + onComplete: function() { 1.346 + delete self._pairJpake; 1.347 + Weave.Service.persistLogin(); 1.348 + if (self._currentlyVisibleContainer == self._elements.pairNewDevice) { 1.349 + self._showContainer(self._elements.pairSuccess); 1.350 + } 1.351 + Weave.Service.scheduler.scheduleNextSync(Weave.Service.scheduler.activeInterval); 1.352 + }, 1.353 + 1.354 + onAbort: function(error) { 1.355 + delete self._pairJpake; 1.356 + if (error == Weave.JPAKE_ERROR_USERABORT) { 1.357 + return; 1.358 + } 1.359 + 1.360 + self._elements.pairFailureMessage.collapsed = false; 1.361 + self.updatePairButtonState(); 1.362 + } 1.363 + }); 1.364 + 1.365 + this._pairJpake.pairWithPIN(this._elements.pairCode1.value 1.366 + + this._elements.pairCode2.value 1.367 + + this._elements.pairCode3.value, 1.368 + false); 1.369 + }, 1.370 +};