// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('options', function() {
const OptionsPage = options.OptionsPage;
// Variable to track if a captcha challenge was issued. If this gets set to
// true, it stays that way until we are told about successful login from
// the browser. This means subsequent errors (like invalid password) are
// rendered in the captcha state, which is basically identical except we
// don't show the top error blurb "Error Signing in" or the "Create
// account" link.
var captchaChallengeActive_ = false;
// True if the synced account uses a custom passphrase.
var usePassphrase_ = false;
/**
* SyncSetupOverlay class
* Encapsulated handling of the 'Sync Setup' overlay page.
* @class
*/
function SyncSetupOverlay() {
OptionsPage.call(this, 'syncSetup',
templateData.syncSetupOverlayTitle,
'sync-setup-overlay');
}
cr.addSingletonGetter(SyncSetupOverlay);
SyncSetupOverlay.prototype = {
__proto__: OptionsPage.prototype,
/**
* Initializes the page.
*/
initializePage: function() {
OptionsPage.prototype.initializePage.call(this);
var acct_text = $('gaia-account-text');
var translated_text = acct_text.textContent;
var posGoogle = translated_text.indexOf('Google');
if (posGoogle != -1) {
var ltr = templateData['textdirection'] == 'ltr';
var googleIsAtEndOfSentence = posGoogle != 0;
if (googleIsAtEndOfSentence == ltr) {
// We're in ltr and in the translation the word 'Google' is AFTER the
// word 'Account' OR we're in rtl and 'Google' is BEFORE 'Account'.
var logo_td = $('gaia-logo');
logo_td.parentNode.appendChild(logo_td);
}
acct_text.textContent = translated_text.replace('Google','');
}
var self = this;
$('gaia-login-form').onsubmit = function() {
self.sendCredentialsAndClose_();
return false;
};
$('chooseDataTypesForm').onsubmit = function() {
self.sendConfiguration_();
return false;
};
$('google-option').onchange = $('explicit-option').onchange = function() {
self.onRadioChange_();
};
$('choose-datatypes-cancel').onclick = $('sync-setup-cancel').onclick =
$('confirm-everything-cancel').onclick = function() {
self.closeOverlay_();
};
$('customize-link').onclick = function() {
self.showCustomizePage_(false);
};
$('confirm-everything-ok').onclick = function() {
self.sendConfiguration_();
};
$('use-default-link').onclick = function() {
self.showSyncEverythingPage_();
};
$('cancel-no-button').onclick = function() {
self.hideCancelWarning_();
return false;
};
$('cancel-yes-button').onclick = function() {
chrome.send('PassphraseCancel', ['']);
return false;
};
$('passphraseForm').onsubmit = $('passphrase-ok').onclick = function() {
self.sendPassphraseAndClose_();
return false;
};
$('passphrase-cancel').onclick = function() {
self.showCancelWarning_();
return false;
};
},
closeOverlay_: function() {
OptionsPage.closeOverlay();
},
/** @inheritDoc */
didShowPage: function() {
chrome.send('didShowPage');
},
/** @inheritDoc */
didClosePage: function() {
chrome.send('didClosePage');
},
showCancelWarning_: function() {
$('cancel-warning-box').hidden = false;
$('passphrase-ok').disabled = true;
$('passphrase-cancel').disabled = true;
$('cancel-no-button').focus();
},
sendPassphraseAndClose_: function() {
var f = $('passphraseForm');
var result = JSON.stringify({"passphrase": f.passphrase.value});
chrome.send("Passphrase", [result]);
},
getRadioCheckedValue_: function() {
var f = $('chooseDataTypesForm');
for (var i = 0; i < f.option.length; ++i) {
if (f.option[i].checked) {
return f.option[i].value;
}
}
return undefined;
},
// TODO(jhawkins): Remove this method.
switchToMode_: function(mode) {
if (mode == "google")
$('sync-custom-passphrase').hidden = true;
else if (mode =="explicit")
$('sync-custom-passphrase').hidden = false;
},
onRadioChange_: function() {
this.switchToMode_(this.getRadioCheckedValue_());
},
checkAllDataTypeCheckboxes_: function() {
var checkboxes = document.getElementsByName("dataTypeCheckbox");
for (var i = 0; i < checkboxes.length; i++) {
// Only check the visible ones (since there's no way to uncheck
// the invisible ones).
if (checkboxes[i].parentElement.className == "sync-item-show") {
checkboxes[i].checked = true;
}
}
},
setDataTypeCheckboxesEnabled_: function(enabled) {
var checkboxes = document.getElementsByName("dataTypeCheckbox");
var labels = document.getElementsByName("dataTypeLabel");
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].disabled = !enabled;
if (checkboxes[i].disabled) {
labels[i].className = "sync-label-inactive";
} else {
labels[i].className = "sync-label-active";
}
}
},
setCheckboxesToKeepEverythingSynced_: function(value) {
this.setDataTypeCheckboxesEnabled_(!value);
if (value)
this.checkAllDataTypeCheckboxes_();
},
// Returns true if at least one data type is enabled and no data types are
// checked. (If all data type checkboxes are disabled, it's because "keep
// everything synced" is checked.)
noDataTypesChecked_: function() {
var checkboxes = document.getElementsByName("dataTypeCheckbox");
var atLeastOneChecked = false;
var atLeastOneEnabled = false;
for (var i = 0; i < checkboxes.length; i++) {
if (!checkboxes[i].disabled &&
checkboxes[i].parentElement.className == "sync-item-show") {
atLeastOneEnabled = true;
if (checkboxes[i].checked) {
atLeastOneChecked = true;
}
}
}
return atLeastOneEnabled && !atLeastOneChecked;
},
checkPassphraseMatch_: function() {
var emptyError = $('emptyerror');
var mismatchError = $('mismatcherror');
emptyError.style.display = "none";
mismatchError.style.display = "none";
var f = $('chooseDataTypesForm');
if (this.getRadioCheckedValue_() != "explicit" || f.option[0].disabled)
return true;
var customPassphrase = $('custom-passphrase');
if (customPassphrase.value.length == 0) {
emptyError.style.display = "block";
return false;
}
var confirmPassphrase = $('confirm-passphrase');
if (confirmPassphrase.value != customPassphrase.value) {
mismatchError.style.display = "block";
return false;
}
return true;
},
hideCancelWarning_: function() {
$('cancel-warning-box').hidden = true;
$('passphrase-ok').disabled = false;
$('passphrase-cancel').disabled = false;
},
sendConfiguration_: function() {
// Trying to submit, so hide previous errors.
$('aborted-text').className = "sync-error-hide";
$('error-text').className = "sync-error-hide";
if (this.noDataTypesChecked_()) {
$('error-text').className = "sync-error-show";
return;
}
var f = $('chooseDataTypesForm');
if (!this.checkPassphraseMatch_())
return;
// Don't allow the user to tweak the settings once we send the
// configuration to the backend.
this.disableConfigureElements_();
var syncAll =
document.getElementById('sync-select-datatypes').selectedIndex == 0;
var customPassphrase = $('custom-passphrase');
// These values need to be kept in sync with where they are read in
// SyncSetupFlow::GetDataTypeChoiceData().
var result = JSON.stringify({
"keepEverythingSynced": syncAll,
"syncBookmarks": syncAll || f.bookmarksCheckbox.checked,
"syncPreferences": syncAll || f.preferencesCheckbox.checked,
"syncThemes": syncAll || f.themesCheckbox.checked,
"syncPasswords": syncAll || f.passwordsCheckbox.checked,
"syncAutofill": syncAll || f.autofillCheckbox.checked,
"syncExtensions": syncAll || f.extensionsCheckbox.checked,
"syncTypedUrls": syncAll || f.typedUrlsCheckbox.checked,
"syncApps": syncAll || f.appsCheckbox.checked,
"syncSessions": syncAll || f.sessionsCheckbox.checked,
"usePassphrase": (this.getRadioCheckedValue_() == 'explicit'),
"passphrase": customPassphrase.value
});
chrome.send("Configure", [result]);
},
/**
* Disables all input elements within the 'Customize Sync Preferences'
* screen. This is used to prohibit the user from changing the inputs after
* confirming the customized sync preferences.
* @private
*/
disableConfigureElements_: function() {
var configureElements =
$('customize-sync-preferences').querySelectorAll('input');
for (var i = 0; i < configureElements.length; i++)
configureElements[i].disabled = true;
},
setChooseDataTypesCheckboxes_: function(args) {
// If this frame is on top, the focus should be on it, so pressing enter
// submits this form.
if (args.iframeToShow == 'configure') {
$('choose-datatypes-ok').focus();
}
var datatypeSelect = document.getElementById('sync-select-datatypes');
datatypeSelect.selectedIndex = args.keepEverythingSynced ? 0 : 1;
$('bookmarksCheckbox').checked = args.syncBookmarks;
$('preferencesCheckbox').checked = args.syncPreferences;
$('themesCheckbox').checked = args.syncThemes;
if (args.passwordsRegistered) {
$('passwordsCheckbox').checked = args.syncPasswords;
$('passwordsItem').className = "sync-item-show";
} else {
$('passwordsItem').className = "sync-item-hide";
}
if (args.autofillRegistered) {
$('autofillCheckbox').checked = args.syncAutofill;
$('autofillItem').className = "sync-item-show";
} else {
$('autofillItem').className = "sync-item-hide";
}
if (args.extensionsRegistered) {
$('extensionsCheckbox').checked = args.syncExtensions;
$('extensionsItem').className = "sync-item-show";
} else {
$('extensionsItem').className = "sync-item-hide";
}
if (args.typedUrlsRegistered) {
$('typedUrlsCheckbox').checked = args.syncTypedUrls;
$('omniboxItem').className = "sync-item-show";
} else {
$('omniboxItem').className = "sync-item-hide";
}
if (args.appsRegistered) {
$('appsCheckbox').checked = args.syncApps;
$('appsItem').className = "sync-item-show";
} else {
$('appsItem').className = "sync-item-hide";
}
this.setCheckboxesToKeepEverythingSynced_(args.keepEverythingSynced);
if (args.sessionsRegistered) {
$('sessionsCheckbox').checked = args.syncSessions;
$('sessionsItem').className = "sync-item-show";
} else {
$('sessionsItem').className = "sync-item-hide";
}
},
setEncryptionCheckboxes_: function(args) {
if (args["usePassphrase"]) {
$('explicit-option').checked = true;
// The passphrase, once set, cannot be unset, but we show a reset link.
$('explicit-option').disabled = true;
$('google-option').disabled = true;
$('sync-custom-passphrase').hidden = true;
} else {
$('google-option').checked = true;
}
this.switchToMode_("");
},
setErrorState_: function(args) {
if (!args.was_aborted)
return;
$('aborted-text').className = "sync-error-show";
$('choose-datatypes-ok').disabled = true;
$('keepEverythingSyncedRadio').disabled = true;
$('chooseDataTypesRadio').disabled = true;
},
setCheckboxesAndErrors_: function(args) {
this.setChooseDataTypesCheckboxes_(args);
this.setEncryptionCheckboxes_(args);
this.setErrorState_(args);
},
// Called once, when this html/js is loaded.
showConfigure_: function(args) {
var datatypeSelect = document.getElementById('sync-select-datatypes');
var self = this;
datatypeSelect.onchange = function() {
var syncAll = this.selectedIndex == 0;
self.setCheckboxesToKeepEverythingSynced_(syncAll);
};
$('sync-setup-configure').classList.remove('hidden');
if (args) {
this.setCheckboxesAndErrors_(args);
// Whether to display the 'Sync everything' confirmation screen or the
// customize data types screen.
// TODO(jhawkins): Rename |keepEverythingSynced| to |syncAllDataTypes|.
var syncEverything = args['syncEverything'];
var syncAllDataTypes = args['keepEverythingSynced'];
this.usePassphrase_ = args['usePassphrase'];
if (syncEverything == false || syncAllDataTypes == false ||
this.usePassphrase_) {
this.showCustomizePage_(syncAllDataTypes);
} else {
this.showSyncEverythingPage_();
}
}
},
showSyncEverythingPage_: function() {
$('confirm-sync-preferences').hidden = false;
$('customize-sync-preferences').hidden = true;
// Reset the selection to 'Sync everything'.
$('sync-select-datatypes').selectedIndex = 0;
// The default state is to sync everything.
this.setCheckboxesToKeepEverythingSynced_(true);
// If the account is not synced with a custom passphrase, reset the
// passphrase radio when switching to the 'Sync everything' page.
if (!this.usePassphrase_) {
$('google-option').checked = true;
this.switchToMode_("google");
}
$('confirm-everything-ok').focus();
},
showCustomizePage_: function(syncEverything) {
document.getElementById('confirm-sync-preferences').hidden = true;
document.getElementById('customize-sync-preferences').hidden = false;
// If the user has selected the 'Customize' page on initial set up, it's
// likely he intends to change the data types. Select the
// 'Choose data types' option in this case.
var index = syncEverything ? 0 : 1;
document.getElementById('sync-select-datatypes').selectedIndex = index;
this.setDataTypeCheckboxesEnabled_(!syncEverything);
$('choose-datatypes-ok').focus();
},
showSyncSetupPage_: function(page, args) {
if (page == 'settingUp') {
this.setThrobbersVisible_(true);
return;
} else {
this.setThrobbersVisible_(false);
}
// Hide an existing visible overlay.
var overlay = $('sync-setup-overlay');
for (var i = 0; i < overlay.children.length; i++)
overlay.children[i].classList.add('hidden');
if (page == 'login')
this.showGaiaLogin_(args);
else if (page == 'configure')
this.showConfigure_(args);
else if (page == 'passphrase')
this.showPassphrase_(args);
else if (page == 'done')
this.closeOverlay_();
},
setThrobbersVisible_: function(visible) {
var throbbers = document.getElementsByClassName("throbber");
for (var i = 0; i < throbbers.length; i++)
throbbers[i].style.visibility = visible ? "visible" : "hidden";
},
showPassphrase_: function(args) {
$('sync-setup-passphrase').classList.remove('hidden');
$('passphraseRejectedBody').style.display = "none";
$('normalBody').style.display = "none";
$('incorrectPassphrase').style.display = "none";
if (args["passphrase_creation_rejected"]) {
$('passphraseRejectedBody').style.display = "block";
} else {
$('normalBody').style.display = "block";
}
if (args["passphrase_setting_rejected"]) {
$('incorrectPassphrase').style.display = "block";
}
$('passphrase').focus();
},
setElementDisplay_: function(id, display) {
var d = document.getElementById(id);
if (d)
d.style.display = display;
},
loginSetFocus_: function() {
var email = $('gaia-email');
var passwd = $('gaia-passwd');
if (email && (email.value == null || email.value == "")) {
email.focus();
} else if (passwd) {
passwd.focus();
}
},
showAccessCodeRequired_: function() {
this.setElementDisplay_("password-row", "none");
this.setElementDisplay_("email-row", "none");
$('create-account-cell').style.visibility = "hidden";
this.setElementDisplay_("access-code-label-row", "table-row");
this.setElementDisplay_("access-code-input-row", "table-row");
this.setElementDisplay_("access-code-help-row", "table-row");
document.getElementById('access-code').disabled = false;
},
showCaptcha_: function(args) {
this.captchaChallengeActive_ = true;
// The captcha takes up lots of space, so make room.
this.setElementDisplay_("top-blurb", "none");
this.setElementDisplay_("top-blurb-error", "none");
this.setElementDisplay_("create-account-div", "none");
document.getElementById('create-account-cell').height = 0;
// It's showtime for the captcha now.
this.setElementDisplay_("captcha-div", "block");
document.getElementById('gaia-email').disabled = true;
document.getElementById('gaia-passwd').disabled = false;
document.getElementById('captcha-value').disabled = false;
document.getElementById('captcha-wrapper').style.backgroundImage =
url(args.captchaUrl);
},
showGaiaLogin_: function(args) {
$('sync-setup-login').classList.remove('hidden');
document.getElementById('gaia-email').disabled = false;
document.getElementById('gaia-passwd').disabled = false;
var f = $('gaia-login-form');
var email = $('gaia-email');
var passwd = $('gaia-passwd');
if (f) {
if (args.user != undefined) {
if (email.value != args.user)
passwd.value = ""; // Reset the password field
email.value = args.user;
}
if (!args.editable_user) {
email.style.display = 'none';
var span = document.getElementById('email-readonly');
span.appendChild(document.createTextNode(email.value));
span.style.display = 'inline';
this.setElementDisplay_("create-account-div", "none");
}
f.accessCode.disabled = true;
}
if (1 == args.error) {
var access_code = document.getElementById('access-code');
if (access_code.value && access_code.value != "") {
this.setElementDisplay_("errormsg-0-access-code", 'block');
this.showAccessCodeRequired_();
} else {
this.setElementDisplay_("errormsg-1-password", 'table-row');
}
this.setBlurbError_(args.error_message);
} else if (3 == args.error) {
this.setElementDisplay_("errormsg-0-connection", 'table-row');
this.setBlurbError_(args.error_message);
} else if (4 == args.error) {
this.showCaptcha_(args);
} else if (8 == args.error) {
this.showAccessCodeRequired_();
} else if (args.error_message) {
this.setBlurbError_(args.error_message);
}
$('sign-in').disabled = false;
$('sign-in').value = templateData['signin'];
this.loginSetFocus_();
},
resetErrorVisibility_: function() {
this.setElementDisplay_("errormsg-0-email", 'none');
this.setElementDisplay_("errormsg-0-password", 'none');
this.setElementDisplay_("errormsg-1-password", 'none');
this.setElementDisplay_("errormsg-0-connection", 'none');
this.setElementDisplay_("errormsg-0-access-code", 'none');
},
setBlurbError_: function(error_message) {
if (this.captchaChallengeActive_)
return; // No blurb in captcha challenge mode.
if (error_message) {
document.getElementById('error-signing-in').style.display = 'none';
document.getElementById('error-custom').style.display = 'inline';
document.getElementById('error-custom').textContent = error_message;
} else {
document.getElementById('error-signing-in').style.display = 'inline';
document.getElementById('error-custom').style.display = 'none';
}
$('top-blurb-error').style.visibility = "visible";
document.getElementById('gaia-email').disabled = false;
document.getElementById('gaia-passwd').disabled = false;
},
setErrorVisibility_: function() {
this.resetErrorVisibility_();
var f = $('gaia-login-form');
var email = $('gaia-email');
var passwd = $('gaia-passwd');
if (null == email.value || "" == email.value) {
this.setElementDisplay_("errormsg-0-email", 'table-row');
this.setBlurbError_();
return false;
}
if (null == passwd.value || "" == passwd.value) {
this.setElementDisplay_("errormsg-0-password", 'table-row');
this.setBlurbError_();
return false;
}
if (!f.accessCode.disabled && (null == f.accessCode.value ||
"" == f.accessCode.value)) {
this.setElementDisplay_("errormsg-0-password", 'table-row');
return false;
}
return true;
},
sendCredentialsAndClose_: function() {
if (!this.setErrorVisibility_()) {
return false;
}
$('gaia-email').disabled = true;
$('gaia-passwd').disabled = true;
$('captcha-value').disabled = true;
$('access-code').disabled = true;
$('logging-in-throbber').style.visibility = "visible";
var f = $('gaia-login-form');
var email = $('gaia-email');
var passwd = $('gaia-passwd');
var result = JSON.stringify({"user" : email.value,
"pass" : passwd.value,
"captcha" : f.captchaValue.value,
"access_code" : f.accessCode.value});
$('sign-in').disabled = true;
chrome.send("SubmitAuth", [result]);
},
showGaiaSuccessAndClose_: function() {
$('sign-in').value = localStrings.getString('loginSuccess');
setTimeout(this.closeOverlay_, 1600);
},
showSuccessAndSettingUp_: function() {
$('sign-in').value = localStrings.getString('settingup');
},
/** @inheritDoc */
shouldClose: function() {
if (!$('cancel-warning-box').hidden) {
chrome.send('PassphraseCancel', ['']);
return true;
} else if (!$('sync-setup-passphrase').classList.contains('hidden')) {
// The Passphrase page is showing, and the use has pressed escape.
// Activate the cancel logic in this case.
this.showCancelWarning_();
return false;
}
return true;
},
};
SyncSetupOverlay.showSyncSetupPage = function(page, args) {
SyncSetupOverlay.getInstance().showSyncSetupPage_(page, args);
};
SyncSetupOverlay.showSuccessAndClose = function() {
SyncSetupOverlay.getInstance().showSuccessAndClose_();
};
SyncSetupOverlay.showSuccessAndSettingUp = function() {
SyncSetupOverlay.getInstance().showSuccessAndSettingUp_();
};
// Export
return {
SyncSetupOverlay: SyncSetupOverlay
};
});