Bug 675823 - Part 4: Make the setup flow more concise. r=rnewman

This commit is contained in:
Philipp von Weitershausen 2011-10-02 01:17:48 -07:00
parent 46c7d56717
commit ceaffbeaea
7 changed files with 61 additions and 115 deletions

View File

@ -49,13 +49,11 @@ const Cu = Components.utils;
const PAIR_PAGE = 0;
const INTRO_PAGE = 1;
const NEW_ACCOUNT_START_PAGE = 2;
const NEW_ACCOUNT_PP_PAGE = 3;
const NEW_ACCOUNT_CAPTCHA_PAGE = 4;
const EXISTING_ACCOUNT_CONNECT_PAGE = 5;
const EXISTING_ACCOUNT_LOGIN_PAGE = 6;
const OPTIONS_PAGE = 7;
const OPTIONS_CONFIRM_PAGE = 8;
const SETUP_SUCCESS_PAGE = 9;
const EXISTING_ACCOUNT_CONNECT_PAGE = 3;
const EXISTING_ACCOUNT_LOGIN_PAGE = 4;
const OPTIONS_PAGE = 5;
const OPTIONS_CONFIRM_PAGE = 6;
const SETUP_SUCCESS_PAGE = 7;
// Broader than we'd like, but after this changed from api-secure.recaptcha.net
// we had no choice. At least we only do this for the duration of setup.
@ -70,12 +68,16 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PlacesUtils.jsm");
Cu.import("resource://gre/modules/PluralForm.jsm");
function setVisibility(element, visible) {
element.style.visibility = visible ? "visible" : "hidden";
}
var gSyncSetup = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsIWebProgressListener,
Ci.nsISupportsWeakReference]),
haveCaptcha: true,
captchaBrowser: null,
wizard: null,
_disabledSites: [],
@ -159,7 +161,6 @@ var gSyncSetup = {
return false;
this._settingUpNew = true;
this.wizard.pageIndex = NEW_ACCOUNT_START_PAGE;
this.loadCaptcha();
},
useExistingAccount: function () {
@ -373,16 +374,8 @@ var gSyncSetup = {
onPasswordChange: function () {
let password = document.getElementById("weavePassword");
let valid, str;
if (password.value == document.getElementById("weavePassphrase").value) {
// xxxmpc - hack, sigh
valid = false;
errorString = Weave.Utils.getErrorString("change.password.pwSameAsRecoveryKey");
}
else {
let pwconfirm = document.getElementById("weavePasswordConfirm");
[valid, errorString] = gSyncUtils.validatePassword(password, pwconfirm);
}
let pwconfirm = document.getElementById("weavePasswordConfirm");
let [valid, errorString] = gSyncUtils.validatePassword(password, pwconfirm);
let feedback = document.getElementById("passwordFeedbackRow");
this._setFeedback(feedback, valid, errorString);
@ -391,13 +384,6 @@ var gSyncSetup = {
this.checkFields();
},
onPassphraseGenerate: function () {
let passphrase = Weave.Utils.generatePassphrase();
Weave.Service.passphrase = passphrase;
let el = document.getElementById("weavePassphrase");
el.value = Weave.Utils.hyphenatePassphrase(passphrase);
},
onPageShow: function() {
switch (this.wizard.pageIndex) {
case PAIR_PAGE:
@ -407,23 +393,15 @@ var gSyncSetup = {
this.pin1.focus();
break;
case INTRO_PAGE:
// We may not need the captcha in the Existing Account branch of the
// wizard. However, we want to preload it to avoid any flickering while
// the Create Account page is shown.
this.loadCaptcha();
this.wizard.getButton("next").hidden = true;
this.wizard.getButton("back").hidden = true;
this.wizard.getButton("extra1").hidden = true;
this.checkFields();
break;
case NEW_ACCOUNT_PP_PAGE:
document.getElementById("saveSyncKeyButton").focus();
let el = document.getElementById("weavePassphrase");
if (!el.value)
this.onPassphraseGenerate();
this.checkFields();
break;
case NEW_ACCOUNT_CAPTCHA_PAGE:
if (!this.haveCaptcha) {
gSyncSetup.wizard.advance();
}
break;
case NEW_ACCOUNT_START_PAGE:
this.wizard.getButton("extra1").hidden = false;
this.wizard.getButton("next").hidden = false;
@ -503,12 +481,16 @@ var gSyncSetup = {
case NEW_ACCOUNT_START_PAGE:
// If the user selects Next (e.g. by hitting enter) when we haven't
// executed the delayed checks yet, execute them immediately.
if (this._checkAccountTimer)
if (this._checkAccountTimer) {
this.checkAccount();
if (this._checkServerTimer)
}
if (this._checkServerTimer) {
this.checkServer();
return this.wizard.canAdvance;
case NEW_ACCOUNT_CAPTCHA_PAGE:
}
if (!this.wizard.canAdvance) {
return false;
}
let doc = this.captchaBrowser.contentDocument;
let getField = function getField(field) {
let node = doc.getElementById("recaptcha_" + field + "_field");
@ -521,7 +503,7 @@ var gSyncSetup = {
let label = image.nextSibling;
image.setAttribute("status", "active");
label.value = this._stringBundle.GetStringFromName("verifying.label");
feedback.hidden = false;
setVisibility(feedback, true);
let password = document.getElementById("weavePassword").value;
let email = Weave.Utils.normalizeAccount(
@ -535,6 +517,7 @@ var gSyncSetup = {
if (error == null) {
Weave.Service.account = email;
Weave.Service.password = password;
Weave.Service.passphrase = Weave.Utils.generatePassphrase();
this._handleNoScript(false);
this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
return false;
@ -823,7 +806,7 @@ var gSyncSetup = {
},
onServerCommand: function () {
document.getElementById("TOSRow").hidden = !this._usingMainServers;
setVisibility(document.getElementById("TOSRow"), this._usingMainServers);
let control = document.getElementById("server");
if (!this._usingMainServers) {
control.setAttribute("editable", "true");
@ -1077,9 +1060,12 @@ var gSyncSetup = {
},
loadCaptcha: function loadCaptcha() {
let captchaURI = Weave.Service.miscAPI + "captcha_html";
// First check for NoScript and whitelist the right sites.
this._handleNoScript(true);
this.captchaBrowser.loadURI(Weave.Service.miscAPI + "captcha_html");
if (this.captchaBrowser.currentURI.spec != captchaURI) {
this.captchaBrowser.loadURI(captchaURI);
}
},
onStateChange: function(webProgress, request, stateFlags, status) {
@ -1091,19 +1077,10 @@ var gSyncSetup = {
if ((stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) == 0)
return;
// If we didn't find the captcha, assume it's not needed and move on
if (request.QueryInterface(Ci.nsIHttpChannel).responseStatus == 404) {
this.haveCaptcha = false;
// Hide the browser just in case we end up displaying the captcha page
// due to a sign up error.
this.captchaBrowser.hidden = true;
if (this.wizard.pageIndex == NEW_ACCOUNT_CAPTCHA_PAGE) {
this.onWizardAdvance();
}
} else {
this.haveCaptcha = true;
this.captchaBrowser.hidden = false;
}
// If we didn't find a captcha, assume it's not needed and don't show it.
let responseStatus = request.QueryInterface(Ci.nsIHttpChannel).responseStatus;
setVisibility(this.captchaBrowser, responseStatus != 404);
//XXX TODO we should really log any responseStatus other than 200
},
onProgressChange: function() {},
onStatusChange: function() {},

View File

@ -122,22 +122,20 @@
<description style="padding: 0 7em;">
&setup.pickSetupType.description;
</description>
<spacer flex="1"/>
<spacer flex="3"/>
<button id="newAccount"
class="accountChoiceButton"
label="&button.createNewAccount.label;"
oncommand="gSyncSetup.startNewAccountSetup()"
align="center"/>
<spacer flex="3"/>
<spacer flex="1"/>
</vbox>
<separator class="groove"/>
<vbox align="center" flex="1">
<spacer flex="3"/>
<label value="&setup.haveAccount.label;" />
<spacer flex="1"/>
<button id="existingAccount"
class="accountChoiceButton"
label="&button.connect.label;"
label="&button.haveAccount.label;"
oncommand="gSyncSetup.useExistingAccount()"/>
<spacer flex="3"/>
</vbox>
@ -237,55 +235,18 @@
</row>
</rows>
</grid>
</wizardpage>
<wizardpage label="&setup.newRecoveryKeyPage.title.label;"
onextra1="gSyncSetup.onSyncOptions()"
onpageshow="gSyncSetup.onPageShow();">
<description>
&setup.newRecoveryKeyPage.description.label;
</description>
<spacer/>
<groupbox>
<label value="&recoveryKeyEntry.label;"
accesskey="&recoveryKeyEntry.accesskey;"
control="weavePassphrase"/>
<textbox id="weavePassphrase"
readonly="true"
onfocus="this.select();"/>
</groupbox>
<groupbox align="center">
<description>&recoveryKeyBackup.description;</description>
<hbox>
<button id="printSyncKeyButton"
label="&button.syncKeyBackup.print.label;"
accesskey="&button.syncKeyBackup.print.accesskey;"
oncommand="gSyncUtils.passphrasePrint('weavePassphrase');"/>
<button id="saveSyncKeyButton"
label="&button.syncKeyBackup.save.label;"
accesskey="&button.syncKeyBackup.save.accesskey;"
oncommand="gSyncUtils.passphraseSave('weavePassphrase');"/>
</hbox>
</groupbox>
</wizardpage>
<wizardpage label="&setup.captchaPage2.title.label;"
onextra1="gSyncSetup.onSyncOptions()"
onpageshow="gSyncSetup.onPageShow();">
<spacer flex="1"/>
<vbox flex="1" align="center">
<browser height="150"
width="450"
width="500"
id="captcha"
type="content"
disablehistory="true"/>
<spacer flex="1"/>
<hbox id="captchaFeedback" hidden="true">
<hbox id="captchaFeedback">
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
<spacer flex="3"/>
</vbox>
</wizardpage>

View File

@ -4,8 +4,7 @@
<!ENTITY setup.pickSetupType.description "Welcome, if you've never used &syncBrand.fullName.label; before, you will need to create a new account.">
<!ENTITY button.createNewAccount.label "Create a New Account">
<!ENTITY setup.haveAccount.label "I already have a &syncBrand.fullName.label; account.">
<!ENTITY button.connect.label "Connect">
<!ENTITY button.haveAccount.label "I Have an Account">
<!ENTITY setup.choicePage.title.label "Have you used &syncBrand.fullName.label; before?">
<!ENTITY setup.choicePage.new.label "I've never used &syncBrand.shortName.label; before">
@ -40,7 +39,7 @@
<!ENTITY setup.tosAgree3.label "">
<!ENTITY setup.tosAgree2.accesskey "">
<!-- New Account Page 2: Sync Key -->
<!-- My Recovery Key dialog -->
<!ENTITY setup.newRecoveryKeyPage.title.label "&brandShortName; Cares About Your Privacy">
<!ENTITY setup.newRecoveryKeyPage.description.label "To ensure your total privacy, all of your data is encrypted prior to being uploaded. The Recovery Key which is necessary to decrypt your data is not uploaded.">
<!ENTITY recoveryKeyEntry.label "Your Recovery Key">
@ -53,8 +52,6 @@
<!ENTITY button.syncKeyBackup.save.label "Save…">
<!ENTITY button.syncKeyBackup.save.accesskey "S">
<!-- New Account Page 3: Captcha -->
<!ENTITY setup.captchaPage2.title.label "Please Confirm You're Not a Robot">
<!-- Existing Account Page 1: Add Device (incl. Add a Device dialog strings) -->
<!ENTITY addDevice.title.label "Add a Device">
<!ENTITY addDevice.showMeHow.label "Show me how.">

View File

@ -1,7 +1,7 @@
wizard {
-moz-appearance: none;
width: 55em;
height: 42em;
height: 45em;
padding: 0;
background-color: Window;
}
@ -17,7 +17,7 @@ wizardpage {
-moz-box-pack: center;
-moz-box-align: center;
margin: 0;
padding: 0 8em;
padding: 0 6em;
background-color: Window;
}
@ -114,6 +114,10 @@ description > .text-link:focus {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
#captchaFeedback {
visibility: hidden;
}
#successPageIcon {
/* TODO replace this with a 128px version (bug 591122) */
list-style-image: url("chrome://browser/skin/sync-32.png");

View File

@ -1,7 +1,7 @@
wizard {
-moz-appearance: none;
width: 55em;
height: 42em;
height: 45em;
padding: 0;
background-color: Window;
}
@ -17,7 +17,7 @@ wizardpage {
-moz-box-pack: center;
-moz-box-align: center;
margin: 0;
padding: 0 8em;
padding: 0 6em;
background-color: Window;
}
@ -113,6 +113,10 @@ description > .text-link:focus {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
#captchaFeedback {
visibility: hidden;
}
#successPageIcon {
/* TODO replace this with a 128px version (bug 591122) */
list-style-image: url("chrome://browser/skin/sync-32.png");

View File

@ -1,7 +1,7 @@
wizard {
-moz-appearance: none;
width: 55em;
height: 42em;
height: 45em;
padding: 0;
background-color: Window;
}
@ -17,7 +17,7 @@ wizardpage {
-moz-box-pack: center;
-moz-box-align: center;
margin: 0;
padding: 0 8em;
padding: 0 6em;
background-color: Window;
}
@ -114,6 +114,10 @@ description > .text-link:focus {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
#captchaFeedback {
visibility: hidden;
}
#successPageIcon {
/* TODO replace this with a 128px version (bug 591122) */
list-style-image: url("chrome://browser/skin/sync-32.png");

View File

@ -15,7 +15,6 @@ weak-password = Use a stronger password
# this is the fallback, if we hit an error we didn't bother to localize
error.reason.unknown = Unknown error
change.password.pwSameAsRecoveryKey = Password can't match your Recovery Key
change.password.pwSameAsPassword = Password can't match current password
change.password.pwSameAsUsername = Password can't match your user name
change.password.pwSameAsEmail = Password can't match your email address