// Copyright (c) 2012 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() {
var OptionsPage = options.OptionsPage;
var ArrayDataModel = cr.ui.ArrayDataModel;
var RepeatingButton = cr.ui.RepeatingButton;
//
// BrowserOptions class
// Encapsulated handling of browser options page.
//
function BrowserOptions() {
OptionsPage.call(this, 'settings', templateData.settingsTitle,
'settings');
}
cr.addSingletonGetter(BrowserOptions);
BrowserOptions.prototype = {
__proto__: options.OptionsPage.prototype,
// State variables.
syncSetupCompleted: false,
showHomeButton_: false,
homePageIsNtp_: false,
/**
* An autocomplete list that can be attached to the home page URL text field
* during editing.
* @type {HTMLElement}
* @private
*/
autocompleteList_: null,
/**
* The cached value of the instant.confirm_dialog_shown preference.
* @type {bool}
* @private
*/
instantConfirmDialogShown_: false,
/**
* @inheritDoc
*/
initializePage: function() {
OptionsPage.prototype.initializePage.call(this);
var self = this;
window.addEventListener('message', this.handleWindowMessage_.bind(this));
$('advanced-settings-expander').onclick =
this.toggleAdvancedSettings_.bind(this);
// Sync (Sign in) section.
this.updateSyncState_(templateData.syncData);
$('sync-action-link').onclick = function(event) {
SyncSetupOverlay.showErrorUI();
};
$('start-stop-sync').onclick = function(event) {
if (self.syncSetupCompleted)
SyncSetupOverlay.showStopSyncingUI();
else
SyncSetupOverlay.showSetupUI();
};
$('customize-sync').onclick = function(event) {
SyncSetupOverlay.showSetupUI();
};
// Internet connection section (ChromeOS only).
if (cr.isChromeOS) {
$('internet-options-button').onclick = function(event) {
OptionsPage.navigateToPage('internet');
chrome.send('coreOptionsUserMetricsAction',
['Options_InternetOptions']);
};
}
// On Startup section.
var startupSetPagesLink = $('startup-set-pages');
const showPagesValue = Number($('startup-show-pages').value);
Preferences.getInstance().addEventListener('session.restore_on_startup',
function(event) {
startupSetPagesLink.disabled = event.value['disabled'] &&
event.value['value'] != showPagesValue;
});
startupSetPagesLink.onclick = function() {
OptionsPage.navigateToPage('startup');
};
this.sessionRestoreEnabled_ = templateData.enable_restore_session_state;
if (this.sessionRestoreEnabled_) {
$('old-startup-last-text').hidden = true;
$('new-startup-last-text').hidden = false;
}
// Appearance section.
$('home-page-select').addEventListener(
'change', this.onHomePageSelectChange_.bind(this));
['browser.show_home_button',
'homepage',
'homepage_is_newtabpage'].forEach(function(pref) {
Preferences.getInstance().addEventListener(
pref,
self.onHomePagePrefChanged_.bind(self));
});
$('themes-gallery').onclick = function(event) {
window.open(localStrings.getString('themesGalleryURL'));
};
$('themes-reset').onclick = function(event) {
chrome.send('themesReset');
};
// Device section (ChromeOS only).
if (cr.isChromeOS) {
$('keyboard-settings-button').onclick = function(evt) {
OptionsPage.navigateToPage('keyboard-overlay');
};
$('pointer-settings-button').onclick = function(evt) {
OptionsPage.navigateToPage('pointer-overlay');
};
this.initBrightnessButton_('brightness-decrease-button',
'decreaseScreenBrightness');
this.initBrightnessButton_('brightness-increase-button',
'increaseScreenBrightness');
}
// Search section.
$('manage-default-search-engines').onclick = function(event) {
OptionsPage.navigateToPage('searchEngines');
chrome.send('coreOptionsUserMetricsAction',
['Options_ManageSearchEngines']);
};
$('default-search-engine').addEventListener('change',
this.setDefaultSearchEngine_);
$('instant-enabled-control').customChangeHandler = function(event) {
if (this.checked) {
if (self.instantConfirmDialogShown_)
chrome.send('enableInstant');
else
OptionsPage.navigateToPage('instantConfirm');
} else {
chrome.send('disableInstant');
}
return true;
};
$('instant-field-trial-control').onchange = function(evt) {
this.checked = true;
chrome.send('disableInstant');
};
Preferences.getInstance().addEventListener('instant.confirm_dialog_shown',
this.onInstantConfirmDialogShownChanged_.bind(this));
Preferences.getInstance().addEventListener('instant.enabled',
this.onInstantEnabledChanged_.bind(this));
Preferences.getInstance().addEventListener(
'session.restore_on_startup',
this.onSessionRestoreSelectedChanged_.bind(this));
Preferences.getInstance().addEventListener(
'restore_session_state.dialog_shown',
this.onSessionRestoreDialogShownChanged_.bind(this));
// Text fields may change widths when the window changes size, so make
// sure the suggestion list stays in sync.
window.addEventListener('resize', function() {
self.autocompleteList_.syncWidthToInput();
});
var suggestionList = new cr.ui.AutocompleteList();
suggestionList.autoExpands = true;
suggestionList.suggestionUpdateRequestCallback =
this.requestAutocompleteSuggestions_.bind(this);
$('main-content').appendChild(suggestionList);
this.autocompleteList_ = suggestionList;
// Users section.
var profilesList = $('profiles-list');
options.browser_options.ProfileList.decorate(profilesList);
profilesList.autoExpands = true;
profilesList.addEventListener('change',
this.setProfileViewButtonsStatus_);
$('profiles-create').onclick = function(event) {
chrome.send('createProfile');
};
$('profiles-manage').onclick = function(event) {
var selectedProfile = self.getSelectedProfileItem_();
if (selectedProfile)
ManageProfileOverlay.showManageDialog(selectedProfile);
};
$('profiles-delete').onclick = function(event) {
var selectedProfile = self.getSelectedProfileItem_();
if (selectedProfile)
ManageProfileOverlay.showDeleteDialog(selectedProfile);
};
if (cr.isChromeOS) {
// Username (canonical email) of the currently logged in user or
// |kGuestUser| if a guest session is active.
this.username_ = localStrings.getString('username');
this.updateAccountPicture_();
if (cr.commandLine && cr.commandLine.options['--bwsi']) {
// Disable the screen lock checkbox in guest mode.
$('enable-screen-lock').disabled = true;
// Hide the startup section in Guest mode.
$('startup-section').hidden = true;
} else {
$('account-picture-wrapper').onclick = function(event) {
OptionsPage.navigateToPage('changePicture');
};
}
$('manage-accounts-button').onclick = function(event) {
OptionsPage.navigateToPage('accounts');
chrome.send('coreOptionsUserMetricsAction',
['Options_ManageAccounts']);
};
} else {
$('import-data').onclick = function(event) {
// Make sure that any previous import success message is hidden, and
// we're showing the UI to import further data.
$('import-data-configure').hidden = false;
$('import-data-success').hidden = true;
OptionsPage.navigateToPage('importData');
chrome.send('coreOptionsUserMetricsAction', ['Import_ShowDlg']);
};
if ($('themes-GTK-button')) {
$('themes-GTK-button').onclick = function(event) {
chrome.send('themesSetGTK');
};
}
}
// Default browser section.
if (!cr.isChromeOS) {
$('set-as-default-browser').onclick = function(event) {
chrome.send('becomeDefaultBrowser');
};
$('auto-launch').onclick = this.handleAutoLaunchChanged_;
}
// Date and time section (CrOS only).
if (cr.isChromeOS && AccountsOptions.loggedInAsGuest()) {
// Disable time-related settings if we're not logged in as a real user.
$('timezone-select').disabled = true;
$('use-24hour-clock').disabled = true;
}
// Privacy section.
$('privacyContentSettingsButton').onclick = function(event) {
OptionsPage.navigateToPage('content');
OptionsPage.showTab($('cookies-nav-tab'));
chrome.send('coreOptionsUserMetricsAction',
['Options_ContentSettings']);
};
$('privacyClearDataButton').onclick = function(event) {
OptionsPage.navigateToPage('clearBrowserData');
chrome.send('coreOptionsUserMetricsAction', ['Options_ClearData']);
};
// 'metricsReportingEnabled' element is only present on Chrome branded
// builds.
if ($('metricsReportingEnabled')) {
$('metricsReportingEnabled').onclick = function(event) {
chrome.send('metricsReportingCheckboxAction',
[String(event.target.checked)]);
};
}
// Bluetooth (CrOS only).
if (cr.isChromeOS) {
options.system.bluetooth.BluetoothDeviceList.decorate(
$('bluetooth-paired-devices-list'));
$('bluetooth-add-device').onclick =
this.handleAddBluetoothDevice_.bind(this);
$('enable-bluetooth').onchange = function(event) {
var state = $('enable-bluetooth').checked;
chrome.send('bluetoothEnableChange', [Boolean(state)]);
};
$('bluetooth-reconnect-device').onclick = function(event) {
var device = $('bluetooth-paired-devices-list').selectedItem;
var address = device.address;
chrome.send('updateBluetoothDevice', [address, 'connect']);
OptionsPage.closeOverlay();
};
$('bluetooth-reconnect-device').onmousedown = function(event) {
// Prevent 'blur' event, which would reset the list selection,
// thereby disabling the apply button.
event.preventDefault();
};
$('bluetooth-paired-devices-list').addEventListener('change',
function() {
var item = $('bluetooth-paired-devices-list').selectedItem;
var disabled = !item || !item.paired || item.connected;
$('bluetooth-reconnect-device').disabled = disabled;
});
}
// Passwords and Forms section.
$('autofill-settings').onclick = function(event) {
OptionsPage.navigateToPage('autofill');
chrome.send('coreOptionsUserMetricsAction',
['Options_ShowAutofillSettings']);
};
$('manage-passwords').onclick = function(event) {
OptionsPage.navigateToPage('passwords');
OptionsPage.showTab($('passwords-nav-tab'));
chrome.send('coreOptionsUserMetricsAction',
['Options_ShowPasswordManager']);
};
if (this.guestModeActive_()) {
// Disable and turn off Autofill in guest mode.
var autofillEnabled = $('autofill-enabled');
autofillEnabled.disabled = true;
autofillEnabled.checked = false;
cr.dispatchSimpleEvent(autofillEnabled, 'change');
$('autofill-settings').disabled = true;
// Disable and turn off Password Manager in guest mode.
var passwordManagerEnabled = $('password-manager-enabled');
passwordManagerEnabled.disabled = true;
passwordManagerEnabled.checked = false;
cr.dispatchSimpleEvent(passwordManagerEnabled, 'change');
$('manage-passwords').disabled = true;
// Hide the entire section on ChromeOS
if (cr.isChromeOS)
$('passwords-and-autofill-section').hidden = true;
}
$('mac-passwords-warning').hidden =
!(localStrings.getString('macPasswordsWarning'));
// Network section.
if (!cr.isChromeOS) {
$('proxiesConfigureButton').onclick = function(event) {
chrome.send('showNetworkProxySettings');
};
}
// Web Content section.
$('fontSettingsCustomizeFontsButton').onclick = function(event) {
OptionsPage.navigateToPage('fonts');
chrome.send('coreOptionsUserMetricsAction', ['Options_FontSettings']);
};
$('defaultFontSize').onchange = function(event) {
var value = event.target.options[event.target.selectedIndex].value;
Preferences.setIntegerPref(
'webkit.webprefs.global.default_fixed_font_size',
value - OptionsPage.SIZE_DIFFERENCE_FIXED_STANDARD, '');
chrome.send('defaultFontSizeAction', [String(value)]);
};
$('defaultZoomFactor').onchange = function(event) {
chrome.send('defaultZoomFactorAction',
[String(event.target.options[event.target.selectedIndex].value)]);
};
// Languages section.
$('language-button').onclick = function(event) {
OptionsPage.navigateToPage('languages');
chrome.send('coreOptionsUserMetricsAction',
['Options_LanuageAndSpellCheckSettings']);
};
// Downloads section.
if (!cr.isChromeOS) {
$('downloadLocationChangeButton').onclick = function(event) {
chrome.send('selectDownloadLocation');
};
// This text field is always disabled. Setting ".disabled = true" isn't
// enough, since a policy can disable it but shouldn't re-enable when
// it is removed.
$('downloadLocationPath').setDisabled('readonly', true);
$('autoOpenFileTypesResetToDefault').onclick = function(event) {
chrome.send('autoOpenFileTypesAction');
};
}
// HTTPS/SSL section.
if (cr.isWindows || cr.isMac) {
$('certificatesManageButton').onclick = function(event) {
chrome.send('showManageSSLCertificates');
};
} else {
$('certificatesManageButton').onclick = function(event) {
OptionsPage.navigateToPage('certificates');
chrome.send('coreOptionsUserMetricsAction',
['Options_ManageSSLCertificates']);
};
}
$('sslCheckRevocation').onclick = function(event) {
chrome.send('checkRevocationCheckboxAction',
[String($('sslCheckRevocation').checked)]);
};
// Cloud Print section.
// 'cloudPrintProxyEnabled' is true for Chrome branded builds on
// certain platforms, or could be enabled by a lab.
if (!cr.isChromeOS) {
$('cloudPrintConnectorSetupButton').onclick = function(event) {
if ($('cloudPrintManageButton').style.display == 'none') {
// Disable the button, set it's text to the intermediate state.
$('cloudPrintConnectorSetupButton').textContent =
localStrings.getString('cloudPrintConnectorEnablingButton');
$('cloudPrintConnectorSetupButton').disabled = true;
chrome.send('showCloudPrintSetupDialog');
} else {
chrome.send('disableCloudPrintConnector');
}
};
}
$('cloudPrintManageButton').onclick = function(event) {
chrome.send('showCloudPrintManagePage');
};
// Accessibility section (CrOS only).
if (cr.isChromeOS) {
$('accessibility-spoken-feedback-check').onchange = function(event) {
chrome.send('spokenFeedbackChange',
[$('accessibility-spoken-feedback-check').checked]);
};
}
// Background mode section.
if ($('backgroundModeCheckbox')) {
$('backgroundModeCheckbox').onclick = function(event) {
chrome.send('backgroundModeAction',
[String($('backgroundModeCheckbox').checked)]);
};
}
},
/**
* @inheritDoc
*/
didShowPage: function() {
$('search-field').focus();
},
/**
* Handler for messages sent from the main uber page.
* @param {Event} e The 'message' event from the uber page.
* @private
*/
handleWindowMessage_: function(e) {
if (e.data.method == 'frameSelected')
$('search-field').focus();
},
/**
* Toggle the visibility state of the Advanced section.
* @private
*/
toggleAdvancedSettings_: function() {
if ($('advanced-settings').style.height == '')
this.showAdvancedSettings_();
else
this.hideAdvancedSettings_();
},
/**
* Show advanced settings.
* @private
*/
showAdvancedSettings_: function() {
$('advanced-settings').style.height =
$('advanced-settings-container').offsetHeight + 20 + 'px';
$('advanced-settings-expander').textContent =
localStrings.getString('hideAdvancedSettings');
},
/**
* Hide advanced settings.
* @private
*/
hideAdvancedSettings_: function() {
$('advanced-settings').style.height = '';
$('advanced-settings-expander').textContent =
localStrings.getString('showAdvancedSettings');
},
/**
* Initializes a button for controlling screen brightness.
* @param {string} id Button ID.
* @param {string} callback Name of the callback function.
*/
initBrightnessButton_: function(id, callback) {
var button = $(id);
cr.ui.decorate(button, RepeatingButton);
button.repeatInterval = 300;
button.addEventListener(RepeatingButton.Event.BUTTON_HELD, function(e) {
chrome.send(callback);
});
},
/**
* Updates the sync section with the given state.
* @param {Object} syncData A bunch of data records that describe the status
* of the sync system.
* @private
*/
updateSyncState_: function(syncData) {
if (!syncData.syncSystemEnabled) {
$('sync-section').hidden = true;
return;
}
$('sync-section').hidden = false;
this.syncSetupCompleted = syncData.setupCompleted;
$('customize-sync').hidden = !syncData.setupCompleted;
var startStopButton = $('start-stop-sync');
startStopButton.disabled = syncData.managed ||
syncData.setupInProgress;
startStopButton.hidden =
syncData.setupCompleted && cr.isChromeOs;
startStopButton.textContent =
syncData.setupCompleted ?
localStrings.getString('syncButtonTextStop') :
syncData.setupInProgress ?
localStrings.getString('syncButtonTextInProgress') :
localStrings.getString('syncButtonTextStart');
// TODO(estade): can this just be textContent?
$('sync-status-text').innerHTML = syncData.statusText;
var statusSet = syncData.statusText.length != 0;
$('sync-overview').hidden = statusSet;
$('sync-status').hidden = !statusSet;
$('sync-action-link').textContent = syncData.actionLinkText;
$('sync-action-link').hidden = syncData.actionLinkText.length == 0;
$('sync-action-link').disabled = syncData.managed;
if (syncData.syncHasError)
$('sync-status').classList.add('sync-error');
else
$('sync-status').classList.remove('sync-error');
$('customize-sync').disabled = syncData.hasUnrecoverableError;
$('enable-auto-login-checkbox').hidden = !syncData.autoLoginVisible;
},
/**
* Display or hide the profiles section of the page. This is used for
* multi-profile settings.
* @param {boolean} visible True to show the section.
* @private
*/
setProfilesSectionVisible_: function(visible) {
$('profiles-section').hidden = !visible;
},
/**
* Get the start/stop sync button DOM element. Used for testing.
* @return {DOMElement} The start/stop sync button.
* @private
*/
getStartStopSyncButton_: function() {
return $('start-stop-sync');
},
/**
* Returns the