summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/resources/options
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/chrome/browser/resources/options
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/chrome/browser/resources/options')
-rw-r--r--chromium/chrome/browser/resources/options/OWNERS1
-rw-r--r--chromium/chrome/browser/resources/options/arrow_next.pngbin200 -> 0 bytes
-rw-r--r--chromium/chrome/browser/resources/options/autofill_edit_address_overlay.html50
-rw-r--r--chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js355
-rw-r--r--chromium/chrome/browser/resources/options/autofill_edit_overlay.css53
-rw-r--r--chromium/chrome/browser/resources/options/autofill_options.html3
-rw-r--r--chromium/chrome/browser/resources/options/autofill_options.js13
-rw-r--r--chromium/chrome/browser/resources/options/autofill_options_list.js45
-rw-r--r--chromium/chrome/browser/resources/options/automatic_settings_reset_banner.html15
-rw-r--r--chromium/chrome/browser/resources/options/automatic_settings_reset_banner.js60
-rw-r--r--chromium/chrome/browser/resources/options/browser_options.css34
-rw-r--r--chromium/chrome/browser/resources/options/browser_options.html285
-rw-r--r--chromium/chrome/browser/resources/options/browser_options.js602
-rw-r--r--chromium/chrome/browser/resources/options/browser_options_profile_list.js24
-rw-r--r--chromium/chrome/browser/resources/options/certificate_manager.html11
-rw-r--r--chromium/chrome/browser/resources/options/certificate_manager.js97
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/accounts_options.html28
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/accounts_options.js4
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth.css45
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html3
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js32
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js74
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/change_picture_options.css12
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/change_picture_options.html14
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/change_picture_options.js48
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/display_options.html9
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/display_options.js23
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/internet_detail.html2
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/internet_detail.js11
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.html20
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.js8
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/network_list.js2
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css8
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html21
-rw-r--r--chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js89
-rw-r--r--chromium/chrome/browser/resources/options/clear_browser_data_overlay.html2
-rw-r--r--chromium/chrome/browser/resources/options/clear_browser_data_overlay.js186
-rw-r--r--chromium/chrome/browser/resources/options/confirm_dialog.js19
-rw-r--r--chromium/chrome/browser/resources/options/content_settings.css11
-rw-r--r--chromium/chrome/browser/resources/options/content_settings.html25
-rw-r--r--chromium/chrome/browser/resources/options/content_settings.js79
-rw-r--r--chromium/chrome/browser/resources/options/content_settings2.html13
-rw-r--r--chromium/chrome/browser/resources/options/content_settings2.js88
-rw-r--r--chromium/chrome/browser/resources/options/content_settings_exceptions_area.html15
-rw-r--r--chromium/chrome/browser/resources/options/content_settings_exceptions_area.js28
-rw-r--r--chromium/chrome/browser/resources/options/controlled_setting.css48
-rw-r--r--chromium/chrome/browser/resources/options/controlled_setting.js37
-rw-r--r--chromium/chrome/browser/resources/options/cookies_view.js4
-rw-r--r--chromium/chrome/browser/resources/options/deletable_item_list.js2
-rw-r--r--chromium/chrome/browser/resources/options/do_not_track_confirm_overlay.html26
-rw-r--r--chromium/chrome/browser/resources/options/font_settings.js4
-rw-r--r--chromium/chrome/browser/resources/options/handler_options.html14
-rw-r--r--chromium/chrome/browser/resources/options/handler_options.js2
-rw-r--r--chromium/chrome/browser/resources/options/handler_options_list.js18
-rw-r--r--chromium/chrome/browser/resources/options/home_page_overlay.html2
-rw-r--r--chromium/chrome/browser/resources/options/hotword_confirm_overlay.css12
-rw-r--r--chromium/chrome/browser/resources/options/hotword_confirm_overlay.html38
-rw-r--r--chromium/chrome/browser/resources/options/hotword_search_setting_indicator.css10
-rw-r--r--chromium/chrome/browser/resources/options/hotword_search_setting_indicator.js115
-rw-r--r--chromium/chrome/browser/resources/options/import_data_overlay.html2
-rw-r--r--chromium/chrome/browser/resources/options/import_data_overlay.js11
-rw-r--r--chromium/chrome/browser/resources/options/language_options.css10
-rw-r--r--chromium/chrome/browser/resources/options/language_options.html19
-rw-r--r--chromium/chrome/browser/resources/options/language_options.js129
-rw-r--r--chromium/chrome/browser/resources/options/manage_profile_overlay.css36
-rw-r--r--chromium/chrome/browser/resources/options/manage_profile_overlay.html27
-rw-r--r--chromium/chrome/browser/resources/options/manage_profile_overlay.js270
-rw-r--r--chromium/chrome/browser/resources/options/managed_user_create_confirm.js21
-rw-r--r--chromium/chrome/browser/resources/options/managed_user_import.css7
-rw-r--r--chromium/chrome/browser/resources/options/managed_user_import.html32
-rw-r--r--chromium/chrome/browser/resources/options/managed_user_import.js107
-rw-r--r--chromium/chrome/browser/resources/options/managed_user_list.js3
-rw-r--r--chromium/chrome/browser/resources/options/managed_user_list_data.js152
-rw-r--r--chromium/chrome/browser/resources/options/media_galleries_list.js59
-rw-r--r--chromium/chrome/browser/resources/options/media_galleries_manager_overlay.html19
-rw-r--r--chromium/chrome/browser/resources/options/media_galleries_manager_overlay.js81
-rw-r--r--chromium/chrome/browser/resources/options/options.html36
-rw-r--r--chromium/chrome/browser/resources/options/options.js45
-rw-r--r--chromium/chrome/browser/resources/options/options_bundle.js16
-rw-r--r--chromium/chrome/browser/resources/options/options_page.css40
-rw-r--r--chromium/chrome/browser/resources/options/options_page.js126
-rw-r--r--chromium/chrome/browser/resources/options/options_settings_app.js1
-rw-r--r--chromium/chrome/browser/resources/options/password_manager_list.js1
-rw-r--r--chromium/chrome/browser/resources/options/pref_ui.js5
-rw-r--r--chromium/chrome/browser/resources/options/preferences.js11
-rw-r--r--chromium/chrome/browser/resources/options/profiles_icon_grid.js3
-rw-r--r--chromium/chrome/browser/resources/options/reset_profile_settings_banner.html2
-rw-r--r--chromium/chrome/browser/resources/options/reset_profile_settings_banner.js59
-rw-r--r--chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html4
-rw-r--r--chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js12
-rw-r--r--chromium/chrome/browser/resources/options/search_engine_manager.css8
-rw-r--r--chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js5
-rw-r--r--chromium/chrome/browser/resources/options/search_page.js15
-rw-r--r--chromium/chrome/browser/resources/options/secondary_user_banner.html11
-rw-r--r--chromium/chrome/browser/resources/options/settings_banner.css (renamed from chromium/chrome/browser/resources/options/reset_profile_settings_banner.css)36
-rw-r--r--chromium/chrome/browser/resources/options/settings_banner.js86
-rw-r--r--chromium/chrome/browser/resources/options/startup_section.html4
-rw-r--r--chromium/chrome/browser/resources/options/subpages_tab_controls.css14
-rw-r--r--chromium/chrome/browser/resources/options/sync_section.html28
99 files changed, 2915 insertions, 1537 deletions
diff --git a/chromium/chrome/browser/resources/options/OWNERS b/chromium/chrome/browser/resources/options/OWNERS
index 8da21baca39..4b65fc20160 100644
--- a/chromium/chrome/browser/resources/options/OWNERS
+++ b/chromium/chrome/browser/resources/options/OWNERS
@@ -1,3 +1,4 @@
dbeam@chromium.org
estade@chromium.org
jhawkins@chromium.org
+stevenjb@chromium.org
diff --git a/chromium/chrome/browser/resources/options/arrow_next.png b/chromium/chrome/browser/resources/options/arrow_next.png
deleted file mode 100644
index 7d626c0e8cd..00000000000
--- a/chromium/chrome/browser/resources/options/arrow_next.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.html b/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.html
index 44ff77f147c..3b7ef004c9c 100644
--- a/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.html
+++ b/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.html
@@ -2,64 +2,26 @@
<div class="close-button"></div>
<h1 id="autofill-address-title"></h1>
<div class="content-area">
- <div>
- <div id="autofill-name-labels">
- <span i18n-content="autofillFirstNameLabel"></span>
- <span i18n-content="autofillMiddleNameLabel"></span>
- <span i18n-content="autofillLastNameLabel"></span>
- </div>
- </div>
- <div>
- <list id="full-name-list"></list>
+ <div id="autofill-edit-address-fields">
</div>
- <label class="settings-row">
- <div i18n-content="autofillCompanyNameLabel"></div>
- <input id="company-name" type="text">
- </label>
-
- <label class="settings-row">
- <div i18n-content="autofillAddrLine1Label"></div>
- <input id="addr-line-1" type="text">
- </label>
-
- <label class="settings-row">
- <div i18n-content="autofillAddrLine2Label"></div>
- <input id="addr-line-2" type="text">
- </label>
-
- <div class="input-group settings-row">
- <label>
- <div i18n-content="autofillCityLabel"></div>
- <input id="city" type="text">
- </label>
-
- <label>
- <div id="state-label"></div>
- <input id="state" type="text">
- </label>
-
+ <div class="settings-row">
<label>
- <div id="postal-code-label"></div>
- <input id="postal-code" type="text">
+ <div i18n-content="autofillCountryLabel"></div>
+ <select class="country" field="country"></select>
</label>
</div>
- <div class="settings-row">
- <div i18n-content="autofillCountryLabel"></div>
- <select id="country"></select>
- </div>
-
<div class="input-group settings-row">
<div>
<div i18n-content="autofillPhoneLabel"></div>
- <list id="phone-list"
+ <list class="short" field="phone"
i18n-values="placeholder:autofillAddPhonePlaceholder"></list>
</div>
<div>
<div i18n-content="autofillEmailLabel"></div>
- <list id="email-list"
+ <list class="short" field="email"
i18n-values="placeholder:autofillAddEmailPlaceholder"></list>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js b/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js
index 94b6a5d307d..d3e211324e0 100644
--- a/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js
+++ b/chromium/chrome/browser/resources/options/autofill_edit_address_overlay.js
@@ -6,9 +6,6 @@ cr.define('options', function() {
/** @const */ var OptionsPage = options.OptionsPage;
/** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
- // The GUID of the loaded address.
- var guid;
-
/**
* AutofillEditAddressOverlay class
* Encapsulated handling of the 'Add Page' overlay page.
@@ -26,6 +23,28 @@ cr.define('options', function() {
__proto__: OptionsPage.prototype,
/**
+ * The GUID of the loaded address.
+ * @type {string}
+ */
+ guid_: '',
+
+ /**
+ * The BCP 47 language code for the layout of input fields.
+ * @type {string}
+ */
+ languageCode_: '',
+
+ /**
+ * The saved field values for the address. For example, if the user changes
+ * from United States to Switzerland, then the State field will be hidden
+ * and its value will be stored here. If the user changes back to United
+ * States, then the State field will be restored to its previous value, as
+ * stored in this object.
+ * @type {Object}
+ */
+ savedFieldValues_: {},
+
+ /**
* Initializes the page.
*/
initializePage: function() {
@@ -46,8 +65,11 @@ cr.define('options', function() {
// Blurring is delayed for list elements. Queue save and close to
// ensure that pending changes have been applied.
setTimeout(function() {
- self.saveAddress_();
- self.dismissOverlay_();
+ self.pageDiv.querySelector('[field=phone]').doneValidating().then(
+ function() {
+ self.saveAddress_();
+ self.dismissOverlay_();
+ });
}, 0);
};
@@ -62,10 +84,17 @@ cr.define('options', function() {
event.preventDefault();
};
- self.guid = '';
- self.populateCountryList_();
- self.clearInputFields_();
- self.connectInputEvents_();
+ this.guid_ = '';
+ this.populateCountryList_();
+ this.rebuildInputFields_(
+ loadTimeData.getValue('autofillDefaultCountryComponents'));
+ this.languageCode_ =
+ loadTimeData.getString('autofillDefaultCountryLanguageCode');
+ this.connectInputEvents_();
+ this.setInputFields_({});
+ this.getCountrySwitcher_().onchange = function(event) {
+ self.countryChanged_();
+ };
},
/**
@@ -79,34 +108,27 @@ cr.define('options', function() {
},
/**
- * Creates, decorates and initializes the multi-value lists for full name,
- * phone, and email.
+ * Creates, decorates and initializes the multi-value lists for phone and
+ * email.
* @private
*/
createMultiValueLists_: function() {
- var list = $('full-name-list');
- options.autofillOptions.AutofillNameValuesList.decorate(list);
- list.autoExpands = true;
-
- list = $('phone-list');
+ var list = this.pageDiv.querySelector('[field=phone]');
options.autofillOptions.AutofillPhoneValuesList.decorate(list);
list.autoExpands = true;
- list = $('email-list');
+ list = this.pageDiv.querySelector('[field=email]');
options.autofillOptions.AutofillValuesList.decorate(list);
list.autoExpands = true;
},
/**
- * Updates the data model for the list named |listName| with the values from
- * |entries|.
- * @param {string} listName The id of the list.
+ * Updates the data model for the |list| with the values from |entries|.
+ * @param {cr.ui.List} list The list to update.
* @param {Array} entries The list of items to be added to the list.
+ * @private
*/
- setMultiValueList_: function(listName, entries) {
- // Add data entries.
- var list = $(listName);
-
+ setMultiValueList_: function(list, entries) {
// Add special entry for adding new values.
var augmentedList = entries.slice();
augmentedList.push(null);
@@ -127,33 +149,104 @@ cr.define('options', function() {
* @private
*/
dismissOverlay_: function() {
- this.clearInputFields_();
- this.guid = '';
+ this.setInputFields_({});
+ this.inputFieldChanged_();
+ this.guid_ = '';
+ this.languageCode_ = '';
+ this.savedInputFields_ = {};
OptionsPage.closeOverlay();
},
/**
+ * @return {Element} The element used to switch countries.
+ * @private
+ */
+ getCountrySwitcher_: function() {
+ return this.pageDiv.querySelector('[field=country]');
+ },
+
+ /**
+ * Returns all list elements.
+ * @return {!NodeList} The list elements.
+ * @private
+ */
+ getLists_: function() {
+ return this.pageDiv.querySelectorAll('list[field]');
+ },
+
+ /**
+ * Returns all text input elements.
+ * @return {!NodeList} The text input elements.
+ * @private
+ */
+ getTextFields_: function() {
+ return this.pageDiv.querySelectorAll('textarea[field], input[field]');
+ },
+
+ /**
+ * Creates a map from type => value for all text fields.
+ * @return {Object} The mapping from field names to values.
+ * @private
+ */
+ getInputFields_: function() {
+ var address = {country: this.getCountrySwitcher_().value};
+
+ var lists = this.getLists_();
+ for (var i = 0; i < lists.length; i++) {
+ address[lists[i].getAttribute('field')] =
+ lists[i].dataModel.slice(0, lists[i].dataModel.length - 1);
+ }
+
+ var fields = this.getTextFields_();
+ for (var i = 0; i < fields.length; i++) {
+ address[fields[i].getAttribute('field')] = fields[i].value;
+ }
+
+ return address;
+ },
+
+ /**
+ * Sets the value of each input field according to |address|.
+ * @param {object} address The object with values to use.
+ * @private
+ */
+ setInputFields_: function(address) {
+ this.getCountrySwitcher_().value = address.country || '';
+
+ var lists = this.getLists_();
+ for (var i = 0; i < lists.length; i++) {
+ this.setMultiValueList_(
+ lists[i], address[lists[i].getAttribute('field')] || []);
+ }
+
+ var fields = this.getTextFields_();
+ for (var i = 0; i < fields.length; i++) {
+ fields[i].value = address[fields[i].getAttribute('field')] || '';
+ }
+ },
+
+ /**
* Aggregates the values in the input fields into an array and sends the
* array to the Autofill handler.
* @private
*/
saveAddress_: function() {
- var address = new Array();
- address[0] = this.guid;
- var list = $('full-name-list');
- address[1] = list.dataModel.slice(0, list.dataModel.length - 1);
- address[2] = $('company-name').value;
- address[3] = $('addr-line-1').value;
- address[4] = $('addr-line-2').value;
- address[5] = $('city').value;
- address[6] = $('state').value;
- address[7] = $('postal-code').value;
- address[8] = $('country').value;
- list = $('phone-list');
- address[9] = list.dataModel.slice(0, list.dataModel.length - 1);
- list = $('email-list');
- address[10] = list.dataModel.slice(0, list.dataModel.length - 1);
-
+ var inputFields = this.getInputFields_();
+ var address = [
+ this.guid_,
+ inputFields.fullName || [],
+ inputFields.companyName || '',
+ inputFields.addrLines || '',
+ inputFields.dependentLocality || '',
+ inputFields.city || '',
+ inputFields.state || '',
+ inputFields.postalCode || '',
+ inputFields.sortingCode || '',
+ inputFields.country || '',
+ inputFields.phone || [],
+ inputFields.email || [],
+ this.languageCode_,
+ ];
chrome.send('setAddress', address);
},
@@ -164,52 +257,53 @@ cr.define('options', function() {
* @private
*/
connectInputEvents_: function() {
- var self = this;
- $('company-name').oninput = $('addr-line-1').oninput =
- $('addr-line-2').oninput = $('city').oninput = $('state').oninput =
- $('postal-code').oninput = function(event) {
- self.inputFieldChanged_();
- };
-
- $('country').onchange = function(event) {
- self.countryChanged_();
- };
+ var fields = this.getTextFields_();
+ for (var i = 0; i < fields.length; i++) {
+ fields[i].oninput = this.inputFieldChanged_.bind(this);
+ }
},
/**
- * Checks the values of each of the input fields and disables the 'Ok'
- * button if all of the fields are empty.
+ * Disables the 'Ok' button if all of the fields are empty.
* @private
*/
inputFieldChanged_: function() {
- // Length of lists are tested for <= 1 due to the "add" placeholder item
- // in the list.
- var disabled =
- $('full-name-list').items.length <= 1 &&
- !$('company-name').value &&
- !$('addr-line-1').value && !$('addr-line-2').value &&
- !$('city').value && !$('state').value && !$('postal-code').value &&
- !$('country').value && $('phone-list').items.length <= 1 &&
- $('email-list').items.length <= 1;
+ var disabled = !this.getCountrySwitcher_().value;
+ if (disabled) {
+ // Length of lists are tested for > 1 due to the "add" placeholder item
+ // in the list.
+ var lists = this.getLists_();
+ for (var i = 0; i < lists.length; i++) {
+ if (lists[i].items.length > 1) {
+ disabled = false;
+ break;
+ }
+ }
+ }
+
+ if (disabled) {
+ var fields = this.getTextFields_();
+ for (var i = 0; i < fields.length; i++) {
+ if (fields[i].value) {
+ disabled = false;
+ break;
+ }
+ }
+ }
+
$('autofill-edit-address-apply-button').disabled = disabled;
},
/**
- * Updates the postal code and state field labels appropriately for the
- * selected country.
+ * Updates the address fields appropriately for the selected country.
* @private
*/
countryChanged_: function() {
- var countryCode = $('country').value ||
- loadTimeData.getString('defaultCountryCode');
-
- var details = loadTimeData.getValue('autofillCountryData')[countryCode];
- var postal = $('postal-code-label');
- postal.textContent = details.postalCodeLabel;
- $('state-label').textContent = details.stateLabel;
-
- // Also update the 'Ok' button as needed.
- this.inputFieldChanged_();
+ var countryCode = this.getCountrySwitcher_().value;
+ if (countryCode)
+ chrome.send('loadAddressEditorComponents', [countryCode]);
+ else
+ this.inputFieldChanged_();
},
/**
@@ -220,7 +314,7 @@ cr.define('options', function() {
var countryList = loadTimeData.getValue('autofillCountrySelectList');
// Add the countries to the country <select> list.
- var countrySelect = $('country');
+ var countrySelect = this.getCountrySwitcher_();
// Add an empty option.
countrySelect.appendChild(new Option('', ''));
for (var i = 0; i < countryList.length; i++) {
@@ -232,52 +326,85 @@ cr.define('options', function() {
},
/**
- * Clears the value of each input field.
+ * Loads the address data from |address|, sets the input fields based on
+ * this data, and stores the GUID and language code of the address.
+ * @param {!Object} address Lots of info about an address from the browser.
* @private
*/
- clearInputFields_: function() {
- this.setMultiValueList_('full-name-list', []);
- $('company-name').value = '';
- $('addr-line-1').value = '';
- $('addr-line-2').value = '';
- $('city').value = '';
- $('state').value = '';
- $('postal-code').value = '';
- $('country').value = '';
- this.setMultiValueList_('phone-list', []);
- this.setMultiValueList_('email-list', []);
-
- this.countryChanged_();
+ loadAddress_: function(address) {
+ this.rebuildInputFields_(address.components);
+ this.setInputFields_(address);
+ this.inputFieldChanged_();
+ this.connectInputEvents_();
+ this.guid_ = address.guid;
+ this.languageCode_ = address.languageCode;
},
/**
- * Loads the address data from |address|, sets the input fields based on
- * this data and stores the GUID of the address.
+ * Takes a snapshot of the input values, clears the input values, loads the
+ * address input layout from |input.components|, restores the input values
+ * from snapshot, and stores the |input.languageCode| for the address.
+ * @param {{languageCode: string, components: Array.<Array.<Object>>}} input
+ * Info about how to layout inputs fields in this dialog.
* @private
*/
- loadAddress_: function(address) {
- this.setInputFields_(address);
+ loadAddressComponents_: function(input) {
+ var inputFields = this.getInputFields_();
+ for (var fieldName in inputFields) {
+ if (inputFields.hasOwnProperty(fieldName))
+ this.savedFieldValues_[fieldName] = inputFields[fieldName];
+ }
+ this.rebuildInputFields_(input.components);
+ this.setInputFields_(this.savedFieldValues_);
this.inputFieldChanged_();
- this.guid = address.guid;
+ this.connectInputEvents_();
+ this.languageCode_ = input.languageCode;
},
/**
- * Sets the value of each input field according to |address|
+ * Clears address inputs and rebuilds the input fields according to
+ * |components|.
+ * @param {Array.<Array.<Object>>} components A list of information about
+ * each input field.
* @private
*/
- setInputFields_: function(address) {
- this.setMultiValueList_('full-name-list', address.fullName);
- $('company-name').value = address.companyName;
- $('addr-line-1').value = address.addrLine1;
- $('addr-line-2').value = address.addrLine2;
- $('city').value = address.city;
- $('state').value = address.state;
- $('postal-code').value = address.postalCode;
- $('country').value = address.country;
- this.setMultiValueList_('phone-list', address.phone);
- this.setMultiValueList_('email-list', address.email);
-
- this.countryChanged_();
+ rebuildInputFields_: function(components) {
+ var content = $('autofill-edit-address-fields');
+ content.innerHTML = '';
+
+ var customContainerElements = {fullName: 'div'};
+ var customInputElements = {fullName: 'list', addrLines: 'textarea'};
+
+ for (var i in components) {
+ var row = document.createElement('div');
+ row.classList.add('input-group', 'settings-row');
+ content.appendChild(row);
+
+ for (var j in components[i]) {
+ if (components[i][j].field == 'country')
+ continue;
+
+ var fieldContainer = document.createElement(
+ customContainerElements[components[i][j].field] || 'label');
+ row.appendChild(fieldContainer);
+
+ var fieldName = document.createElement('div');
+ fieldName.textContent = components[i][j].name;
+ fieldContainer.appendChild(fieldName);
+
+ var input = document.createElement(
+ customInputElements[components[i][j].field] || 'input');
+ input.setAttribute('field', components[i][j].field);
+ input.classList.add(components[i][j].length);
+ input.setAttribute('placeholder', components[i][j].placeholder || '');
+ fieldContainer.appendChild(input);
+
+ if (input.tagName == 'LIST') {
+ options.autofillOptions.AutofillValuesList.decorate(input);
+ input.autoExpands = true;
+ }
+ }
+ }
},
};
@@ -285,13 +412,19 @@ cr.define('options', function() {
AutofillEditAddressOverlay.getInstance().loadAddress_(address);
};
+ AutofillEditAddressOverlay.loadAddressComponents = function(input) {
+ AutofillEditAddressOverlay.getInstance().loadAddressComponents_(input);
+ };
+
AutofillEditAddressOverlay.setTitle = function(title) {
$('autofill-address-title').textContent = title;
};
AutofillEditAddressOverlay.setValidatedPhoneNumbers = function(numbers) {
- AutofillEditAddressOverlay.getInstance().setMultiValueList_('phone-list',
- numbers);
+ var instance = AutofillEditAddressOverlay.getInstance();
+ var phoneList = instance.pageDiv.querySelector('[field=phone]');
+ instance.setMultiValueList_(phoneList, numbers);
+ phoneList.didReceiveValidationResult();
};
// Export
diff --git a/chromium/chrome/browser/resources/options/autofill_edit_overlay.css b/chromium/chrome/browser/resources/options/autofill_edit_overlay.css
index 166f0cd3da1..24500e6a2fb 100644
--- a/chromium/chrome/browser/resources/options/autofill_edit_overlay.css
+++ b/chromium/chrome/browser/resources/options/autofill_edit_overlay.css
@@ -10,14 +10,21 @@
min-width: 500px;
}
-#full-name-list input,
-#company-name,
-#addr-line-1,
-#addr-line-2 {
+#autofill-edit-address-overlay .long div[role='listitem'] > div > div,
+#autofill-edit-address-overlay .long input,
+#autofill-edit-address-overlay textarea.long,
+#autofill-edit-address-overlay input.long {
width: 16em;
}
-#country {
+#autofill-edit-address-overlay .short div[role='listitem'] > div > div,
+#autofill-edit-address-overlay .short input,
+#autofill-edit-address-overlay textarea.short,
+#autofill-edit-address-overlay input.short {
+ width: 14em;
+}
+
+#autofill-edit-address-overlay .country {
max-width: 450px;
}
@@ -33,45 +40,19 @@
-webkit-padding-end: 4px;
-webkit-padding-start: 4px;
border: 1px solid darkGray;
+ /* Border should go "inside" the height. */
+ box-sizing: border-box;
/* Set the line-height and min-height to match the height of an input element,
* so that even empty cells renderer with the correct height. */
- line-height: 1.75em;
- min-height: 1.75em;
+ height: 2em;
+ line-height: 2em;
}
:-webkit-any(#autofill-edit-credit-card-overlay, #autofill-edit-address-overlay)
- .settings-row div + :-webkit-any(input, select) {
+ .settings-row label > :-webkit-any(input, select, textarea, list) {
margin-top: 4px;
}
-#autofill-name-labels {
- display: -webkit-inline-box;
-}
-
-#autofill-name-labels span {
- -webkit-box-flex: 1;
- display: block;
-}
-
-#full-name-list {
- display: inline-block;
-}
-
-#full-name-list div[role='listitem'] > div {
- display: -webkit-box;
-}
-
-#full-name-list div[role='listitem'] > div > div,
-#autofill-name-labels span {
- -webkit-margin-end: 5px;
- width: 16em;
-}
-
-:-webkit-any(#phone-list, #email-list) div[role='listitem'] > div > div,
-:-webkit-any(#phone-list, #email-list) input {
- width: 14em;
-}
-
.input-group > * {
-webkit-box-orient: vertical;
-webkit-margin-end: 2px;
diff --git a/chromium/chrome/browser/resources/options/autofill_options.html b/chromium/chrome/browser/resources/options/autofill_options.html
index 27a869aced5..f24da00fe72 100644
--- a/chromium/chrome/browser/resources/options/autofill_options.html
+++ b/chromium/chrome/browser/resources/options/autofill_options.html
@@ -5,7 +5,8 @@
<if expr="is_macosx">
<div class="checkbox">
<label>
- <input pref="autofill.auxiliary_profiles_enabled" type="checkbox"
+ <input pref="autofill.use_mac_address_book" type="checkbox"
+ id="autofill-use-mac-address-book-checkbox"
metric="Options_AutofillAuxiliaryProfiles">
<span i18n-content="auxiliaryProfilesEnabled"></span>
</label>
diff --git a/chromium/chrome/browser/resources/options/autofill_options.js b/chromium/chrome/browser/resources/options/autofill_options.js
index 65fb71964ae..bc4c90cf703 100644
--- a/chromium/chrome/browser/resources/options/autofill_options.js
+++ b/chromium/chrome/browser/resources/options/autofill_options.js
@@ -55,6 +55,19 @@ cr.define('options', function() {
$('autofill-options-confirm').onclick = function(event) {
OptionsPage.closeOverlay();
};
+<if expr="is_macosx">
+ $('autofill-use-mac-address-book-checkbox').onchange = function(event) {
+ if (this.checked) {
+ setTimeout(function() {
+ // Prompt the user to give Chrome access to the user's Address
+ // Book, if the user was not previously prompted. The dialog that
+ // appears blocks the Chrome process, so wait for a small period of
+ // time to allow the checkbox to appear filled in.
+ chrome.send('accessAddressBook');
+ }, 10);
+ }
+ };
+</if>
// TODO(jhawkins): What happens when Autofill is disabled whilst on the
// Autofill options page?
diff --git a/chromium/chrome/browser/resources/options/autofill_options_list.js b/chromium/chrome/browser/resources/options/autofill_options_list.js
index 0be698d3e2a..8fd7fdb6a09 100644
--- a/chromium/chrome/browser/resources/options/autofill_options_list.js
+++ b/chromium/chrome/browser/resources/options/autofill_options_list.js
@@ -489,9 +489,52 @@ cr.define('options.autofillOptions', function() {
var info = new Array();
info[0] = index;
info[1] = numbers;
- info[2] = $('country').value;
+ info[2] = document.querySelector(
+ '#autofill-edit-address-overlay [field=country]').value;
+ this.validationRequests_++;
chrome.send('validatePhoneNumbers', info);
},
+
+ /**
+ * The number of ongoing validation requests.
+ * @type {number}
+ * @private
+ */
+ validationRequests_: 0,
+
+ /**
+ * Pending Promise resolver functions.
+ * @type {Array.<!Function>}
+ * @private
+ */
+ validationPromiseResolvers_: [],
+
+ /**
+ * This should be called when a reply of chrome.send('validatePhoneNumbers')
+ * is received.
+ */
+ didReceiveValidationResult: function() {
+ this.validationRequests_--;
+ assert(this.validationRequests_ >= 0);
+ if (this.validationRequests_ <= 0) {
+ while (this.validationPromiseResolvers_.length) {
+ this.validationPromiseResolvers_.pop()();
+ }
+ }
+ },
+
+ /**
+ * Returns a Promise which is fulfilled when all of validation requests are
+ * completed.
+ * @return {!Promise} A promise.
+ */
+ doneValidating: function() {
+ if (this.validationRequests_ <= 0)
+ return Promise.resolve();
+ return new Promise(function(resolve) {
+ this.validationPromiseResolvers_.push(resolve);
+ }.bind(this));
+ }
};
return {
diff --git a/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.html b/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.html
new file mode 100644
index 00000000000..8eae144ba40
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.html
@@ -0,0 +1,15 @@
+<div id="automatic-settings-reset-banner" class="settings-banner" hidden>
+ <div id="automatic-settings-reset-banner-close" class="close-button"></div>
+ <div class="content-area">
+ <div class="badge"></div>
+ <div class="text">
+ <p>
+ <span i18n-values=".innerHTML:automaticSettingsResetBannerText">
+ </span>
+ <a id="automatic-settings-reset-learn-more" class="nowrap"
+ i18n-values="href:automaticSettingsResetLearnMoreUrl"
+ i18n-content="learnMore" target="_blank"></a>
+ </p>
+ </div>
+ </div>
+</div>
diff --git a/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.js b/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.js
new file mode 100644
index 00000000000..15877ad4b7f
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/automatic_settings_reset_banner.js
@@ -0,0 +1,60 @@
+// Copyright 2014 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.
+
+// Note: the native-side handler for this is AutomaticSettingsResetHandler.
+
+cr.define('options', function() {
+ /** @const */ var SettingsBannerBase = options.SettingsBannerBase;
+
+ /**
+ * AutomaticSettingsResetBanner class
+ * Provides encapsulated handling of the Reset Profile Settings banner.
+ * @constructor
+ */
+ function AutomaticSettingsResetBanner() {}
+
+ cr.addSingletonGetter(AutomaticSettingsResetBanner);
+
+ AutomaticSettingsResetBanner.prototype = {
+ __proto__: SettingsBannerBase.prototype,
+
+ /**
+ * Initializes the banner's event handlers.
+ */
+ initialize: function() {
+ this.showMetricName_ = 'AutomaticSettingsReset_WebUIBanner_BannerShown';
+
+ this.dismissNativeCallbackName_ =
+ 'onDismissedAutomaticSettingsResetBanner';
+
+ this.setVisibilibyDomElement_ = $('automatic-settings-reset-banner');
+
+ $('automatic-settings-reset-banner-close').onclick = function(event) {
+ chrome.send('metricsHandler:recordAction',
+ ['AutomaticSettingsReset_WebUIBanner_ManuallyClosed']);
+ AutomaticSettingsResetBanner.dismiss();
+ };
+ $('automatic-settings-reset-learn-more').onclick = function(event) {
+ chrome.send('metricsHandler:recordAction',
+ ['AutomaticSettingsReset_WebUIBanner_LearnMoreClicked']);
+ };
+ },
+ };
+
+ // Forward public APIs to private implementations.
+ [
+ 'show',
+ 'dismiss',
+ ].forEach(function(name) {
+ AutomaticSettingsResetBanner[name] = function() {
+ var instance = AutomaticSettingsResetBanner.getInstance();
+ return instance[name + '_'].apply(instance, arguments);
+ };
+ });
+
+ // Export
+ return {
+ AutomaticSettingsResetBanner: AutomaticSettingsResetBanner
+ };
+});
diff --git a/chromium/chrome/browser/resources/options/browser_options.css b/chromium/chrome/browser/resources/options/browser_options.css
index a3dcba14d10..24ed45d766d 100644
--- a/chromium/chrome/browser/resources/options/browser_options.css
+++ b/chromium/chrome/browser/resources/options/browser_options.css
@@ -87,6 +87,12 @@ html[dir=rtl] #account-picture-wrapper {
min-height: 0;
}
+#profiles-list .profile-container {
+ -webkit-box-align: center;
+ display: -webkit-box;
+ max-width: 100%;
+}
+
#profiles-list .profile-name {
-webkit-box-flex: 1;
overflow: hidden;
@@ -94,6 +100,11 @@ html[dir=rtl] #account-picture-wrapper {
white-space: nowrap;
}
+#profiles-list .profile-supervised {
+ color: #999;
+ margin-left: 5px;
+}
+
#profiles-list > * {
height: 40px;
}
@@ -148,6 +159,21 @@ input[type='range'] {
padding-top: 0;
}
+.extension-controlled-warning-box {
+ background-color: #fbfbfb;
+ border: 1px solid #cecece;
+ border-radius: 3px;
+ padding: 19px;
+}
+
+.extension-controlled-warning {
+ -webkit-padding-start: 35px;
+ background-repeat: no-repeat;
+ margin-bottom: 14px;
+ padding-bottom: 6px;
+ padding-top: 3px;
+}
+
/* Override a platform specific rule in Widgets that may no longer be relevant.
* Too late in the development cycle to update Widgets.css due to the number
* of pages that depend on it.
@@ -156,6 +182,10 @@ input[type='range'] {
padding-bottom: 0;
}
+.hotword-settings {
+ -webkit-margin-start: 22px;
+}
+
/* Internet settings */
#network-settings {
@@ -399,10 +429,6 @@ list:not([disabled]) > .network-group[selected] {
overflow: hidden;
}
-#auto-open-file-types-label {
- padding: 0.45em 0
-}
-
.sliding {
-webkit-transition: height 200ms;
overflow-y: hidden;
diff --git a/chromium/chrome/browser/resources/options/browser_options.html b/chromium/chrome/browser/resources/options/browser_options.html
index 22c61ff490b..4c05757cd72 100644
--- a/chromium/chrome/browser/resources/options/browser_options.html
+++ b/chromium/chrome/browser/resources/options/browser_options.html
@@ -3,17 +3,20 @@
<h1 i18n-content="settingsTitle"></h1>
</header>
<include src="reset_profile_settings_banner.html">
-<if expr="not pp_ifdef('chromeos')">
- <include src="sync_section.html">
-</if>
-<if expr="pp_ifdef('chromeos')">
+ <include src="automatic_settings_reset_banner.html">
+<if expr="chromeos">
+ <include src="secondary_user_banner.html">
<section>
- <h3 i18n-content="sectionTitleInternet"></h3>
+ <div id="network-section-header" class="section-header">
+ <h3 i18n-content="sectionTitleInternet"></h3>
+ <span class="controlled-setting-indicator" plural></span>
+ </div>
<div id="network-settings">
<list id="network-list"></list>
<div id="shared-proxies" class="checkbox">
<label>
<input id="use-shared-proxies" type="checkbox"
+ metric="Options_NetworkUseSharedProxies"
pref="settings.use_shared_proxies">
<span i18n-content="useSharedProxies"></span>
</label>
@@ -22,24 +25,32 @@
</div>
</section>
</if>
-<if expr="not pp_ifdef('chromeos')">
+<if expr="not chromeos">
+ <include src="sync_section.html">
<include src="startup_section.html">
</if>
+ <section id="proxy-section" hidden>
+ <h3 i18n-content="sectionTitleProxy"></h3>
+ <div id="proxy-section-content"></div>
+ </section>
+
<section>
<h3 i18n-content="sectionTitleAppearance"></h3>
<div class="settings-row">
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<button id="set-wallpaper" i18n-content="setWallpaper"
guest-visibility="disabled"></button>
+ <span id="wallpaper-indicator" class="controlled-setting-indicator">
+ </span>
</if>
-<if expr="not pp_ifdef('chromeos') and is_posix and not is_macosx">
+<if expr="not chromeos and is_posix and not is_macosx">
<button id="themes-gallery" i18n-content="themesGallery"></button>
<button id="themes-native-button"
i18n-content="themesNativeButton"></button>
<button id="themes-reset"
i18n-content="themesSetClassic"></button>
</if>
-<if expr="pp_ifdef('chromeos') or is_win or is_macosx">
+<if expr="chromeos or is_win or is_macosx">
<button id="themes-gallery" i18n-content="themesGallery"></button>
<button id="themes-reset" i18n-content="themesReset"></button>
</if>
@@ -65,6 +76,7 @@
<span id="home-page-url" class="home-page-label"></span>
<button id="change-home-page" class="link-button"
i18n-content="changeHomePage"></button>
+ <div id="extension-controlled-container"></div>
</div>
</div>
<div class="checkbox" guest-visibility="disabled">
@@ -82,7 +94,7 @@
</span>
</span>
</div>
-<if expr="not pp_ifdef('toolkit_views') and is_posix and not is_macosx">
+<if expr="is_posix and not chromeos and not is_macosx">
<div class="checkbox"><label>
<input id="show-window-decorations" type="checkbox"
pref="browser.custom_chrome_frame" metric="Options_CustomFrame"
@@ -91,7 +103,7 @@
</label></div>
</if>
</section>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<section>
<h3 i18n-content="sectionTitleDevice"></h3>
<div>
@@ -125,14 +137,14 @@
</if>
<section>
<h3 i18n-content="sectionTitleSearch"></h3>
- <div>
+ <div id="search-section-content">
<label for="default-search-engine" class="settings-row"
i18n-values=".innerHTML:defaultSearchGroupLabel">
</label>
<div class="settings-row">
<select id="default-search-engine" class="weakrtl"></select>
<span class="controlled-setting-indicator"
- pref="default_search_provider.enabled">
+ pref="default_search_provider_data.template_url_data">
</span>
<button id="manage-default-search-engines"
i18n-content="defaultSearchManageEngines">
@@ -142,7 +154,7 @@
</section>
<section id="sync-users-section" guest-visibility="hidden">
<h3 i18n-content="sectionTitleUsers"></h3>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<include src="sync_section.html">
</if>
<div id="profiles-section" hidden>
@@ -152,7 +164,7 @@
</div>
<div id="profiles-buttons">
<button id="profiles-create" i18n-content="profilesCreate"></button>
-<if expr="pp_ifdef('enable_settings_app')">
+<if expr="enable_settings_app">
<button id="profiles-app-list-switch"
i18n-content="profilesAppListSwitch" hidden>
</button>
@@ -160,7 +172,7 @@
<button id="profiles-manage" i18n-content="profilesManage" disabled>
</button>
<button id="profiles-delete" i18n-content="profilesDelete"></button>
-<if expr="not pp_ifdef('chromeos')">
+<if expr="not chromeos">
<button id="import-data" i18n-content="importData"></button>
</if>
</div>
@@ -169,8 +181,8 @@
i18n-values=".innerHTML:profilesSupervisedDashboardTip" hidden>
</div>
</section>
-<if expr="not pp_ifdef('chromeos')">
- <section>
+ <section id="set-default-browser-section">
+<if expr="not chromeos">
<h3 i18n-content="sectionTitleDefaultBrowser"></h3>
<div>
<button id="set-as-default-browser"
@@ -185,11 +197,11 @@
</label>
</div>
</div>
+</if> <!-- not chromeos -->
</section>
-</if> <!-- not pp_ifdef('chromeos') -->
<div id="advanced-settings" hidden>
<div id="advanced-settings-container">
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<section>
<h3 i18n-content="datetimeTitle"></h3>
<div class="option-control-table">
@@ -203,13 +215,30 @@
</select>
</div>
</div>
- <div class="checkbox">
+ <div class="checkbox settings-row">
<label>
<input id="use-24hour-clock" pref="settings.clock.use_24hour_clock"
type="checkbox">
<span i18n-content="use24HourClock"></span>
</label>
</div>
+ <div id="time-synced-explanation" class="settings-row"
+ i18n-content="timeSyncedExplanation"></div>
+ <div id="set-time" class="settings-row" hidden>
+ <button id="set-time-button"
+ i18n-content="setTimeButton"></button>
+ </div>
+ </div>
+ </section>
+
+ <section id="security-section" hidden>
+ <h3 i18n-content="securityTitle"></h3>
+ <div class="settings-row">
+ <span i18n-content="consumerManagementEnrollDescription"></span>
+ </div>
+ <div class="settings-row">
+ <button id="consumer-management-enroll-button"
+ i18n-content="consumerManagementEnrollButton"></button>
</div>
</section>
</if>
@@ -272,6 +301,22 @@
</div>
<div class="checkbox">
<span class="controlled-setting-with-label">
+ <input id="safe-browsing-extended-reporting-enabled"
+ metric="Options_SafeBrowsingExtendedReportingCheckbox"
+ pref="safebrowsing.extended_reporting_enabled"
+ type="checkbox">
+ <span>
+ <label for="safe-browsing-extended-reporting-enabled"
+ i18n-content="safeBrowsingEnableExtendedReporting">
+ </label>
+ <span class="controlled-setting-indicator"
+ pref="safebrowsing.extended_reporting_enabled">
+ </span>
+ </span>
+ </span>
+ </div>
+ <div class="checkbox">
+ <span class="controlled-setting-with-label">
<input id="safeBrowsingEnabled" pref="safebrowsing.enabled"
metric="Options_SafeBrowsingCheckbox" type="checkbox">
<span>
@@ -284,10 +329,11 @@
</span>
</span>
</div>
-<if expr="pp_ifdef('_google_chrome')">
+<if expr="_google_chrome">
<div class="checkbox">
<span class="controlled-setting-with-label">
<input id="spelling-enabled-control" type="checkbox"
+ metric="Options_SpellingServiceCheckbox"
pref="spellcheck.use_spelling_service" dialog-pref>
<span>
<label for="spelling-enabled-control" i18n-content="spellingPref">
@@ -301,7 +347,7 @@
</div>
<div id="metricsReportingSetting" class="checkbox">
<span class="controlled-setting-with-label">
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<input id="metricsReportingEnabled"
pref="cros.metrics.reportingEnabled" type="checkbox">
<span>
@@ -312,7 +358,7 @@
</span>
</span>
</if>
-<if expr="not pp_ifdef('chromeos')">
+<if expr="not chromeos">
<input id="metricsReportingEnabled"
pref="user_experience_metrics.reporting_enabled" type="checkbox">
<span>
@@ -325,7 +371,7 @@
</if>
</span>
</div>
-</if> <!-- pp_ifdef('_google_chrome') -->
+</if> <!-- _google_chrome -->
<div class="checkbox">
<label>
<input id="do-not-track-enabled" pref="enable_do_not_track"
@@ -333,7 +379,7 @@
<span i18n-content="doNotTrack"></span>
</label>
</div>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<div class="checkbox">
<span class="controlled-setting-with-label">
<input id="content-protection-attestation-enabled" type="checkbox"
@@ -352,9 +398,25 @@
</span>
</div>
</if>
+ <div id="hotword-search" hidden>
+ <div class="checkbox">
+ <span class="controlled-setting-with-label">
+ <input id="hotword-search-enable" pref="hotword.search_enabled_2"
+ metric="Options_HotwordCheckbox" type="checkbox" dialog-pref>
+ <span>
+ <label for="hotword-search-enable"
+ i18n-values=".innerHTML:hotwordSearchEnable">
+ </label>
+ <span id="hotword-search-setting-indicator"
+ pref="hotword.search_enabled_2" dialog-pref>
+ </span>
+ </span>
+ </span>
+ </div>
+ </div>
</div>
</section>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<!-- By default, the bluetooth section is hidden. It is only visible if a
bluetooth adapter is discovered -->
<section id="bluetooth-devices" hidden>
@@ -381,7 +443,7 @@
</div>
</div>
</section>
-</if> <!-- pp_ifdef('chromeos') -->
+</if> <!-- chromeos -->
<section id="passwords-and-autofill-section">
<h3 i18n-content="passwordsAndAutofillGroupName"></h3>
<div class="checkbox">
@@ -416,18 +478,47 @@
</span>
</span>
</div>
- <div class="checkbox" id="password-generation-checkbox">
- <label>
- <input id="password-generation-enabled" pref="password_generation.enabled"
- metric="Options_PasswordGenerationCheckbox" type="checkbox">
- <span i18n-content="passwordGenerationEnabledDescription"></span>
- </label>
- </div>
<if expr="is_macosx">
<div id="mac-passwords-warning" i18n-content="macPasswordsWarning" hidden>
</div>
</if>
</section>
+ <section id="easy-unlock-section" guest-visibility="hidden" hidden>
+ <h3 i18n-content="easyUnlockSectionTitle"></h3>
+ <!-- Options shown when the user has not set up Easy Unlock -->
+ <div id='easy-unlock-setup' hidden>
+ <button id="easy-unlock-setup-button"
+ i18n-content="easyUnlockSetupButton"></button>
+ <div>
+ <a target="_blank" i18n-content="learnMore"
+ i18n-values="href:easyUnlockLearnMoreURL"></a>
+ </div>
+ </div>
+ <!-- Options shown when the user has set up Easy Unlock -->
+ <div id='easy-unlock-enable' hidden>
+ <div class="checkbox">
+ <span class="controlled-setting-with-label">
+ <input id="easy-unlock-check" type="checkbox"
+ pref="easy_unlock.enabled"
+ metric="EasyUnlock_Enabled">
+ <span>
+ <label for="easy-unlock-checkbox">
+ <span i18n-content="easyUnlockCheckboxLabel"></span>
+ <a target="_blank" i18n-content="learnMore"
+ i18n-values="href:easyUnlockLearnMoreURL"></a>
+ </label>
+ <span class="controlled-setting-indicator"
+ pref="easy_unlock.enabled">
+ </span>
+ </span>
+ </span>
+ </div>
+ <div>
+ <a target="_blank" i18n-content="easyUnlockManagement"
+ i18n-values="href:easyUnlockManagementURL"></a>
+ </div>
+ </div>
+ </section>
<section id="web-content-section">
<h3 i18n-content="advancedSectionTitleContent"></h3>
<div>
@@ -466,11 +557,13 @@
</if>
</div>
</section>
-<if expr="not pp_ifdef('chromeos')">
+<if expr="not chromeos">
<section id="network-section">
<h3 i18n-content="advancedSectionTitleNetwork"></h3>
<div>
- <span id="proxiesLabel" class="settings-row"></span>
+ <span id="proxiesLabel"
+ class="settings-row"
+ i18n-content="proxiesLabelSystem"></span>
<div class="settings-row">
<button id="proxiesConfigureButton"
i18n-content="proxiesConfigureButton"></button>
@@ -481,7 +574,11 @@
</if>
<section id="languages-section">
<h3 i18n-content="advancedSectionTitleLanguages"></h3>
- <span class="settings-row" i18n-content="languageSectionLabel"></span>
+ <div class="settings-row">
+ <span i18n-content="languageSectionLabel"></span>
+ <a target="_blank" i18n-content="learnMore"
+ i18n-values="href:languagesLearnMoreURL"></a>
+ </div>
<div class="settings-row">
<button id="language-button"
i18n-content="languageAndSpellCheckSettingsButton"></button>
@@ -534,7 +631,7 @@
</span>
</span>
</div>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<div class="checkbox" id="disable-drive-row" guest-visibility="disabled">
<span class="controlled-setting-with-label">
<input id="drive-disabled" type="checkbox"
@@ -548,40 +645,32 @@
</span>
</div>
</if>
-<if expr="not pp_ifdef('chromeos')">
<div id="auto-open-file-types-section" hidden>
<div id="auto-open-file-types-container">
- <div id="auto-open-file-types-label"
+ <div id="auto-open-file-types-label" class="settings-row"
i18n-content="autoOpenFileTypesInfo"></div>
- <button id="autoOpenFileTypesResetToDefault"
- i18n-content="autoOpenFileTypesResetToDefault"></button>
+ <div class="settings-row">
+ <button id="autoOpenFileTypesResetToDefault"
+ i18n-content="autoOpenFileTypesResetToDefault"></button>
+ </div>
</div>
</div>
-</if>
</div>
</section>
<section>
- <h3 i18n-content="advancedSectionTitleSecurity"></h3>
+ <h3 i18n-content="advancedSectionTitleCertificates"></h3>
<div>
-<if expr="pp_ifdef('use_nss') or is_win or is_macosx">
+<if expr="use_nss or is_win or is_macosx">
<div class="settings-row">
<button id="certificatesManageButton"
i18n-content="certificatesManageButton"></button>
</div>
</if>
- <div class="checkbox">
- <label>
- <input id="sslCheckRevocation" pref="ssl.rev_checking.enabled"
- type="checkbox">
- <span i18n-content="sslCheckRevocation"></span>
- </label>
- </div>
</div>
</section>
- <section id="cloud-print-connector-section">
- <h3 i18n-content="advancedSectionTitleCloudPrint"></h3>
-<if expr="pp_ifdef('enable_mdns')">
- <div id="cloudprint-options-mdns" hidden>
+<if expr="enable_service_discovery">
+ <section id="cloudprint-options-mdns">
+ <h3 i18n-content="advancedSectionTitleCloudPrint"></h3>
<div class="settings-row">
<span i18n-content="cloudPrintOptionLabel"></span>
<a target="_blank" i18n-content="learnMore"
@@ -597,7 +686,7 @@
<input id="local-discovery-notifications-enabled"
pref="local_discovery.notifications_enabled"
type="checkbox"
- metric="LocalDiscoveryNotificationsDisabled_Settings" />
+ metric="LocalDiscoveryNotificationsDisabled_Settings">
<span>
<label for="local-discovery-notifications-enabled"
i18n-content="cloudPrintEnableNotificationsLabel">
@@ -606,52 +695,27 @@
pref="local_discovery.notifications_enabled">
</span>
</span>
+ </span>
</div>
- </div>
-</if>
-
- <div id="cloudprint-options-nomdns">
-<if expr="pp_ifdef('chromeos')">
- <div>
- <span i18n-content="cloudPrintOptionLabel"></span>
- <a target="_blank" i18n-content="learnMore"
- i18n-values="href:cloudPrintLearnMoreURL"></a>
- </div>
-</if>
-
-<if expr="not pp_ifdef('chromeos')">
- <p id="cloudPrintConnectorLabel" class="settings-row"
- i18n-content="cloudPrintConnectorDisabledLabel"></p>
-</if>
-
- <div class="settings-row">
-<if expr="not pp_ifdef('chromeos')">
- <button id="cloudPrintConnectorSetupButton"
- i18n-content="cloudPrintConnectorDisabledButton"></button>
+ </section>
</if>
- <button id="cloudPrintManageButton"
- i18n-content="cloudPrintManageButton">
- </button>
- </div>
- </div>
- </section>
-
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<include src="startup_section.html">
<section>
<h3 i18n-content="accessibilityTitle"></h3>
<div class="option-control-table">
<p id="accessibility-explanation" class="settings-row">
<span i18n-content="accessibilityExplanation"></span>
- <a target="_blank" i18n-content="learnMore"
- i18n-values="href:accessibilityLearnMoreURL"></a>
+ <a id="accessibility-learn-more" target="_blank"
+ i18n-content="learnMore"></a>
</p>
<div class="option-name">
<div class="checkbox">
<span class="controlled-setting-with-label">
<input id="accessibility-should-always-show-menu"
- pref="settings.a11y.enable_menu" type="checkbox">
+ pref="settings.a11y.enable_menu" type="checkbox"
+ metric="Options_AccessibilitySystemMenu">
<span>
<label for="accessibility-should-always-show-menu"
i18n-content="accessibilityAlwaysShowMenu">
@@ -666,7 +730,8 @@
<div class="checkbox">
<span class="controlled-setting-with-label">
<input id="accessibility-large-cursor-check"
- pref="settings.a11y.large_cursor_enabled" type="checkbox">
+ pref="settings.a11y.large_cursor_enabled" type="checkbox"
+ metric="Options_AccessibilityLargeMouseCursor">
<span>
<label for="accessibility-large-cursor-check"
i18n-content="accessibilityLargeCursor">
@@ -682,7 +747,8 @@
<div class="checkbox">
<span class="controlled-setting-with-label">
<input id="accessibility-high-contrast-check"
- pref="settings.a11y.high_contrast_enabled" type="checkbox">
+ pref="settings.a11y.high_contrast_enabled" type="checkbox"
+ metric="Options_AccessibilityHighContrastMode">
<span>
<label for="accessibility-high-contrast-check"
i18n-content="accessibilityHighContrast">
@@ -694,11 +760,12 @@
</span>
</div>
</div>
- <div id="accessibility-sticky-keys" class="option-name" hidden>
+ <div id="accessibility-sticky-keys" class="option-name">
<div class="checkbox">
<span class="controlled-setting-with-label">
<input id="accessibility-sticky-keys-check"
- pref="settings.a11y.sticky_keys_enabled" type="checkbox">
+ pref="settings.a11y.sticky_keys_enabled" type="checkbox"
+ metric="Options_AccessibilityStickyKeys">
<span>
<label for="accessibility-sticky-keys-check"
i18n-content="accessibilityStickyKeys">
@@ -714,7 +781,8 @@
<div class="checkbox">
<span class="controlled-setting-with-label">
<input id="accessibility-spoken-feedback-check"
- pref="settings.accessibility" type="checkbox">
+ pref="settings.accessibility" type="checkbox"
+ metric="Options_AccessibilitySpokenFeedback">
<span>
<label for="accessibility-spoken-feedback-check"
i18n-content="accessibilitySpokenFeedback">
@@ -734,7 +802,8 @@
<div class="checkbox">
<span class="controlled-setting-with-label">
<input id="accessibility-screen-magnifier-check"
- pref="settings.a11y.screen_magnifier" type="checkbox">
+ pref="settings.a11y.screen_magnifier" type="checkbox"
+ metric="Options_AccessibilityScreenMagnifier">
<span>
<label for="accessibility-screen-magnifier-check"
i18n-content="accessibilityScreenMagnifier">
@@ -750,7 +819,8 @@
<div class="checkbox">
<label>
<input id="accessibility-tap-dragging-check"
- pref="settings.touchpad.enable_tap_dragging" type="checkbox">
+ pref="settings.touchpad.enable_tap_dragging" type="checkbox"
+ metric="Options_AccessibilityTapDragging">
<span i18n-content="accessibilityTapDragging"></span>
</label>
</div>
@@ -795,8 +865,25 @@
</span>
</div>
</div>
+ <div class="option_name" id="accessibility_onscreen_keyboard">
+ <div class="checkbox">
+ <span class="controlled-setting-with-label">
+ <input id="accessibility-virtual-keyboard-check"
+ pref="settings.a11y.virtual_keyboard" type="checkbox"
+ metric="Options_AccessibilityOnScreenKeyboard">
+ <span>
+ <label for="accessibility-virtual-keyboard-check"
+ i18n-content="accessibilityVirtualKeyboard">
+ </label>
+ <span class="controlled-setting-indicator"
+ pref="settings.a11y.virtual_keyboard">
+ </span>
+ </span>
+ </span>
+ </div>
+ </div>
</section>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<section id="factory-reset-section" hidden>
<h3 i18n-content="factoryResetTitle"></h3>
<div>
@@ -809,7 +896,7 @@
</section>
</if>
</if>
-<if expr="not pp_ifdef('chromeos')">
+<if expr="not chromeos">
<section id="system-section">
<h3 i18n-content="advancedSectionTitleSystem"></h3>
<if expr="not is_macosx">
diff --git a/chromium/chrome/browser/resources/options/browser_options.js b/chromium/chrome/browser/resources/options/browser_options.js
index 60cacd18495..dc1302d4952 100644
--- a/chromium/chrome/browser/resources/options/browser_options.js
+++ b/chromium/chrome/browser/resources/options/browser_options.js
@@ -6,6 +6,7 @@ cr.define('options', function() {
var OptionsPage = options.OptionsPage;
var ArrayDataModel = cr.ui.ArrayDataModel;
var RepeatingButton = cr.ui.RepeatingButton;
+ var HotwordSearchSettingIndicator = options.HotwordSearchSettingIndicator;
//
// BrowserOptions class
@@ -18,6 +19,16 @@ cr.define('options', function() {
cr.addSingletonGetter(BrowserOptions);
+ /**
+ * @param {HTMLElement} section The section to show or hide.
+ * @return {boolean} Whether the section should be shown.
+ * @private
+ */
+ BrowserOptions.shouldShowSection_ = function(section) {
+ // If the section is hidden or hiding, it should be shown.
+ return section.style.height == '' || section.style.height == '0px';
+ };
+
BrowserOptions.prototype = {
__proto__: options.OptionsPage.prototype,
@@ -29,6 +40,14 @@ cr.define('options', function() {
signedIn_: false,
/**
+ * Indicates whether signing out is allowed or whether a complete profile
+ * wipe is required to remove the current enterprise account.
+ * @type {boolean}
+ * @private
+ */
+ signoutAllowed_: true,
+
+ /**
* Keeps track of whether |onShowHomeButtonChanged_| has been called. See
* |onShowHomeButtonChanged_|.
* @type {boolean}
@@ -45,6 +64,14 @@ cr.define('options', function() {
*/
initializationComplete_: false,
+ /**
+ * When a section is waiting to change its height, this will be a number.
+ * Otherwise it'll be null.
+ * @type {?number}
+ * @private
+ */
+ sectionHeightChangeTimeout_: null,
+
/** @override */
initializePage: function() {
OptionsPage.prototype.initializePage.call(this);
@@ -57,39 +84,57 @@ cr.define('options', function() {
window.addEventListener('message', this.handleWindowMessage_.bind(this));
- $('advanced-settings-expander').onclick = function() {
- self.toggleSectionWithAnimation_(
- $('advanced-settings'),
- $('advanced-settings-container'));
-
- // If the link was focused (i.e., it was activated using the keyboard)
- // and it was used to show the section (rather than hiding it), focus
- // the first element in the container.
- if (document.activeElement === $('advanced-settings-expander') &&
- $('advanced-settings').style.height === '') {
- var focusElement = $('advanced-settings-container').querySelector(
- 'button, input, list, select, a[href]');
- if (focusElement)
- focusElement.focus();
- }
+ if (loadTimeData.getBoolean('allowAdvancedSettings')) {
+ $('advanced-settings-expander').onclick = function() {
+ var showAdvanced =
+ BrowserOptions.shouldShowSection_($('advanced-settings'));
+ if (showAdvanced) {
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_ShowAdvancedSettings']);
+ }
+ self.toggleSectionWithAnimation_(
+ $('advanced-settings'),
+ $('advanced-settings-container'));
+
+ // If the link was focused (i.e., it was activated using the keyboard)
+ // and it was used to show the section (rather than hiding it), focus
+ // the first element in the container.
+ if (document.activeElement === $('advanced-settings-expander') &&
+ showAdvanced) {
+ var focusElement = $('advanced-settings-container').querySelector(
+ 'button, input, list, select, a[href]');
+ if (focusElement)
+ focusElement.focus();
+ }
+ };
+ } else {
+ $('advanced-settings-expander').hidden = true;
+ $('advanced-settings').hidden = true;
}
$('advanced-settings').addEventListener('webkitTransitionEnd',
this.updateAdvancedSettingsExpander_.bind(this));
- if (cr.isChromeOS)
+ if (cr.isChromeOS) {
UIAccountTweaks.applyGuestModeVisibility(document);
+ if (loadTimeData.getBoolean('secondaryUser'))
+ $('secondary-user-banner').hidden = false;
+ }
// Sync (Sign in) section.
this.updateSyncState_(loadTimeData.getValue('syncData'));
$('start-stop-sync').onclick = function(event) {
- if (self.signedIn_)
- SyncSetupOverlay.showStopSyncingUI();
- else if (cr.isChromeOS)
+ if (self.signedIn_) {
+ if (self.signoutAllowed_)
+ SyncSetupOverlay.showStopSyncingUI();
+ else
+ chrome.send('showDisconnectManagedProfileDialog');
+ } else if (cr.isChromeOS) {
SyncSetupOverlay.showSetupUI();
- else
+ } else {
SyncSetupOverlay.startSignIn();
+ }
};
$('customize-sync').onclick = function(event) {
SyncSetupOverlay.showSetupUI();
@@ -98,6 +143,14 @@ cr.define('options', function() {
// Internet connection section (ChromeOS only).
if (cr.isChromeOS) {
options.network.NetworkList.decorate($('network-list'));
+ // Show that the network settings are shared if this is a secondary user
+ // in a multi-profile session.
+ if (loadTimeData.getBoolean('secondaryUser')) {
+ var networkIndicator = document.querySelector(
+ '#network-section-header > .controlled-setting-indicator');
+ networkIndicator.setAttribute('controlled-by', 'shared');
+ networkIndicator.location = cr.ui.ArrowLocation.TOP_START;
+ }
options.network.NetworkList.refreshNetworkData(
loadTimeData.getValue('networkData'));
}
@@ -126,16 +179,27 @@ cr.define('options', function() {
$('change-home-page').onclick = function(event) {
OptionsPage.navigateToPage('homePageOverlay');
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_Homepage_ShowSettings']);
};
+ chrome.send('requestHotwordAvailable');
+ var hotwordIndicator = $('hotword-search-setting-indicator');
+ HotwordSearchSettingIndicator.decorate(hotwordIndicator);
+ hotwordIndicator.disabledOnErrorSection = $('hotword-search-enable');
+
if ($('set-wallpaper')) {
$('set-wallpaper').onclick = function(event) {
chrome.send('openWallpaperManager');
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_OpenWallpaperManager']);
};
}
$('themes-gallery').onclick = function(event) {
window.open(loadTimeData.getString('themesGalleryURL'));
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_ThemesGallery']);
};
$('themes-reset').onclick = function(event) {
chrome.send('themesReset');
@@ -155,9 +219,13 @@ cr.define('options', function() {
if (cr.isChromeOS) {
$('keyboard-settings-button').onclick = function(evt) {
OptionsPage.navigateToPage('keyboard-overlay');
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_ShowKeyboardSettings']);
};
$('pointer-settings-button').onclick = function(evt) {
OptionsPage.navigateToPage('pointer-overlay');
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_ShowTouchpadSettings']);
};
}
@@ -169,15 +237,11 @@ cr.define('options', function() {
};
$('default-search-engine').addEventListener('change',
this.setDefaultSearchEngine_);
- // Without this, the bubble would overlap the uber frame navigation pane
- // and would not get mouse event as explained in crbug.com/311421.
- document.querySelector(
- '#default-search-engine + .controlled-setting-indicator').location =
- cr.ui.ArrowLocation.TOP_START;
// Users section.
if (loadTimeData.valueExists('profilesInfo')) {
$('profiles-section').hidden = false;
+ this.maybeShowUserSection_();
var profilesList = $('profiles-list');
options.browser_options.ProfileList.decorate(profilesList);
@@ -228,6 +292,11 @@ cr.define('options', function() {
chrome.send('coreOptionsUserMetricsAction',
['Options_ManageAccounts']);
};
+
+ document.querySelector(
+ '#enable-screen-lock + span > .controlled-setting-indicator').
+ setAttribute('textshared',
+ loadTimeData.getString('screenLockShared'));
} else {
$('import-data').onclick = function(event) {
ImportDataOverlay.show();
@@ -241,8 +310,15 @@ cr.define('options', function() {
}
}
+ // Date and time section (CrOS only).
+ if ($('set-time-button'))
+ $('set-time-button').onclick = this.handleSetTime_.bind(this);
+
// Default browser section.
if (!cr.isChromeOS) {
+ if (!loadTimeData.getBoolean('showSetDefault')) {
+ $('set-default-browser-section').hidden = true;
+ }
$('set-as-default-browser').onclick = function(event) {
chrome.send('becomeDefaultBrowser');
};
@@ -340,6 +416,23 @@ cr.define('options', function() {
};
}
+ // Security section.
+ if (cr.isChromeOS &&
+ loadTimeData.getBoolean('consumerManagementEnabled')) {
+ $('security-section').hidden = false;
+ $('consumer-management-enroll-button').onclick = function(event) {
+ chrome.send('enrollConsumerManagement');
+ };
+ }
+
+ // Easy Unlock section.
+ if (loadTimeData.getBoolean('easyUnlockEnabled')) {
+ $('easy-unlock-section').hidden = false;
+ $('easy-unlock-setup-button').onclick = function(event) {
+ chrome.send('launchEasyUnlockSetup');
+ };
+ }
+
// Web Content section.
$('fontSettingsCustomizeFontsButton').onclick = function(event) {
OptionsPage.navigateToPage('fonts');
@@ -372,14 +465,13 @@ cr.define('options', function() {
$('downloadLocationChangeButton').onclick = function(event) {
chrome.send('selectDownloadLocation');
};
- if (!cr.isChromeOS) {
- $('autoOpenFileTypesResetToDefault').onclick = function(event) {
- chrome.send('autoOpenFileTypesAction');
- };
- } else {
+ if (cr.isChromeOS) {
$('disable-drive-row').hidden =
UIAccountTweaks.loggedInAsLocallyManagedUser();
}
+ $('autoOpenFileTypesResetToDefault').onclick = function(event) {
+ chrome.send('autoOpenFileTypesAction');
+ };
// HTTPS/SSL section.
if (cr.isWindows || cr.isMac) {
@@ -394,29 +486,8 @@ cr.define('options', function() {
};
}
- // 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 its text to the intermediate state.
- $('cloudPrintConnectorSetupButton').textContent =
- loadTimeData.getString('cloudPrintConnectorEnablingButton');
- $('cloudPrintConnectorSetupButton').disabled = true;
- chrome.send('showCloudPrintSetupDialog');
- } else {
- chrome.send('disableCloudPrintConnector');
- }
- };
- }
- $('cloudPrintManageButton').onclick = function(event) {
- chrome.send('showCloudPrintManagePage');
- };
-
if (loadTimeData.getBoolean('cloudPrintShowMDnsOptions')) {
$('cloudprint-options-mdns').hidden = false;
- $('cloudprint-options-nomdns').hidden = true;
$('cloudPrintDevicesPageButton').onclick = function() {
chrome.send('showCloudPrintDevicesPage');
};
@@ -431,17 +502,24 @@ cr.define('options', function() {
Preferences.getInstance().addEventListener(
'settings.accessibility',
updateAccessibilitySettingsButton);
- $('accessibility-settings-button').onclick = function(event) {
+ $('accessibility-learn-more').onclick = function(unused_event) {
+ window.open(loadTimeData.getString('accessibilityLearnMoreURL'));
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_AccessibilityLearnMore']);
+ };
+ $('accessibility-settings-button').onclick = function(unused_event) {
window.open(loadTimeData.getString('accessibilitySettingsURL'));
};
- $('accessibility-spoken-feedback-check').onchange = function(event) {
+ $('accessibility-spoken-feedback-check').onchange = function(
+ unused_event) {
chrome.send('spokenFeedbackChange',
[$('accessibility-spoken-feedback-check').checked]);
updateAccessibilitySettingsButton();
};
updateAccessibilitySettingsButton();
- $('accessibility-high-contrast-check').onchange = function(event) {
+ $('accessibility-high-contrast-check').onchange = function(
+ unused_event) {
chrome.send('highContrastChange',
[$('accessibility-high-contrast-check').checked]);
};
@@ -453,9 +531,6 @@ cr.define('options', function() {
Preferences.getInstance().addEventListener(
$('accessibility-autoclick-check').getAttribute('pref'),
updateDelayDropdown);
-
- $('accessibility-sticky-keys').hidden =
- !loadTimeData.getBoolean('enableStickyKeys');
}
// Display management section (CrOS only).
@@ -471,6 +546,7 @@ cr.define('options', function() {
if (cr.isChromeOS) {
$('factory-reset-restart').onclick = function(event) {
OptionsPage.navigateToPage('factoryResetData');
+ chrome.send('onPowerwashDialogShow');
};
}
@@ -496,6 +572,33 @@ cr.define('options', function() {
};
$('reset-profile-settings-section').hidden =
!loadTimeData.getBoolean('enableResetProfileSettings');
+
+ // Extension controlled UI.
+ this.addExtensionControlledBox_('search-section-content',
+ 'search-engine-controlled',
+ true);
+ this.addExtensionControlledBox_('extension-controlled-container',
+ 'homepage-controlled',
+ true);
+ this.addExtensionControlledBox_('startup-section-content',
+ 'startpage-controlled',
+ false);
+ this.addExtensionControlledBox_('newtab-section-content',
+ 'newtab-controlled',
+ false);
+ this.addExtensionControlledBox_('proxy-section-content',
+ 'proxy-controlled',
+ true);
+
+ document.body.addEventListener('click', function(e) {
+ var button = findAncestor(e.target, function(el) {
+ return el.tagName == 'BUTTON' &&
+ el.dataset.extensionId !== undefined &&
+ el.dataset.extensionId.length;
+ });
+ if (button)
+ chrome.send('disableExtension', [button.dataset.extensionId]);
+ });
},
/** @override */
@@ -549,6 +652,35 @@ cr.define('options', function() {
},
/**
+ * Animatedly changes height |from| a px number |to| a px number.
+ * @param {HTMLElement} section The section to animate.
+ * @param {HTMLElement} container The container of |section|.
+ * @param {boolean} showing Whether to go from 0 -> container height or
+ * container height -> 0.
+ * @private
+ */
+ animatedSectionHeightChange_: function(section, container, showing) {
+ // If the section is already animating, dispatch a synthetic transition
+ // end event as the upcoming code will cancel the current one.
+ if (section.classList.contains('sliding'))
+ cr.dispatchSimpleEvent(section, 'webkitTransitionEnd');
+
+ this.addTransitionEndListener_(section);
+
+ section.hidden = false;
+ section.style.height = (showing ? 0 : container.offsetHeight) + 'px';
+ section.classList.add('sliding');
+
+ if (this.sectionHeightChangeTimeout_ !== null)
+ clearTimeout(this.sectionHeightChangeTimeout_);
+
+ this.sectionHeightChangeTimeout_ = setTimeout(function() {
+ section.style.height = (showing ? container.offsetHeight : 0) + 'px';
+ this.sectionHeightChangeTimeout_ = null;
+ });
+ },
+
+ /**
* Shows the given section.
* @param {HTMLElement} section The section to be shown.
* @param {HTMLElement} container The container for the section. Must be
@@ -557,30 +689,15 @@ cr.define('options', function() {
* @private
*/
showSection_: function(section, container, animate) {
- if (animate)
- this.addTransitionEndListener_(section);
-
- // Unhide
- section.hidden = false;
- section.style.height = '0px';
-
- var expander = function() {
- // Reveal the section using a WebKit transition if animating.
- if (animate) {
- section.classList.add('sliding');
- section.style.height = container.offsetHeight + 'px';
- } else {
- section.style.height = 'auto';
- }
- };
-
// Delay starting the transition if animating so that hidden change will
// be processed.
- if (animate)
- setTimeout(expander, 0);
- else
- expander();
- },
+ if (animate) {
+ this.animatedSectionHeightChange_(section, container, true);
+ } else {
+ section.hidden = false;
+ section.style.height = 'auto';
+ }
+ },
/**
* Shows the given section, with animation.
@@ -590,33 +707,29 @@ cr.define('options', function() {
* @private
*/
showSectionWithAnimation_: function(section, container) {
- this.showSection_(section, container, /*animate */ true);
+ this.showSection_(section, container, /* animate */ true);
},
/**
- * See showSectionWithAnimation_.
+ * Hides the given |section| with animation.
+ * @param {HTMLElement} section The section to be hidden.
+ * @param {HTMLElement} container The container for the section. Must be
+ * inside of |section|.
+ * @private
*/
hideSectionWithAnimation_: function(section, container) {
- this.addTransitionEndListener_(section);
-
- // Before we start hiding the section, we need to set
- // the height to a pixel value.
- section.style.height = container.offsetHeight + 'px';
-
- // Delay starting the transition so that the height change will be
- // processed.
- setTimeout(function() {
- // Hide the section using a WebKit transition.
- section.classList.add('sliding');
- section.style.height = '0px';
- }, 0);
+ this.animatedSectionHeightChange_(section, container, false);
},
/**
- * See showSectionWithAnimation_.
+ * Toggles the visibility of |section| in an animated way.
+ * @param {HTMLElement} section The section to be toggled.
+ * @param {HTMLElement} container The container for the section. Must be
+ * inside of |section|.
+ * @private
*/
toggleSectionWithAnimation_: function(section, container) {
- if (section.style.height == '')
+ if (BrowserOptions.shouldShowSection_(section))
this.showSectionWithAnimation_(section, container);
else
this.hideSectionWithAnimation_(section, container);
@@ -633,7 +746,10 @@ cr.define('options', function() {
scrollToSection_: function(section) {
var advancedSettings = $('advanced-settings');
var container = $('advanced-settings-container');
- if (advancedSettings.hidden && section.parentNode == container) {
+ var expander = $('advanced-settings-expander');
+ if (!expander.hidden &&
+ advancedSettings.hidden &&
+ section.parentNode == container) {
this.showSection_($('advanced-settings'),
$('advanced-settings-container'),
/* animate */ false);
@@ -686,17 +802,23 @@ cr.define('options', function() {
/**
* Called after an animation transition has ended.
+ * @param {Event} The webkitTransitionEnd event. NOTE: May be synthetic.
* @private
*/
onTransitionEnd_: function(event) {
- if (event.propertyName != 'height')
+ if (event.propertyName && event.propertyName != 'height') {
+ // If not a synthetic event or a real transition we care about, bail.
return;
+ }
var section = event.target;
-
- // Disable WebKit transitions.
section.classList.remove('sliding');
+ if (!event.propertyName) {
+ // Only real transitions past this point.
+ return;
+ }
+
if (section.style.height == '0px') {
// Hide the content so it can't get tab focus.
section.hidden = true;
@@ -708,9 +830,10 @@ cr.define('options', function() {
}
},
+ /** @private */
updateAdvancedSettingsExpander_: function() {
var expander = $('advanced-settings-expander');
- if ($('advanced-settings').style.height == '')
+ if (BrowserOptions.shouldShowSection_($('advanced-settings')))
expander.textContent = loadTimeData.getString('showAdvancedSettings');
else
expander.textContent = loadTimeData.getString('hideAdvancedSettings');
@@ -726,22 +849,25 @@ cr.define('options', function() {
if (!syncData.signinAllowed &&
(!syncData.supervisedUser || !cr.isChromeOS)) {
$('sync-section').hidden = true;
+ this.maybeShowUserSection_();
return;
}
$('sync-section').hidden = false;
+ this.maybeShowUserSection_();
+
+ if (cr.isChromeOS && syncData.supervisedUser) {
+ var subSection = $('sync-section').firstChild;
+ while (subSection) {
+ if (subSection.nodeType == Node.ELEMENT_NODE)
+ subSection.hidden = true;
+ subSection = subSection.nextSibling;
+ }
- var subSection = $('sync-section').firstChild;
- while (subSection) {
- if (subSection.nodeType == Node.ELEMENT_NODE)
- subSection.hidden = syncData.supervisedUser;
- subSection = subSection.nextSibling;
- }
-
- if (syncData.supervisedUser) {
$('account-picture-wrapper').hidden = false;
$('sync-general').hidden = false;
$('sync-status').hidden = true;
+
return;
}
@@ -778,8 +904,8 @@ cr.define('options', function() {
// Disable the "sign in" button if we're currently signing in, or if we're
// already signed in and signout is not allowed.
var signInButton = $('start-stop-sync');
- signInButton.disabled = syncData.setupInProgress ||
- !syncData.signoutAllowed;
+ signInButton.disabled = syncData.setupInProgress;
+ this.signoutAllowed_ = syncData.signoutAllowed;
if (!syncData.signoutAllowed)
$('start-stop-sync-indicator').setAttribute('controlled-by', 'policy');
else
@@ -829,23 +955,27 @@ cr.define('options', function() {
customizeSyncButton.disabled =
syncData.hasUnrecoverableError ||
(!syncData.setupCompleted && !$('sync-action-link').hidden);
+ },
- // Move #enable-auto-login-checkbox to a different location on CrOS.
- if (cr.isChromeOs) {
- $('sync-general').insertBefore($('sync-status').nextSibling,
- $('enable-auto-login-checkbox'));
- }
- $('enable-auto-login-checkbox').hidden = !syncData.autoLoginVisible;
+ /**
+ * Update the UI depending on whether the current profile has a pairing for
+ * Easy Unlock.
+ * @param {boolean} hasPairing True if the current profile has a pairing.
+ */
+ updateEasyUnlock_: function(hasPairing) {
+ $('easy-unlock-setup').hidden = hasPairing;
+ $('easy-unlock-enable').hidden = !hasPairing;
},
/**
* Update the UI depending on whether the current profile manages any
* supervised users.
- * @param {boolean} value True if the current profile manages any supervised
+ * @param {boolean} show True if the current profile manages any supervised
* users.
*/
- updateManagesSupervisedUsers_: function(value) {
- $('profiles-supervised-dashboard-tip').hidden = !value;
+ updateManagesSupervisedUsers_: function(show) {
+ $('profiles-supervised-dashboard-tip').hidden = !show;
+ this.maybeShowUserSection_();
},
/**
@@ -878,6 +1008,18 @@ cr.define('options', function() {
},
/**
+ * Activates the Hotword section from the System settings page.
+ * @param {string} opt_error The error message to display.
+ * @param {string} opt_help_link The link to a troubleshooting page.
+ * @private
+ */
+ showHotwordSection_: function(opt_error, opt_help_link) {
+ $('hotword-search').hidden = false;
+ $('hotword-search-setting-indicator').errorText = opt_error;
+ $('hotword-search-setting-indicator').helpLink = opt_help_link;
+ },
+
+ /**
* Event listener for the 'homepage is NTP' preference. Updates the label
* next to the 'Change' button.
* @param {Event} event The preference change event.
@@ -928,12 +1070,13 @@ cr.define('options', function() {
onDefaultDownloadDirectoryChanged_: function(event) {
$('downloadLocationPath').value = event.value.value;
if (cr.isChromeOS) {
- // On ChromeOS, replace /special/drive/root with Drive for drive paths,
- // /home/chronos/user/Downloads or /home/chronos/u-<hash>/Downloads
- // with Downloads for local paths, and '/' with ' \u203a ' (angled quote
- // sign) everywhere. The modified path is used only for display purpose.
+ // On ChromeOS, replace /special/drive-<hash>/root with "Google Drive"
+ // for remote files, /home/chronos/user/Downloads or
+ // /home/chronos/u-<hash>/Downloads with "Downloads" for local paths,
+ // and '/' with ' \u203a ' (angled quote sign) everywhere. The modified
+ // path is used only for display purpose.
var path = $('downloadLocationPath').value;
- path = path.replace(/^\/special\/drive\/root/, 'Google Drive');
+ path = path.replace(/^\/special\/drive[^\/]*\/root/, 'Google Drive');
path = path.replace(/^\/home\/chronos\/(user|u-[^\/]*)\//, '');
path = path.replace(/\//g, ' \u203a ');
$('downloadLocationPath').value = path;
@@ -1092,7 +1235,8 @@ cr.define('options', function() {
* name: "Profile Name",
* iconURL: "chrome://path/to/icon/image",
* filePath: "/path/to/profile/data/on/disk",
- * isCurrentProfile: false
+ * isCurrentProfile: false,
+ * isManaged: false
* };
* @private
*/
@@ -1180,6 +1324,15 @@ cr.define('options', function() {
'There should always be a current profile, but none found.');
},
+ /**
+ * Propmpts user to confirm deletion of the profile for this browser
+ * window.
+ * @private
+ */
+ deleteCurrentProfile_: function() {
+ ManageProfileOverlay.showDeleteDialog(this.getCurrentProfile_());
+ },
+
setNativeThemeButtonEnabled_: function(enabled) {
var button = $('themes-native-button');
if (button)
@@ -1221,6 +1374,20 @@ cr.define('options', function() {
}
},
+ setWallpaperManaged_: function(managed) {
+ var button = $('set-wallpaper');
+ button.disabled = !!managed;
+
+ // Create a synthetic pref change event decorated as
+ // CoreOptionsHandler::CreateValueForPref() does.
+ var event = new Event('wallpaper');
+ if (managed)
+ event.value = { controlledBy: 'policy' };
+ else
+ event.value = {};
+ $('wallpaper-indicator').handlePrefChange(event);
+ },
+
/**
* Handle the 'add device' button click.
* @private
@@ -1266,17 +1433,6 @@ cr.define('options', function() {
},
/**
- * Set the visibility of the password generation checkbox.
- * @private
- */
- setPasswordGenerationSettingVisibility_: function(visible) {
- if (visible)
- $('password-generation-checkbox').style.display = 'block';
- else
- $('password-generation-checkbox').style.display = 'none';
- },
-
- /**
* Set the font size selected item. This item actually reflects two
* preferences: the default font size and the default fixed font size.
*
@@ -1351,9 +1507,6 @@ cr.define('options', function() {
* @private
*/
setAutoOpenFileTypesDisplayed_: function(display) {
- if (cr.isChromeOS)
- return;
-
if ($('advanced-settings').hidden) {
// If the Advanced section is hidden, don't animate the transition.
$('auto-open-file-types-section').hidden = !display;
@@ -1371,10 +1524,14 @@ cr.define('options', function() {
},
/**
- * Set the enabled state for the proxy settings button.
+ * Set the enabled state for the proxy settings button and its associated
+ * message when extension controlled.
+ * @param {boolean} disabled Whether the button should be disabled.
+ * @param {boolean} extensionControlled Whether the proxy is extension
+ * controlled.
* @private
*/
- setupProxySettingsSection_: function(disabled, extensionControlled) {
+ setupProxySettingsButton_: function(disabled, extensionControlled) {
if (!cr.isChromeOS) {
$('proxiesConfigureButton').disabled = disabled;
$('proxiesLabel').textContent =
@@ -1384,37 +1541,6 @@ cr.define('options', function() {
},
/**
- * Set the Cloud Print proxy UI to enabled, disabled, or processing.
- * @private
- */
- setupCloudPrintConnectorSection_: function(disabled, label, allowed) {
- if (!cr.isChromeOS) {
- $('cloudPrintConnectorLabel').textContent = label;
- if (disabled || !allowed) {
- $('cloudPrintConnectorSetupButton').textContent =
- loadTimeData.getString('cloudPrintConnectorDisabledButton');
- $('cloudPrintManageButton').style.display = 'none';
- } else {
- $('cloudPrintConnectorSetupButton').textContent =
- loadTimeData.getString('cloudPrintConnectorEnabledButton');
- $('cloudPrintManageButton').style.display = 'inline';
- }
- $('cloudPrintConnectorSetupButton').disabled = !allowed;
- }
- },
-
- /**
- * @private
- */
- removeCloudPrintConnectorSection_: function() {
- if (!cr.isChromeOS) {
- var connectorSectionElm = $('cloud-print-connector-section');
- if (connectorSectionElm)
- connectorSectionElm.parentNode.removeChild(connectorSectionElm);
- }
- },
-
- /**
* Set the initial state of the spoken feedback checkbox.
* @private
*/
@@ -1447,6 +1573,92 @@ cr.define('options', function() {
},
/**
+ * Adds hidden warning boxes for settings potentially controlled by
+ * extensions.
+ * @param {string} parentDiv The div name to append the bubble to.
+ * @param {string} bubbleId The ID to use for the bubble.
+ * @param {boolean} first Add as first node if true, otherwise last.
+ * @private
+ */
+ addExtensionControlledBox_: function(parentDiv, bubbleId, first) {
+ var bubble = $('extension-controlled-warning-template').cloneNode(true);
+ bubble.id = bubbleId;
+ var parent = $(parentDiv);
+ if (first)
+ parent.insertBefore(bubble, parent.firstChild);
+ else
+ parent.appendChild(bubble);
+ },
+
+ /**
+ * Adds a bubble showing that an extension is controlling a particular
+ * setting.
+ * @param {string} parentDiv The div name to append the bubble to.
+ * @param {string} bubbleId The ID to use for the bubble.
+ * @param {string} extensionId The ID of the controlling extension.
+ * @param {string} extensionName The name of the controlling extension.
+ * @private
+ */
+ toggleExtensionControlledBox_: function(
+ parentDiv, bubbleId, extensionId, extensionName) {
+ var bubble = $(bubbleId);
+ assert(bubble);
+ bubble.hidden = extensionId.length == 0;
+ if (bubble.hidden)
+ return;
+
+ // Set the extension image.
+ var div = bubble.firstElementChild;
+ div.style.backgroundImage =
+ 'url(chrome://extension-icon/' + extensionId + '/24/1)';
+
+ // Set the bubble label.
+ var label = loadTimeData.getStringF('extensionControlled', extensionName);
+ var docFrag = parseHtmlSubset('<div>' + label + '</div>', ['B', 'DIV']);
+ div.innerHTML = docFrag.firstChild.innerHTML;
+
+ // Wire up the button to disable the right extension.
+ var button = div.nextElementSibling;
+ button.dataset.extensionId = extensionId;
+ },
+
+ /**
+ * Toggles the warning boxes that show which extension is controlling
+ * various settings of Chrome.
+ * @param {object} details A dictionary of ID+name pairs for each of the
+ * settings controlled by an extension.
+ * @private
+ */
+ toggleExtensionIndicators_: function(details) {
+ this.toggleExtensionControlledBox_('search-section-content',
+ 'search-engine-controlled',
+ details.searchEngine.id,
+ details.searchEngine.name);
+ this.toggleExtensionControlledBox_('extension-controlled-container',
+ 'homepage-controlled',
+ details.homePage.id,
+ details.homePage.name);
+ this.toggleExtensionControlledBox_('startup-section-content',
+ 'startpage-controlled',
+ details.startUpPage.id,
+ details.startUpPage.name);
+ this.toggleExtensionControlledBox_('newtab-section-content',
+ 'newtab-controlled',
+ details.newTabPage.id,
+ details.newTabPage.name);
+ this.toggleExtensionControlledBox_('proxy-section-content',
+ 'proxy-controlled',
+ details.proxy.id,
+ details.proxy.name);
+
+ // The proxy section contains just the warning box and nothing else, so
+ // if we're hiding the proxy warning box, we should also hide its header
+ // section.
+ $('proxy-section').hidden = details.proxy.id.length == 0;
+ },
+
+
+ /**
* Show/hide touchpad-related settings.
* @private
*/
@@ -1550,12 +1762,44 @@ cr.define('options', function() {
*/
showImagerPickerOverlay_: function() {
OptionsPage.navigateToPage('changePicture');
- }
+ },
+
+ /**
+ * Shows (or not) the "User" section of the settings page based on whether
+ * any of the sub-sections are present (or not).
+ * @private
+ */
+ maybeShowUserSection_: function() {
+ $('sync-users-section').hidden =
+ $('profiles-section').hidden &&
+ $('sync-section').hidden &&
+ $('profiles-supervised-dashboard-tip').hidden;
+ },
+
+ /**
+ * Updates the date and time section with time sync information.
+ * @param {boolean} canSetTime Whether the system time can be set.
+ * @private
+ */
+ setCanSetTime_: function(canSetTime) {
+ // If the time has been network-synced, it cannot be set manually.
+ $('time-synced-explanation').hidden = canSetTime;
+ $('set-time').hidden = !canSetTime;
+ },
+
+ /**
+ * Handle the 'set date and time' button click.
+ * @private
+ */
+ handleSetTime_: function() {
+ chrome.send('showSetTime');
+ },
};
//Forward public APIs to private implementations.
[
'addBluetoothDevice',
+ 'deleteCurrentProfile',
'enableCertificateButton',
'enableFactoryResetSection',
'getCurrentProfile',
@@ -1563,35 +1807,37 @@ cr.define('options', function() {
'hideBluetoothSettings',
'notifyInitializationComplete',
'removeBluetoothDevice',
- 'removeCloudPrintConnectorSection',
'scrollToSection',
'setAccountPictureManaged',
+ 'setWallpaperManaged',
'setAutoOpenFileTypesDisplayed',
'setBluetoothState',
+ 'setCanSetTime',
'setFontSize',
'setNativeThemeButtonEnabled',
'setHighContrastCheckboxState',
'setMetricsReportingCheckboxState',
'setMetricsReportingSettingVisibility',
- 'setPasswordGenerationSettingVisibility',
'setProfilesInfo',
'setSpokenFeedbackCheckboxState',
'setThemesResetButtonEnabled',
'setVirtualKeyboardCheckboxState',
- 'setupCloudPrintConnectorSection',
'setupPageZoomSelector',
- 'setupProxySettingsSection',
+ 'setupProxySettingsButton',
'showBluetoothSettings',
'showCreateProfileError',
'showCreateProfileSuccess',
'showCreateProfileWarning',
+ 'showHotwordSection',
'showManagedUserImportError',
'showManagedUserImportSuccess',
'showMouseControls',
'showTouchpadControls',
+ 'toggleExtensionIndicators',
'updateAccountPicture',
'updateAutoLaunchState',
'updateDefaultBrowserState',
+ 'updateEasyUnlock',
'updateManagesSupervisedUsers',
'updateSearchEngines',
'updateStartupPages',
diff --git a/chromium/chrome/browser/resources/options/browser_options_profile_list.js b/chromium/chrome/browser/resources/options/browser_options_profile_list.js
index 7a60ca3cf16..429780ede63 100644
--- a/chromium/chrome/browser/resources/options/browser_options_profile_list.js
+++ b/chromium/chrome/browser/resources/options/browser_options_profile_list.js
@@ -9,7 +9,7 @@ cr.define('options.browser_options', function() {
/**
* Creates a new profile list item.
- * @param {Object} profileInfo The profile this item respresents.
+ * @param {Object} profileInfo The profile this item represents.
* @constructor
* @extends {cr.ui.DeletableItem}
*/
@@ -52,16 +52,19 @@ cr.define('options.browser_options', function() {
var profileInfo = this.profileInfo_;
+ var containerEl = this.ownerDocument.createElement('div');
+ containerEl.className = 'profile-container';
+
var iconEl = this.ownerDocument.createElement('img');
iconEl.className = 'profile-img';
- iconEl.style.content = imageset(profileInfo.iconURL + '@scalefactorx');
- this.contentElement.appendChild(iconEl);
+ iconEl.style.content = getProfileAvatarIcon(profileInfo.iconURL);
+ containerEl.appendChild(iconEl);
var nameEl = this.ownerDocument.createElement('div');
nameEl.className = 'profile-name';
if (profileInfo.isCurrentProfile)
nameEl.classList.add('profile-item-current');
- this.contentElement.appendChild(nameEl);
+ containerEl.appendChild(nameEl);
var displayName = profileInfo.name;
if (profileInfo.isCurrentProfile) {
@@ -70,6 +73,16 @@ cr.define('options.browser_options', function() {
}
nameEl.textContent = displayName;
+ if (profileInfo.isManaged) {
+ var supervisedEl = this.ownerDocument.createElement('div');
+ supervisedEl.className = 'profile-supervised';
+ supervisedEl.textContent =
+ '(' + loadTimeData.getStringF('managedUserLabel') + ')';
+ containerEl.appendChild(supervisedEl);
+ }
+
+ this.contentElement.appendChild(containerEl);
+
// Ensure that the button cannot be tabbed to for accessibility reasons.
this.closeButtonElement.tabIndex = -1;
},
@@ -116,7 +129,7 @@ cr.define('options.browser_options', function() {
},
/**
- * If false, items in this list will not be deltable.
+ * If false, items in this list will not be deletable.
* @private
*/
canDeleteItems_: true,
@@ -126,4 +139,3 @@ cr.define('options.browser_options', function() {
ProfileList: ProfileList
};
});
-
diff --git a/chromium/chrome/browser/resources/options/certificate_manager.html b/chromium/chrome/browser/resources/options/certificate_manager.html
index 3d28e7f2b9f..30fe9dc620a 100644
--- a/chromium/chrome/browser/resources/options/certificate_manager.html
+++ b/chromium/chrome/browser/resources/options/certificate_manager.html
@@ -1,6 +1,6 @@
<div id="certificateManagerPage" class="page" hidden>
<div class="close-button"></div>
- <h1 i18n-content="certificateManagerPage"></h1>
+ <h1 id='cert-manager-header' i18n-content="certificateManagerPage"></h1>
<div id="certificate-manager-content-area" class="content-area">
<!-- Navigation tabs -->
<div class="subpages-nav-tabs">
@@ -42,9 +42,9 @@
disabled>
</button>
<button id="personalCertsTab-import"
- i18n-content="import_certificate">
+ i18n-content="import_certificate" disabled>
</button>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<button id="personalCertsTab-import-and-bind"
i18n-content="importAndBindCertificate" disabled>
</button>
@@ -72,7 +72,8 @@
<button id="serverCertsTab-view" i18n-content="view_certificate"
disabled>
</button>
- <button id="serverCertsTab-import" i18n-content="import_certificate">
+ <button id="serverCertsTab-import" i18n-content="import_certificate"
+ disabled>
</button>
<button id="serverCertsTab-export" i18n-content="export_certificate"
disabled>
@@ -101,7 +102,7 @@
disabled>
</button>
<button id="caCertsTab-import" i18n-content="import_certificate"
- ></button>
+ disabled></button>
<button id="caCertsTab-export" i18n-content="export_certificate"
disabled>
</button>
diff --git a/chromium/chrome/browser/resources/options/certificate_manager.js b/chromium/chrome/browser/resources/options/certificate_manager.js
index 5620b80c6c2..b2d46e9dc0c 100644
--- a/chromium/chrome/browser/resources/options/certificate_manager.js
+++ b/chromium/chrome/browser/resources/options/certificate_manager.js
@@ -11,8 +11,9 @@ cr.define('options', function() {
/**
* blah
* @param {!string} id The id of this tab.
+ * @param {boolean} isKiosk True if dialog is shown during CrOS kiosk launch.
*/
- function CertificateManagerTab(id) {
+ function CertificateManagerTab(id, isKiosk) {
this.tree = $(id + '-tree');
options.CertificatesTree.decorate(this.tree);
@@ -44,24 +45,36 @@ cr.define('options', function() {
this.backupButton = $(id + '-backup');
if (this.backupButton !== null) {
- this.backupButton.onclick = function(e) {
- var selected = tree.selectedItem;
- chrome.send('exportPersonalCertificate', [selected.data.id]);
+ if (id == 'personalCertsTab' && isKiosk) {
+ this.backupButton.hidden = true;
+ } else {
+ this.backupButton.onclick = function(e) {
+ var selected = tree.selectedItem;
+ chrome.send('exportPersonalCertificate', [selected.data.id]);
+ }
}
}
this.backupAllButton = $(id + '-backup-all');
if (this.backupAllButton !== null) {
- this.backupAllButton.onclick = function(e) {
- chrome.send('exportAllPersonalCertificates');
+ if (id == 'personalCertsTab' && isKiosk) {
+ this.backupAllButton.hidden = true;
+ } else {
+ this.backupAllButton.onclick = function(e) {
+ chrome.send('exportAllPersonalCertificates');
+ }
}
}
this.importButton = $(id + '-import');
if (this.importButton !== null) {
if (id == 'personalCertsTab') {
- this.importButton.onclick = function(e) {
- chrome.send('importPersonalCertificate', [false]);
+ if (isKiosk) {
+ this.importButton.hidden = true;
+ } else {
+ this.importButton.onclick = function(e) {
+ chrome.send('importPersonalCertificate', [false]);
+ }
}
} else if (id == 'serverCertsTab') {
this.importButton.onclick = function(e) {
@@ -85,9 +98,13 @@ cr.define('options', function() {
this.exportButton = $(id + '-export');
if (this.exportButton !== null) {
- this.exportButton.onclick = function(e) {
- var selected = tree.selectedItem;
- chrome.send('exportCertificate', [selected.data.id]);
+ if (id == 'personalCertsTab' && isKiosk) {
+ this.exportButton.hidden = true;
+ } else {
+ this.exportButton.onclick = function(e) {
+ var selected = tree.selectedItem;
+ chrome.send('exportCertificate', [selected.data.id]);
+ }
}
}
@@ -146,26 +163,6 @@ cr.define('options', function() {
},
};
- // TODO(xiyuan): Use notification from backend instead of polling.
- // TPM token check polling timer.
- var tpmPollingTimer;
-
- // Initiate tpm token check if needed.
- function checkTpmToken() {
- var importAndBindButton = $('personalCertsTab-import-and-bind');
-
- if (importAndBindButton && importAndBindButton.disabled)
- chrome.send('checkTpmTokenReady');
- }
-
- // Stop tpm polling timer.
- function stopTpmTokenCheckPolling() {
- if (tpmPollingTimer) {
- window.clearTimeout(tpmPollingTimer);
- tpmPollingTimer = undefined;
- }
- }
-
/////////////////////////////////////////////////////////////////////////////
// CertificateManager class:
@@ -184,13 +181,14 @@ cr.define('options', function() {
CertificateManager.prototype = {
__proto__: OptionsPage.prototype,
- initializePage: function() {
+ initializePage: function(isKiosk) {
OptionsPage.prototype.initializePage.call(this);
- this.personalTab = new CertificateManagerTab('personalCertsTab');
- this.serverTab = new CertificateManagerTab('serverCertsTab');
- this.caTab = new CertificateManagerTab('caCertsTab');
- this.otherTab = new CertificateManagerTab('otherCertsTab');
+ this.personalTab = new CertificateManagerTab('personalCertsTab',
+ !!isKiosk);
+ this.serverTab = new CertificateManagerTab('serverCertsTab', !!isKiosk);
+ this.caTab = new CertificateManagerTab('caCertsTab', !!isKiosk);
+ this.otherTab = new CertificateManagerTab('otherCertsTab', !!isKiosk);
this.addEventListener('visibleChange', this.handleVisibleChange_);
@@ -212,14 +210,6 @@ cr.define('options', function() {
OptionsPage.showTab($('personal-certs-nav-tab'));
chrome.send('populateCertificateManager');
}
-
- if (cr.isChromeOS) {
- // Ensure TPM token check on visible and stop polling when hidden.
- if (this.visible)
- checkTpmToken();
- else
- stopTpmTokenCheckPolling();
- }
}
};
@@ -236,16 +226,15 @@ cr.define('options', function() {
CertificateRestoreOverlay.show();
};
- CertificateManager.onCheckTpmTokenReady = function(ready) {
- var importAndBindButton = $('personalCertsTab-import-and-bind');
- if (importAndBindButton) {
- importAndBindButton.disabled = !ready;
-
- // Check again after 5 seconds if Tpm is not ready and certificate manager
- // is still visible.
- if (!ready && CertificateManager.getInstance().visible)
- tpmPollingTimer = window.setTimeout(checkTpmToken, 5000);
- }
+ CertificateManager.onModelReady = function(userDbAvailable,
+ tpmAvailable) {
+ if (!userDbAvailable)
+ return;
+ if (tpmAvailable)
+ $('personalCertsTab-import-and-bind').disabled = false;
+ $('personalCertsTab-import').disabled = false;
+ $('serverCertsTab-import').disabled = false;
+ $('caCertsTab-import').disabled = false;
};
// Export
diff --git a/chromium/chrome/browser/resources/options/chromeos/accounts_options.html b/chromium/chrome/browser/resources/options/chromeos/accounts_options.html
index d0fc3bd892b..2ddc846d232 100644
--- a/chromium/chrome/browser/resources/options/chromeos/accounts_options.html
+++ b/chromium/chrome/browser/resources/options/chromeos/accounts_options.html
@@ -12,8 +12,9 @@
<td class="option-name">
<div class="checkbox">
<label>
- <input id="allowBwsiCheck" pref="cros.accounts.allowBWSI"
- type="checkbox">
+ <input id="allowBwsiCheck" type="checkbox"
+ metric="Options_GuestBrowsing"
+ pref="cros.accounts.allowBWSI">
<span i18n-content="allow_BWSI"></span>
</label>
</div>
@@ -22,9 +23,22 @@
<tr>
<td class="option-name">
<div class="checkbox">
+ <label>
+ <input id="allowSupervisedCheck" type="checkbox"
+ metric="Options_SupervisedUsers"
+ pref="cros.accounts.supervisedUsersEnabled">
+ <span i18n-content="allow_supervised_users"></span>
+ </label>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="option-name">
+ <div class="checkbox">
<label>
- <input id="showUserNamesCheck"
- pref="cros.accounts.showUserNamesOnSignIn" type="checkbox">
+ <input id="showUserNamesCheck" type="checkbox"
+ metric="Options_ShowUserNamesOnSignin"
+ pref="cros.accounts.showUserNamesOnSignIn">
<span i18n-content="show_user_on_signin"></span>
</label>
</div>
@@ -34,8 +48,10 @@
<td class="option-name">
<div class="checkbox">
<label>
- <input id="useWhitelistCheck" pref="cros.accounts.allowGuest"
- type="checkbox" inverted_pref>
+ <input id="useWhitelistCheck" type="checkbox"
+ metric="Options_AllowAllUsers"
+ pref="cros.accounts.allowGuest"
+ inverted_pref>
<span i18n-content="use_whitelist"></span>
</label>
</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/accounts_options.js b/chromium/chrome/browser/resources/options/chromeos/accounts_options.js
index eddbbaf3d31..d187f0b82ca 100644
--- a/chromium/chrome/browser/resources/options/chromeos/accounts_options.js
+++ b/chromium/chrome/browser/resources/options/chromeos/accounts_options.js
@@ -117,6 +117,8 @@ cr.define('options', function() {
*/
handleAddUser_: function(e) {
chrome.send('whitelistUser', [e.user.email, e.user.name]);
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_WhitelistedUser_Add']);
},
/**
@@ -126,6 +128,8 @@ cr.define('options', function() {
*/
handleRemoveUser_: function(e) {
chrome.send('unwhitelistUser', [e.user.username]);
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_WhitelistedUser_Remove']);
}
};
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth.css b/chromium/chrome/browser/resources/options/chromeos/bluetooth.css
index e6a91e40705..3c849a981ed 100644
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth.css
+++ b/chromium/chrome/browser/resources/options/chromeos/bluetooth.css
@@ -23,12 +23,14 @@
-webkit-box-pack: justify;
}
-#bluetooth-options .button-strip #bluetooth-scanning-label {
+#bluetooth-options .button-strip #bluetooth-scanning-label,
+#bluetooth-options .button-strip #bluetooth-scan-stopped-label {
-webkit-box-flex: 1;
display: block;
}
-#bluetooth-scanning-label {
+#bluetooth-scanning-label,
+#bluetooth-scan-stopped-label {
-webkit-margin-start: 5px;
color: #999;
}
@@ -106,17 +108,15 @@
.bluetooth-keyboard-button {
-webkit-padding-end: 15px;
-webkit-padding-start: 15px;
- background-image: -webkit-gradient(linear,
- left top,
- left bottom,
- color-stop(0, #e9e9e9),
- color-stop(1, #f5f5f5));
- border: 1px solid #d4d4d4;
+ background-image: linear-gradient(to bottom,
+ #e9e9e9,
+ #f5f5f5);
+ border: 1px solid #ccc;
border-radius: 4px;
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.07),
+ box-shadow: 0 0 0 1px #888,
inset 0 1px 1px 1px #fff,
- inset 0 -1px 1px 1px #ddd;
- color: #666;
+ inset 0 -1px 1px 1px #eee;
+ color: #222;
display: inline-block;
font-size: 14px;
font-weight: 600;
@@ -150,13 +150,24 @@
}
.bluetooth-keyboard-button.key-typed {
- border: 1px solid #ccc;
- box-shadow: 0 0 0 1px #888,
- inset 0 1px 1px 1px #fff,
- inset 0 -1px 1px 1px #eee;
color: #222;
}
-.bluetooth-keyboard-button.key-pin {
- color: #222;
+.bluetooth-keyboard-button.key-next {
+ background-image: -webkit-linear-gradient(top,
+ rgb(77, 144, 254),
+ rgb(71, 135, 237));
+ border: 1px solid rgb(77, 144, 254);
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.07),
+ inset 0 1px 1px 1px #fff,
+ inset 0 -1px 1px 1px rgb(77, 144, 254);
+ color: #fff;
+}
+
+.bluetooth-keyboard-button.key-untyped {
+ border: 1px solid #d4d4d4;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.07),
+ inset 0 1px 1px 1px #fff,
+ inset 0 -1px 1px 1px #ddd;
+ color: #666;
}
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html b/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html
index 534d9634d30..dcb87aba490 100644
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html
+++ b/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.html
@@ -18,6 +18,9 @@
<span id="bluetooth-scanning-label"
i18n-content="bluetoothScanning">
</span>
+ <span id="bluetooth-scan-stopped-label"
+ i18n-content="bluetoothScanStopped">
+ </span>
<div id="bluetooth-scanning-icon" class="inline-spinner"></div>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js b/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js
index 3b076a1f26f..004cc6b3ee2 100644
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js
+++ b/chromium/chrome/browser/resources/options/chromeos/bluetooth_add_device_overlay.js
@@ -33,8 +33,9 @@ cr.define('options', function() {
OptionsPage.prototype.initializePage.call(this);
this.createDeviceList_();
+ BluetoothOptions.updateDiscoveryState(true);
+
$('bluetooth-add-device-cancel-button').onclick = function(event) {
- chrome.send('stopBluetoothDeviceDiscovery');
OptionsPage.closeOverlay();
};
@@ -42,7 +43,6 @@ cr.define('options', function() {
$('bluetooth-add-device-apply-button').onclick = function(event) {
var device = self.deviceList_.selectedItem;
var address = device.address;
- chrome.send('stopBluetoothDeviceDiscovery');
OptionsPage.closeOverlay();
device.pairing = 'bluetoothStartConnecting';
options.BluetoothPairing.showDialog(device);
@@ -68,6 +68,11 @@ cr.define('options', function() {
});
},
+ /** @override */
+ didClosePage: function() {
+ chrome.send('stopBluetoothDeviceDiscovery');
+ },
+
/**
* Creates, decorates and initializes the bluetooth device list.
* @private
@@ -82,11 +87,30 @@ cr.define('options', function() {
* Automatically start the device discovery process if the
* "Add device" dialog is visible.
*/
- BluetoothOptions.updateDiscovery = function() {
+ BluetoothOptions.startDeviceDiscovery = function() {
var page = BluetoothOptions.getInstance();
if (page && page.visible)
chrome.send('findBluetoothDevices');
- }
+ };
+
+ /**
+ * Updates the dialog to show that device discovery has stopped. Updates the
+ * label text and hides/unhides the spinner. based on discovery state.
+ */
+ BluetoothOptions.updateDiscoveryState = function(discovering) {
+ $('bluetooth-scanning-label').hidden = !discovering;
+ $('bluetooth-scanning-icon').hidden = !discovering;
+ $('bluetooth-scan-stopped-label').hidden = discovering;
+ };
+
+ /**
+ * If the "Add device" dialog is visible, dismiss it.
+ */
+ BluetoothOptions.dismissOverlay = function() {
+ var page = BluetoothOptions.getInstance();
+ if (page && page.visible)
+ OptionsPage.closeOverlay();
+ };
// Export
return {
diff --git a/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js b/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js
index a206e8bf72a..acaa0afab39 100644
--- a/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js
+++ b/chromium/chrome/browser/resources/options/chromeos/bluetooth_pair_device_overlay.js
@@ -86,6 +86,7 @@ cr.define('options', function() {
$('bluetooth-pair-device-reject-button').onclick = function() {
chrome.send('updateBluetoothDevice',
[self.device_.address, 'reject']);
+ self.device_.pairing = PAIRING.DISMISSED;
OptionsPage.closeOverlay();
};
$('bluetooth-pair-device-connect-button').onclick = function() {
@@ -104,7 +105,8 @@ cr.define('options', function() {
$('bluetooth-pair-device-accept-button').onclick = function() {
chrome.send('updateBluetoothDevice',
[self.device_.address, 'accept']);
- OptionsPage.closeOverlay();
+ // Prevent sending a 'accept' command twice.
+ $('bluetooth-pair-device-accept-button').disabled = true;
};
$('bluetooth-pair-device-dismiss-button').onclick = function() {
OptionsPage.closeOverlay();
@@ -182,19 +184,20 @@ cr.define('options', function() {
// Update visibility of dialog elements.
if (this.device_.passkey) {
- this.updatePasskey_();
+ this.updatePasskey_(String(this.device_.passkey));
if (this.device_.pairing == PAIRING.CONFIRM_PASSKEY) {
// Confirming a match between displayed passkeys.
this.displayElements_(['bluetooth-pairing-passkey-display',
'bluetooth-pair-device-accept-button',
'bluetooth-pair-device-reject-button']);
+ $('bluetooth-pair-device-accept-button').disabled = false;
} else {
// Remote entering a passkey.
this.displayElements_(['bluetooth-pairing-passkey-display',
'bluetooth-pair-device-cancel-button']);
}
} else if (this.device_.pincode) {
- this.updatePinCode_();
+ this.updatePasskey_(String(this.device_.pincode));
this.displayElements_(['bluetooth-pairing-passkey-display',
'bluetooth-pair-device-cancel-button']);
} else if (this.device_.pairing == PAIRING.ENTER_PIN_CODE) {
@@ -267,14 +270,15 @@ cr.define('options', function() {
},
/**
- * Formats an element for displaying the passkey.
+ * Formats an element for displaying the passkey or PIN code.
+ * @param {string} key Passkey or PIN to display.
*/
- updatePasskey_: function() {
+ updatePasskey_: function(key) {
var passkeyEl = $('bluetooth-pairing-passkey-display');
- var keyClass = this.device_.pairing == PAIRING.REMOTE_PASSKEY ?
+ var keyClass = (this.device_.pairing == PAIRING.REMOTE_PASSKEY ||
+ this.device_.pairing == PAIRING.REMOTE_PIN_CODE) ?
'bluetooth-keyboard-button' : 'bluetooth-passkey-char';
this.clearElement_(passkeyEl);
- var key = String(this.device_.passkey);
// Passkey should always have 6 digits.
key = '000000'.substring(0, 6 - key.length) + key;
var progress = this.device_.entered;
@@ -282,52 +286,32 @@ cr.define('options', function() {
var keyEl = document.createElement('span');
keyEl.textContent = key.charAt(i);
keyEl.className = keyClass;
- if (progress == undefined)
- keyEl.classList.add('key-pin');
- else if (i < progress)
- keyEl.classList.add('key-typed');
- passkeyEl.appendChild(keyEl);
- }
- if (this.device_.pairing == PAIRING.REMOTE_PASSKEY) {
- // Add enter key.
- var label = loadTimeData.getString('bluetoothEnterKey');
- var keyEl = document.createElement('span');
- keyEl.textContent = label;
- keyEl.className = keyClass;
- keyEl.id = 'bluetooth-enter-key';
- if (progress == undefined)
- keyEl.classList.add('key-pin');
- else if (progress > key.length)
- keyEl.classList.add('key-typed');
- passkeyEl.appendChild(keyEl);
- }
- passkeyEl.hidden = false;
- },
-
- /**
- * Formats an element for displaying the PIN code.
- */
- updatePinCode_: function() {
- var passkeyEl = $('bluetooth-pairing-passkey-display');
- var keyClass = this.device_.pairing == PAIRING.REMOTE_PIN_CODE ?
- 'bluetooth-keyboard-button' : 'bluetooth-passkey-char';
- this.clearElement_(passkeyEl);
- var key = String(this.device_.pincode);
- for (var i = 0; i < key.length; i++) {
- var keyEl = document.createElement('span');
- keyEl.textContent = key.charAt(i);
- keyEl.className = keyClass;
- keyEl.classList.add('key-pin');
+ if (progress != undefined) {
+ if (i < progress)
+ keyEl.classList.add('key-typed');
+ else if (i == progress)
+ keyEl.classList.add('key-next');
+ else
+ keyEl.classList.add('key-untyped');
+ }
passkeyEl.appendChild(keyEl);
}
- if (this.device_.pairing == PAIRING.REMOTE_PIN_CODE) {
+ if (this.device_.pairing == PAIRING.REMOTE_PASSKEY ||
+ this.device_.pairing == PAIRING.REMOTE_PIN_CODE) {
// Add enter key.
var label = loadTimeData.getString('bluetoothEnterKey');
var keyEl = document.createElement('span');
keyEl.textContent = label;
keyEl.className = keyClass;
- keyEl.classList.add('key-pin');
keyEl.id = 'bluetooth-enter-key';
+ if (progress != undefined) {
+ if (progress > key.length)
+ keyEl.classList.add('key-typed');
+ else if (progress == key.length)
+ keyEl.classList.add('key-next');
+ else
+ keyEl.classList.add('key-untyped');
+ }
passkeyEl.appendChild(keyEl);
}
passkeyEl.hidden = false;
diff --git a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.css b/chromium/chrome/browser/resources/options/chromeos/change_picture_options.css
index ab0d497df17..d68291a6e9c 100644
--- a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.css
+++ b/chromium/chrome/browser/resources/options/chromeos/change_picture_options.css
@@ -54,13 +54,17 @@
*/
#user-image-preview {
- margin: 20px 10px 0 0;
+ margin: 18px 10px 0 0;
max-width: 220px;
position: relative;
}
#user-image-preview .perspective-box {
-webkit-perspective: 600px;
+ border: solid 1px #cacaca;
+ border-radius: 4px;
+ padding: 3px;
+ width: 220px;
}
#user-image-preview-img {
@@ -69,7 +73,7 @@
border-radius: 4px;
max-height: 220px;
max-width: 220px;
- padding: 2px;
+ padding: 3px;
}
.camera.live #user-image-preview-img {
@@ -168,14 +172,14 @@ html[dir=rtl] #flip-photo {
#take-photo {
display: none;
height: 25px;
- margin: 4px 1px;
+ margin: 4px;
padding: 0;
width: 220px;
}
.camera:not(.live) #discard-photo {
background: url('chrome://theme/IDR_USER_IMAGE_RECYCLE')
- no-repeat center 0;
+ no-repeat center center;
display: block;
}
diff --git a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.html b/chromium/chrome/browser/resources/options/chromeos/change_picture_options.html
index 571555750df..146585dc904 100644
--- a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.html
+++ b/chromium/chrome/browser/resources/options/chromeos/change_picture_options.html
@@ -4,7 +4,7 @@
<div class="content-area">
<div i18n-content="changePicturePageDescription"></div>
<div id="user-images-area">
- <grid id="user-image-grid" class="user-image-picker"></grid>
+ <grid id="user-image-grid" class="user-image-picker" tabindex="1"></grid>
<div id="user-image-preview">
<img id="user-image-preview-img" i18n-values="alt:previewAltText">
<div class="user-image-stream-area">
@@ -15,9 +15,12 @@
</div>
<div class="spinner"></div>
</div>
- <button id="flip-photo" class="custom-appearance"></button>
- <button id="discard-photo"></button>
- <button id="take-photo"></button>
+ <button id="discard-photo" i18n-values="title:discardPhoto"
+ tabindex="2"></button>
+ <button id="take-photo" i18n-values="title:takePhoto" tabindex="2">
+ </button>
+ <button id="flip-photo" class="custom-appearance"
+ i18n-values="title:flipPhoto" tabindex="1"></button>
</div>
</div>
<div id="user-image-attribution">
@@ -28,7 +31,8 @@
</div>
<div class="action-area">
<div class="button-strip">
- <button id="change-picture-overlay-confirm" i18n-content="done"></button>
+ <button id="change-picture-overlay-confirm" i18n-content="done"
+ tabindex="2"></button>
</div>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.js b/chromium/chrome/browser/resources/options/chromeos/change_picture_options.js
index 51ed5364e26..93982ea69c3 100644
--- a/chromium/chrome/browser/resources/options/chromeos/change_picture_options.js
+++ b/chromium/chrome/browser/resources/options/chromeos/change_picture_options.js
@@ -66,9 +66,6 @@ cr.define('options', function() {
imageGrid.addEventListener('photoupdated',
this.handlePhotoTaken_.bind(this));
- // Set the title for "Take Photo" button.
- imageGrid.cameraTitle = loadTimeData.getString('takePhoto');
-
// Add the "Choose file" button.
imageGrid.addItem(ButtonImages.CHOOSE_FILE,
loadTimeData.getString('chooseFile'),
@@ -80,17 +77,19 @@ cr.define('options', function() {
loadTimeData.getString('profilePhotoLoading'));
this.profileImage_.type = 'profile';
+ // Set the title for camera item in the grid.
+ imageGrid.setCameraTitles(
+ loadTimeData.getString('takePhoto'),
+ loadTimeData.getString('photoFromCamera'));
+
$('take-photo').addEventListener(
'click', this.handleTakePhoto_.bind(this));
$('discard-photo').addEventListener(
- 'click', imageGrid.discardPhoto.bind(imageGrid));
+ 'click', this.handleDiscardPhoto_.bind(this));
// Toggle 'animation' class for the duration of WebKit transition.
$('flip-photo').addEventListener(
- 'click', function(e) {
- previewElement.classList.add('animation');
- imageGrid.flipPhoto = !imageGrid.flipPhoto;
- });
+ 'click', this.handleFlipPhoto_.bind(this));
$('user-image-stream-crop').addEventListener(
'webkitTransitionEnd', function(e) {
previewElement.classList.remove('animation');
@@ -131,6 +130,7 @@ cr.define('options', function() {
imageGrid.removeItem(this.oldImage_);
this.oldImage_ = null;
}
+ chrome.send('onChangePicturePageHidden');
},
/**
@@ -152,11 +152,24 @@ cr.define('options', function() {
},
/**
+ * Handle camera-photo flip.
+ */
+ handleFlipPhoto_: function() {
+ var imageGrid = $('user-image-grid');
+ imageGrid.previewElement.classList.add('animation');
+ imageGrid.flipPhoto = !imageGrid.flipPhoto;
+ var flipMessageId = imageGrid.flipPhoto ?
+ 'photoFlippedAccessibleText' : 'photoFlippedBackAccessibleText';
+ announceAccessibleMessage(loadTimeData.getString(flipMessageId));
+ },
+
+ /**
* Handles "Take photo" button click.
* @private
*/
handleTakePhoto_: function() {
$('user-image-grid').takePhoto();
+ chrome.send('takePhoto');
},
/**
@@ -165,6 +178,19 @@ cr.define('options', function() {
*/
handlePhotoTaken_: function(e) {
chrome.send('photoTaken', [e.dataURL]);
+ announceAccessibleMessage(
+ loadTimeData.getString('photoCaptureAccessibleText'));
+ },
+
+ /**
+ * Handles "Discard photo" button click.
+ * @private
+ */
+ handleDiscardPhoto_: function() {
+ $('user-image-grid').discardPhoto();
+ chrome.send('discardPhoto');
+ announceAccessibleMessage(
+ loadTimeData.getString('photoDiscardAccessibleText'));
},
/**
@@ -184,6 +210,10 @@ cr.define('options', function() {
handleImageSelected_: function(e) {
var imageGrid = $('user-image-grid');
var url = imageGrid.selectedItemUrl;
+
+ // Flip button available only for camera picture.
+ imageGrid.flipPhotoElement.tabIndex =
+ imageGrid.selectionType == 'camera' ? 1 : -1;
// Ignore selection change caused by program itself and selection of one
// of the action buttons.
if (!imageGrid.inProgramSelection &&
@@ -289,7 +319,7 @@ cr.define('options', function() {
setDefaultImages_: function(imagesData) {
var imageGrid = $('user-image-grid');
for (var i = 0, data; data = imagesData[i]; i++) {
- var item = imageGrid.addItem(data.url);
+ var item = imageGrid.addItem(data.url, data.title);
item.type = 'default';
item.author = data.author || '';
item.website = data.website || '';
diff --git a/chromium/chrome/browser/resources/options/chromeos/display_options.html b/chromium/chrome/browser/resources/options/chromeos/display_options.html
index 989e7ed3da0..87d23de74c5 100644
--- a/chromium/chrome/browser/resources/options/chromeos/display_options.html
+++ b/chromium/chrome/browser/resources/options/chromeos/display_options.html
@@ -46,6 +46,15 @@
i18n-content="startCalibratingOverscan">
</button>
</div>
+ <div class="selected-display-option-row"
+ id="selected-display-color-profile-row">
+ <div class="selected-display-option-title"
+ i18n-content="selectedDisplayColorProfile">
+ </div>
+ <select id="display-options-color-profile-selection"
+ class="display-options-button">
+ </select>
+ </div>
</div>
</div>
<!-- The arrow of display-configuration is achieved by a div
diff --git a/chromium/chrome/browser/resources/options/chromeos/display_options.js b/chromium/chrome/browser/resources/options/chromeos/display_options.js
index 3b000ca283e..e0285c26fd4 100644
--- a/chromium/chrome/browser/resources/options/chromeos/display_options.js
+++ b/chromium/chrome/browser/resources/options/chromeos/display_options.js
@@ -178,12 +178,18 @@ cr.define('options', function() {
chrome.send('setOrientation', [this.displays_[this.focusedIndex_].id,
ev.target.value]);
}.bind(this);
+ $('display-options-color-profile-selection').onchange = function(ev) {
+ chrome.send('setColorProfile', [this.displays_[this.focusedIndex_].id,
+ ev.target.value]);
+ }.bind(this);
$('selected-display-start-calibrating-overscan').onclick = function() {
// Passes the target display ID. Do not specify it through URL hash,
// we do not care back/forward.
var displayOverscan = options.DisplayOverscan.getInstance();
displayOverscan.setDisplayId(this.displays_[this.focusedIndex_].id);
OptionsPage.navigateToPage('displayOverscan');
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_DisplaySetOverscan']);
}.bind(this);
chrome.send('getDisplayInfo');
@@ -628,6 +634,23 @@ cr.define('options', function() {
}
resolution.disabled = (display.resolutions.length <= 1);
}
+
+ if (display.availableColorProfiles.length <= 1) {
+ $('selected-display-color-profile-row').hidden = true;
+ } else {
+ $('selected-display-color-profile-row').hidden = false;
+ var profiles = $('display-options-color-profile-selection');
+ profiles.innerHTML = '';
+ for (var i = 0; i < display.availableColorProfiles.length; i++) {
+ var option = document.createElement('option');
+ var colorProfile = display.availableColorProfiles[i];
+ option.value = colorProfile.profileId;
+ option.textContent = colorProfile.name;
+ option.selected = (
+ display.colorProfile == colorProfile.profileId);
+ profiles.appendChild(option);
+ }
+ }
},
/**
diff --git a/chromium/chrome/browser/resources/options/chromeos/internet_detail.html b/chromium/chrome/browser/resources/options/chromeos/internet_detail.html
index 556c70adb51..f3632ed49b5 100644
--- a/chromium/chrome/browser/resources/options/chromeos/internet_detail.html
+++ b/chromium/chrome/browser/resources/options/chromeos/internet_detail.html
@@ -359,7 +359,7 @@
<section id="cellular-device-options">
<table class="option-control-table">
<tr>
- <td class="option-name" i18n-content="manufacturer"></td>
+ <td class="option-name" i18n-content="cellularManufacturer"></td>
<td id="manufacturer" class="option-value"></td>
</tr>
<tr>
diff --git a/chromium/chrome/browser/resources/options/chromeos/internet_detail.js b/chromium/chrome/browser/resources/options/chromeos/internet_detail.js
index cbc07f21d2c..7fc6c6e88b4 100644
--- a/chromium/chrome/browser/resources/options/chromeos/internet_detail.js
+++ b/chromium/chrome/browser/resources/options/chromeos/internet_detail.js
@@ -526,6 +526,8 @@ cr.define('options.internet', function() {
!$('proxy-use-pac-url').checked;
$('auto-proxy-parms').hidden = !$('auto-proxy').checked;
$('manual-proxy-parms').hidden = !$('manual-proxy').checked;
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_NetworkManualProxy_Disable']);
},
/**
@@ -556,6 +558,8 @@ cr.define('options.internet', function() {
$('proxy-pac-url').disabled = true;
$('auto-proxy-parms').hidden = !$('auto-proxy').checked;
$('manual-proxy-parms').hidden = !$('manual-proxy').checked;
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_NetworkManualProxy_Enable']);
},
};
@@ -626,6 +630,8 @@ cr.define('options.internet', function() {
updateHidden('#details-internet-page .action-area', true);
detailsPage.updateControls();
detailsPage.visible = true;
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_NetworkShowProxyTab']);
};
/**
@@ -810,6 +816,9 @@ cr.define('options.internet', function() {
data.type == Constants.TYPE_WIMAX ||
data.type == Constants.TYPE_VPN)) {
$('details-internet-configure').hidden = false;
+ } else if (data.type == Constants.TYPE_ETHERNET) {
+ // Ethernet (802.1x) can be configured while connected.
+ $('details-internet-configure').hidden = false;
} else {
$('details-internet-configure').hidden = true;
}
@@ -1111,7 +1120,7 @@ cr.define('options.internet', function() {
$('roaming-state').textContent = data.roamingState;
$('restricted-pool').textContent = data.restrictedPool;
$('error-state').textContent = data.errorState;
- $('manufacturer').textContent = data.manufacturer;
+ $('manufacturer').textContent = data.cellularManufacturer;
$('model-id').textContent = data.modelId;
$('firmware-revision').textContent = data.firmwareRevision;
$('hardware-revision').textContent = data.hardwareRevision;
diff --git a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.html b/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.html
index 039c52e7954..4609b04c322 100644
--- a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.html
+++ b/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.html
@@ -12,6 +12,7 @@
<td class="option-value">
<select id="remap-search-key-to" class="control"
data-type="number" i18n-options="remapSearchKeyToValue"
+ metric="Options_KeyboardRemapSearchKey"
pref="settings.language.xkb_remap_search_key_to" dialog-pref>
</select>
</td>
@@ -25,6 +26,7 @@
<td class="option-value">
<select id="remap-control-key-to" class="control"
data-type="number" i18n-options="remapControlKeyToValue"
+ metric="Options_KeyboardRemapControlKey"
pref="settings.language.xkb_remap_control_key_to" dialog-pref>
</select>
</td>
@@ -37,6 +39,7 @@
</td>
<td class="option-value">
<select id="remap-alt-key-to" class="control" data-type="number"
+ metric="Options_KeyboardRemapAltKey"
pref="settings.language.xkb_remap_alt_key_to"
i18n-options="remapAltKeyToValue" dialog-pref></select>
</td>
@@ -52,6 +55,7 @@
<td class="option-value">
<select id="remap-caps-lock-key-to" class="control"
data-type="number"
+ metric="Options_KeyboardRemapCapsLockKey"
pref="settings.language.remap_caps_lock_key_to"
i18n-options="remapCapsLockKeyToValue" dialog-pref></select>
</td>
@@ -67,6 +71,7 @@
<td class="option-value">
<select id="remap-diamond-key-to" class="control"
data-type="number"
+ metric="Options_KeyboardRemapDiamondKey"
pref="settings.language.remap_diamond_key_to"
i18n-options="remapDiamondKeyToValue" dialog-pref></select>
</td>
@@ -74,11 +79,16 @@
</table>
<div class="settings-row">
<div class="checkbox">
- <label>
+ <span class="controlled-setting-with-label">
<input id="send-function-keys" type="checkbox"
pref="settings.language.send_function_keys" dialog-pref>
- <span i18n-content="sendFunctionKeys"></span>
- </label>
+ <span>
+ <label for="send-function-keys" i18n-content="sendFunctionKeys">
+ </label>
+ <span class="bubble-button controlled-setting-indicator"
+ pref="settings.language.send_function_keys"></span>
+ </span>
+ </span>
</div>
<label id="send-function-keys-description" for="send-function-keys"
i18n-content="sendFunctionKeysDescription">
@@ -86,6 +96,10 @@
</div>
</div>
<div class="content-area">
+ <button id="keyboard-shortcuts" class="link-button"
+ i18n-content="showKeyboardShortcuts"></button>
+ </div>
+ <div class="content-area">
<button id="languages-and-input-settings" class="link-button"
i18n-content="changeLanguageAndInputSettings"></button>
</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.js b/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.js
index 39c8a694fb3..4514adaff8d 100644
--- a/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.js
+++ b/chromium/chrome/browser/resources/options/chromeos/keyboard_overlay.js
@@ -28,6 +28,14 @@ cr.define('options', function() {
$('languages-and-input-settings').onclick = function(e) {
OptionsPage.navigateToPage('languages');
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_KeyboardShowLanguageSettings']);
+ };
+
+ $('keyboard-shortcuts').onclick = function(e) {
+ chrome.send('showKeyboardShortcuts');
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_KeyboardShowKeyboardShortcuts']);
};
},
diff --git a/chromium/chrome/browser/resources/options/chromeos/network_list.js b/chromium/chrome/browser/resources/options/chromeos/network_list.js
index 4d20937fa5f..efc2fad31c7 100644
--- a/chromium/chrome/browser/resources/options/chromeos/network_list.js
+++ b/chromium/chrome/browser/resources/options/chromeos/network_list.js
@@ -499,6 +499,8 @@ cr.define('options.network', function() {
var dialog = options.PreferredNetworks.getInstance();
OptionsPage.showPageByName('preferredNetworksPage', false);
dialog.update(list);
+ chrome.send('coreOptionsUserMetricsAction',
+ ['Options_NetworkShowPreferred']);
};
addendum.push({label: loadTimeData.getString('preferredNetworks'),
command: callback,
diff --git a/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css b/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css
new file mode 100644
index 00000000000..c0e8d30c9ce
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css
@@ -0,0 +1,8 @@
+/* Copyright 2014 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.
+ */
+
+#third-party-ime-confirm-overlay {
+ width: 500px;
+}
diff --git a/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html b/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html
new file mode 100644
index 00000000000..63084432fd1
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.html
@@ -0,0 +1,21 @@
+<div id="third-party-ime-confirm-overlay" class="page" hidden>
+ <div class="close-button"></div>
+ <h1 i18n-content="thirdPartyImeConfirmOverlay"></h1>
+ <div class="content-area">
+ <span id="third-party-ime-confirm-text"
+ i18n-content="thirdPartyImeConfirmMessage">
+ </span>
+ </div>
+ <div class="action-area">
+ <div class="action-area-right">
+ <div class="button-strip">
+ <button id="third-party-ime-confirm-cancel"
+ i18n-content="thirdPartyImeConfirmDisable">
+ </button>
+ <button id="third-party-ime-confirm-ok" class="default-button"
+ i18n-content="thirdPartyImeConfirmEnable">
+ </button>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js b/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js
new file mode 100644
index 00000000000..aaf94d928da
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.js
@@ -0,0 +1,89 @@
+// Copyright 2014 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 */ var OptionsPage = options.OptionsPage;
+ /** @const */ var SettingsDialog = options.SettingsDialog;
+
+ /**
+ * HomePageOverlay class
+ * Dialog that allows users to set the home page.
+ * @extends {SettingsDialog}
+ */
+ function ThirdPartyImeConfirmOverlay() {
+ SettingsDialog.call(
+ this, 'thirdPartyImeConfirm',
+ loadTimeData.getString('thirdPartyImeConfirmOverlayTabTitle'),
+ 'third-party-ime-confirm-overlay',
+ $('third-party-ime-confirm-ok'),
+ $('third-party-ime-confirm-cancel'));
+ }
+
+ cr.addSingletonGetter(ThirdPartyImeConfirmOverlay);
+
+ ThirdPartyImeConfirmOverlay.prototype = {
+ __proto__: SettingsDialog.prototype,
+
+ /**
+ * Callback to authorize use of an input method.
+ * @type {Function}
+ * @private
+ */
+ confirmationCallback_: null,
+
+ /**
+ * Callback to cancel enabling an input method.
+ * @type {Function}
+ * @private
+ */
+ cancellationCallback_: null,
+
+ /**
+ * Confirms enabling of a third party IME.
+ */
+ handleConfirm: function() {
+ SettingsDialog.prototype.handleConfirm.call(this);
+ this.confirmationCallback_();
+ },
+
+ /**
+ * Resets state of the checkobx.
+ */
+ handleCancel: function() {
+ SettingsDialog.prototype.handleCancel.call(this);
+ this.cancellationCallback_();
+ },
+
+ /**
+ * Displays a confirmation dialog indicating the risk fo enabling
+ * a third party IME.
+ * @param {{extension: string, confirm: Function, cancel: Function}} data
+ * Options for the confirmation dialog.
+ * @private
+ */
+ showConfirmationDialog_: function(data) {
+ this.confirmationCallback_ = data.confirm;
+ this.cancellationCallback_ = data.cancel;
+ var message = loadTimeData.getStringF('thirdPartyImeConfirmMessage',
+ data.extension);
+ $('third-party-ime-confirm-text').textContent = message;
+ OptionsPage.showPageByName(this.name, false);
+ },
+ };
+
+ /**
+ * Displays a confirmation dialog indicating the risk fo enabling
+ * a third party IME.
+ * @param {{extension: string, confirm: Function, cancel: Function}} data
+ * Options for the confirmation dialog.
+ */
+ ThirdPartyImeConfirmOverlay.showConfirmationDialog = function(data) {
+ ThirdPartyImeConfirmOverlay.getInstance().showConfirmationDialog_(data);
+ };
+
+ // Export
+ return {
+ ThirdPartyImeConfirmOverlay: ThirdPartyImeConfirmOverlay
+ };
+});
diff --git a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.html b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.html
index 1debae7e6ef..b018b03bbed 100644
--- a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.html
+++ b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.html
@@ -1,4 +1,4 @@
-<div id="clear-browser-data-overlay" class="page" hidden>
+<div id="clear-browser-data-overlay" class="page not-resizable" hidden>
<div class="close-button"></div>
<h1 i18n-content="clearBrowserDataOverlay"></h1>
<div id="clear-browser-data-info-banner" hidden>
diff --git a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.js b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.js
index 563a41a88ff..13f186e7ab0 100644
--- a/chromium/chrome/browser/resources/options/clear_browser_data_overlay.js
+++ b/chromium/chrome/browser/resources/options/clear_browser_data_overlay.js
@@ -22,17 +22,39 @@ cr.define('options', function() {
// Inherit ClearBrowserDataOverlay from OptionsPage.
__proto__: OptionsPage.prototype,
- // Whether deleting history and downloads is allowed.
+ /**
+ * Whether deleting history and downloads is allowed.
+ * @type {boolean}
+ * @private
+ */
allowDeletingHistory_: true,
/**
+ * Whether or not clearing browsing data is currently in progress.
+ * @type {boolean}
+ * @private
+ */
+ isClearingInProgress_: false,
+
+ /**
+ * Whether or not the WebUI handler has completed initialization.
+ *
+ * Unless this becomes true, it must be assumed that the above flags might
+ * not contain the authoritative values.
+ *
+ * @type {boolean}
+ * @private
+ */
+ isInitializationComplete_: false,
+
+ /**
* Initialize the page.
*/
initializePage: function() {
// Call base class implementation to starts preference initialization.
OptionsPage.prototype.initializePage.call(this);
- var f = this.updateCommitButtonState_.bind(this);
+ var f = this.updateStateOfControls_.bind(this);
var types = ['browser.clear_data.browsing_history',
'browser.clear_data.download_history',
'browser.clear_data.cache',
@@ -50,7 +72,6 @@ cr.define('options', function() {
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].onclick = f;
}
- this.updateCommitButtonState_();
this.createStuffRemainsFooter_();
@@ -58,16 +79,25 @@ cr.define('options', function() {
ClearBrowserDataOverlay.dismiss();
};
$('clear-browser-data-commit').onclick = function(event) {
- ClearBrowserDataOverlay.setClearingState(true);
+ ClearBrowserDataOverlay.setClearing(true);
chrome.send('performClearBrowserData');
};
- var show = loadTimeData.getBoolean('showDeleteBrowsingHistoryCheckboxes');
- this.showDeleteHistoryCheckboxes_(show);
+ // For managed profiles, hide the checkboxes controlling whether or not
+ // browsing and download history should be cleared. Note that this is
+ // different than just disabling them as a result of enterprise policies.
+ if (!loadTimeData.getBoolean('showDeleteBrowsingHistoryCheckboxes')) {
+ $('delete-browsing-history-container').hidden = true;
+ $('delete-download-history-container').hidden = true;
+ }
+
+ this.updateStateOfControls_();
},
- // Create a footer that explains that some content is not cleared by the
- // clear browsing history dialog.
+ /**
+ * Create a footer that explains that some content is not cleared by the
+ * clear browsing history dialog.
+ */
createStuffRemainsFooter_: function() {
// The localized string is of the form "Saved [content settings] and
// {search engines} will not be cleared and may reflect your browsing
@@ -114,73 +144,101 @@ cr.define('options', function() {
}
},
- // Set the enabled state of the commit button.
- updateCommitButtonState_: function() {
- var checkboxes = document.querySelectorAll(
- '#cbd-content-area input[type=checkbox]');
- var isChecked = false;
- for (var i = 0; i < checkboxes.length; i++) {
- if (checkboxes[i].checked) {
- isChecked = true;
- break;
- }
- }
- $('clear-browser-data-commit').disabled = !isChecked;
+ /**
+ * Sets whether or not we are in the process of clearing data.
+ * @param {boolean} clearing Whether the browsing data is currently being
+ * cleared.
+ * @private
+ */
+ setClearing_: function(clearing) {
+ this.isClearingInProgress_ = clearing;
+ this.updateStateOfControls_();
},
- setAllowDeletingHistory: function(allowed) {
+ /**
+ * Sets whether deleting history and downloads is disallowed by enterprise
+ * policies. This is called on initialization and in response to a change in
+ * the corresponding preference.
+ * @param {boolean} allowed Whether to allow deleting history and downloads.
+ * @private
+ */
+ setAllowDeletingHistory_: function(allowed) {
this.allowDeletingHistory_ = allowed;
+ this.updateStateOfControls_();
},
- showDeleteHistoryCheckboxes_: function(show) {
- if (!show) {
- $('delete-browsing-history-container').hidden = true;
- $('delete-download-history-container').hidden = true;
- }
+ /**
+ * Called by the WebUI handler to signal that it has finished calling all
+ * initialization methods.
+ * @private
+ */
+ markInitializationComplete_: function() {
+ this.isInitializationComplete_ = true;
+ this.updateStateOfControls_();
},
- /** @override */
- didShowPage: function() {
- var allowed = ClearBrowserDataOverlay.getInstance().allowDeletingHistory_;
- ClearBrowserDataOverlay.updateHistoryCheckboxes(allowed);
- },
+ /**
+ * Updates the enabled/disabled/hidden status of all controls on the dialog.
+ * @private
+ */
+ updateStateOfControls_: function() {
+ // The commit button is enabled if at least one data type selected to be
+ // cleared, and if we are not already in the process of clearing.
+ // To prevent the commit button from being hazardously enabled for a very
+ // short time before setClearing() is called the first time by the native
+ // side, also disable the button if |isInitializationComplete_| is false.
+ var enabled = false;
+ if (this.isInitializationComplete_ && !this.isClearingInProgress_) {
+ var checkboxes = document.querySelectorAll(
+ '#cbd-content-area input[type=checkbox]');
+ for (var i = 0; i < checkboxes.length; i++) {
+ if (checkboxes[i].checked) {
+ enabled = true;
+ break;
+ }
+ }
+ }
+ $('clear-browser-data-commit').disabled = !enabled;
+
+ // The checkboxes for clearing history/downloads are enabled unless they
+ // are disallowed by policies, or we are in the process of clearing data.
+ // To prevent flickering, these, and the rest of the controls can safely
+ // be enabled for a short time before the first call to setClearing().
+ var enabled = this.allowDeletingHistory_ && !this.isClearingInProgress_;
+ $('delete-browsing-history-checkbox').disabled = !enabled;
+ $('delete-download-history-checkbox').disabled = !enabled;
+ if (!this.allowDeletingHistory_) {
+ $('delete-browsing-history-checkbox').checked = false;
+ $('delete-download-history-checkbox').checked = false;
+ }
+
+ // Enable everything else unless we are in the process of clearing.
+ var clearing = this.isClearingInProgress_;
+ $('delete-cache-checkbox').disabled = clearing;
+ $('delete-cookies-checkbox').disabled = clearing;
+ $('delete-passwords-checkbox').disabled = clearing;
+ $('delete-form-data-checkbox').disabled = clearing;
+ $('delete-hosted-apps-data-checkbox').disabled = clearing;
+ $('deauthorize-content-licenses-checkbox').disabled = clearing;
+ $('clear-browser-data-time-period').disabled = clearing;
+ $('cbd-throbber').style.visibility = clearing ? 'visible' : 'hidden';
+ $('clear-browser-data-dismiss').disabled = clearing;
+ }
};
//
// Chrome callbacks
//
- /**
- * Updates the disabled status of the browsing-history and downloads
- * checkboxes, also unchecking them if they are disabled. This is called in
- * response to a change in the corresponding preference.
- */
- ClearBrowserDataOverlay.updateHistoryCheckboxes = function(allowed) {
- $('delete-browsing-history-checkbox').disabled = !allowed;
- $('delete-download-history-checkbox').disabled = !allowed;
- if (!allowed) {
- $('delete-browsing-history-checkbox').checked = false;
- $('delete-download-history-checkbox').checked = false;
- }
- ClearBrowserDataOverlay.getInstance().setAllowDeletingHistory(allowed);
+ ClearBrowserDataOverlay.setAllowDeletingHistory = function(allowed) {
+ ClearBrowserDataOverlay.getInstance().setAllowDeletingHistory_(allowed);
+ };
+
+ ClearBrowserDataOverlay.setClearing = function(clearing) {
+ ClearBrowserDataOverlay.getInstance().setClearing_(clearing);
};
- ClearBrowserDataOverlay.setClearingState = function(state) {
- $('delete-browsing-history-checkbox').disabled = state;
- $('delete-download-history-checkbox').disabled = state;
- $('delete-cache-checkbox').disabled = state;
- $('delete-cookies-checkbox').disabled = state;
- $('delete-passwords-checkbox').disabled = state;
- $('delete-form-data-checkbox').disabled = state;
- $('delete-hosted-apps-data-checkbox').disabled = state;
- $('deauthorize-content-licenses-checkbox').disabled = state;
- $('clear-browser-data-time-period').disabled = state;
- $('cbd-throbber').style.visibility = state ? 'visible' : 'hidden';
- $('clear-browser-data-dismiss').disabled = state;
-
- if (state)
- $('clear-browser-data-commit').disabled = true;
- else
- ClearBrowserDataOverlay.getInstance().updateCommitButtonState_();
+ ClearBrowserDataOverlay.markInitializationComplete = function() {
+ ClearBrowserDataOverlay.getInstance().markInitializationComplete_();
};
ClearBrowserDataOverlay.setBannerVisibility = function(args) {
@@ -193,13 +251,15 @@ cr.define('options', function() {
// actually worked. Otherwise the dialog just vanishes instantly in most
// cases.
window.setTimeout(function() {
+ ClearBrowserDataOverlay.setClearing(false);
ClearBrowserDataOverlay.dismiss();
}, 200);
};
ClearBrowserDataOverlay.dismiss = function() {
- OptionsPage.closeOverlay();
- this.setClearingState(false);
+ var topmostVisiblePage = OptionsPage.getTopmostVisiblePage();
+ if (topmostVisiblePage && topmostVisiblePage.name == 'clearBrowserData')
+ OptionsPage.closeOverlay();
};
// Export
diff --git a/chromium/chrome/browser/resources/options/confirm_dialog.js b/chromium/chrome/browser/resources/options/confirm_dialog.js
index acf34e6db02..b7d235eb027 100644
--- a/chromium/chrome/browser/resources/options/confirm_dialog.js
+++ b/chromium/chrome/browser/resources/options/confirm_dialog.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
cr.define('options', function() {
- /** @const */ var OptionsPage = options.OptionsPage;
+ /** @const */ var SettingsDialog = options.SettingsDialog;
/**
* A dialog that will pop up when the user attempts to set the value of the
@@ -22,13 +22,11 @@ cr.define('options', function() {
* confirmed the dialog before. This ensures that the user is presented
* with the dialog only once. If left |undefined| or |null|, the dialog
* will pop up every time the user attempts to set |pref| to |true|.
- * @extends {OptionsPage}
+ * @extends {SettingsDialog}
*/
function ConfirmDialog(name, title, pageDivName, okButton, cancelButton, pref,
metric, confirmed_pref) {
- OptionsPage.call(this, name, title, pageDivName);
- this.okButton = okButton;
- this.cancelButton = cancelButton;
+ SettingsDialog.call(this, name, title, pageDivName, okButton, cancelButton);
this.pref = pref;
this.metric = metric;
this.confirmed_pref = confirmed_pref;
@@ -37,7 +35,7 @@ cr.define('options', function() {
ConfirmDialog.prototype = {
// Set up the prototype chain
- __proto__: OptionsPage.prototype,
+ __proto__: SettingsDialog.prototype,
/**
* Handle changes to |pref|. Only uncommitted changes are relevant as these
@@ -68,6 +66,8 @@ cr.define('options', function() {
/** @override */
initializePage: function() {
+ SettingsDialog.prototype.initializePage.call(this);
+
this.okButton.onclick = this.handleConfirm.bind(this);
this.cancelButton.onclick = this.handleCancel.bind(this);
Preferences.getInstance().addEventListener(
@@ -82,9 +82,10 @@ cr.define('options', function() {
* Handle the confirm button by committing the |pref| change. If
* |confirmed_pref| has been specified, also remember that the dialog has
* been confirmed to avoid bringing it up in the future.
+ * @override
*/
handleConfirm: function() {
- OptionsPage.closeOverlay();
+ SettingsDialog.prototype.handleConfirm.call(this);
Preferences.getInstance().commitPref(this.pref, this.metric);
if (this.confirmed_pref)
@@ -94,10 +95,10 @@ cr.define('options', function() {
/**
* Handle the cancel button by rolling back the |pref| change without it
* ever taking effect.
+ * @override
*/
handleCancel: function() {
- OptionsPage.closeOverlay();
-
+ SettingsDialog.prototype.handleCancel.call(this);
Preferences.getInstance().rollbackPref(this.pref);
},
diff --git a/chromium/chrome/browser/resources/options/content_settings.css b/chromium/chrome/browser/resources/options/content_settings.css
index 30e01d197fc..b6112eb0b0c 100644
--- a/chromium/chrome/browser/resources/options/content_settings.css
+++ b/chromium/chrome/browser/resources/options/content_settings.css
@@ -39,7 +39,7 @@ select.exception-setting {
-webkit-box-flex: 1;
}
-#exception-behavior-column {
+.exception-value-column-header {
width: 145px;
}
@@ -68,15 +68,6 @@ div[role='listitem'][controlled-by] {
position: relative;
}
-.section-header {
- -webkit-margin-start: -18px;
- margin-bottom: 0.8em;
-}
-
-.section-header > h3 {
- display: inline;
-}
-
.settings-list div[role='listitem'][controlled-by='policy'],
.settings-list div[role='listitem'][controlled-by='extension'] {
background: rgb(250, 230, 146);
diff --git a/chromium/chrome/browser/resources/options/content_settings.html b/chromium/chrome/browser/resources/options/content_settings.html
index 5cebc041b44..176c72d650d 100644
--- a/chromium/chrome/browser/resources/options/content_settings.html
+++ b/chromium/chrome/browser/resources/options/content_settings.html
@@ -285,7 +285,7 @@
</span>
</span>
</div>
-<if expr="pp_ifdef('enable_google_now')">
+<if expr="enable_google_now">
<div class="checkbox" id="geolocationCheckbox" hidden>
<span class="controlled-setting-with-label">
<input id="googleGeolocationAccessEnabled"
@@ -396,7 +396,7 @@
</div>
</div>
</section>
-<if expr="pp_ifdef('chromeos') or is_win">
+<if expr="chromeos or is_win">
<!-- Protected Content filter -->
<section guest-visibility="disabled">
<h3 i18n-content="protectedContentTabLabel"
@@ -411,16 +411,18 @@
<span i18n-content="protectedContentEnable"></span>
</label>
</div>
+ <if expr="chromeos">
<div class="settings-row">
<button id="protected-content-exceptions"
class="exceptions-list-button" contentType="protectedContent"
i18n-content="manageExceptions"></button>
</div>
+ </if>
</div>
</section>
</if>
<!-- Media Stream capture device filter -->
- <section>
+ <section id="media-stream-settings">
<div class="section-header">
<h3 i18n-content="mediaStreamTabLabel"></h3>
<span id="media-indicator"
@@ -502,13 +504,6 @@
</div>
</div>
</section>
- <section id="media-galleries-section" hidden>
- <h3 i18n-content="mediaGalleriesSectionLabel"></h3>
- <div class="settings-row">
- <button id="manage-galleries-button"
- i18n-content="manageGalleriesButton"></button>
- </div>
- </section>
<!-- Automatic Downloads filter -->
<section>
<h3 i18n-content="multiple-automatic-downloads_header"></h3>
@@ -590,6 +585,16 @@
</div>
</div>
</section>
+ <!-- Page zoom levels -->
+ <section id="page-zoom-levels">
+ <h3 i18n-content="zoomlevels_header"></h3>
+ <div>
+ <div class="settings-row">
+ <button class="exceptions-list-button" contentType="zoomlevels"
+ i18n-content="zoomLevelsManage"></button>
+ </div>
+ </div>
+ </section>
</div>
<div class="action-area">
<div class="button-strip">
diff --git a/chromium/chrome/browser/resources/options/content_settings.js b/chromium/chrome/browser/resources/options/content_settings.js
index 160d36f6d79..44ae39f1f8a 100644
--- a/chromium/chrome/browser/resources/options/content_settings.js
+++ b/chromium/chrome/browser/resources/options/content_settings.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-if (!loadTimeData.getBoolean('newContentSettings')) {
-
cr.define('options', function() {
/** @const */ var OptionsPage = options.OptionsPage;
@@ -39,17 +37,11 @@ cr.define('options', function() {
// history so back/forward and tab restore works.
var hash = event.currentTarget.getAttribute('contentType');
var url = page.name + '#' + hash;
- window.history.pushState({pageName: page.name},
- page.title,
- '/' + url);
+ uber.pushState({pageName: page.name}, url);
- // Navigate after the history has been replaced in order to have the
- // correct hash loaded.
+ // Navigate after the local history has been replaced in order to have
+ // the correct hash loaded.
OptionsPage.showPageByName('contentExceptions', false);
-
- uber.invokeMethodOnParent('setPath', {path: url});
- uber.invokeMethodOnParent('setTitle',
- {title: loadTimeData.getString(hash + 'TabTitle')});
};
}
@@ -60,10 +52,6 @@ cr.define('options', function() {
};
}
- $('manage-galleries-button').onclick = function(event) {
- OptionsPage.navigateToPage('manageGalleries');
- };
-
if (cr.isChromeOS)
UIAccountTweaks.applyGuestModeVisibility(document);
@@ -121,8 +109,9 @@ cr.define('options', function() {
value: dict[group].value,
controlledBy: controlledBy,
};
- for (var i = 0; i < indicators.length; i++)
+ for (var i = 0; i < indicators.length; i++) {
indicators[i].handlePrefChange(event);
+ }
}
};
@@ -170,31 +159,36 @@ cr.define('options', function() {
/**
* Initializes an exceptions list.
* @param {string} type The content type that we are setting exceptions for.
- * @param {Array} list An array of pairs, where the first element of each pair
- * is the filter string, and the second is the setting (allow/block).
+ * @param {Array} exceptions An array of pairs, where the first element of
+ * each pair is the filter string, and the second is the setting
+ * (allow/block).
*/
- ContentSettings.setExceptions = function(type, list) {
- var exceptionsList =
- document.querySelector('div[contentType=' + type + ']' +
- ' list[mode=normal]');
- exceptionsList.setExceptions(list);
+ ContentSettings.setExceptions = function(type, exceptions) {
+ this.getExceptionsList(type, 'normal').setExceptions(exceptions);
};
- ContentSettings.setHandlers = function(list) {
- $('handlers-list').setHandlers(list);
+ ContentSettings.setHandlers = function(handlers) {
+ $('handlers-list').setHandlers(handlers);
};
- ContentSettings.setIgnoredHandlers = function(list) {
- $('ignored-handlers-list').setHandlers(list);
+ ContentSettings.setIgnoredHandlers = function(ignoredHandlers) {
+ $('ignored-handlers-list').setHandlers(ignoredHandlers);
};
- ContentSettings.setOTRExceptions = function(type, list) {
- var exceptionsList =
- document.querySelector('div[contentType=' + type + ']' +
- ' list[mode=otr]');
-
+ ContentSettings.setOTRExceptions = function(type, otrExceptions) {
+ var exceptionsList = this.getExceptionsList(type, 'otr');
exceptionsList.parentNode.hidden = false;
- exceptionsList.setExceptions(list);
+ exceptionsList.setExceptions(otrExceptions);
+ };
+
+ /**
+ * @param {string} type The type of exceptions (e.g. "location") to get.
+ * @param {string} mode The mode of the desired exceptions list (e.g. otr).
+ * @return {?ExceptionsList} The corresponding exceptions list or null.
+ */
+ ContentSettings.getExceptionsList = function(type, mode) {
+ return document.querySelector(
+ 'div[contentType=' + type + '] list[mode=' + mode + ']');
};
/**
@@ -208,10 +202,8 @@ cr.define('options', function() {
*/
ContentSettings.patternValidityCheckComplete =
function(type, mode, pattern, valid) {
- var exceptionsList =
- document.querySelector('div[contentType=' + type + '] ' +
- 'list[mode=' + mode + ']');
- exceptionsList.patternValidityCheckComplete(pattern, valid);
+ this.getExceptionsList(type, mode).patternValidityCheckComplete(pattern,
+ valid);
};
/**
@@ -222,7 +214,7 @@ cr.define('options', function() {
*/
ContentSettings.showMediaPepperFlashDefaultLink = function(show) {
$('media-pepper-flash-default').hidden = !show;
- }
+ };
/**
* Shows/hides the link to the Pepper Flash camera and microphone
@@ -232,7 +224,7 @@ cr.define('options', function() {
*/
ContentSettings.showMediaPepperFlashExceptionsLink = function(show) {
$('media-pepper-flash-exceptions').hidden = !show;
- }
+ };
/**
* Shows/hides the whole Web MIDI settings.
@@ -240,7 +232,7 @@ cr.define('options', function() {
*/
ContentSettings.showExperimentalWebMIDISettings = function(show) {
$('experimental-web-midi-settings').hidden = !show;
- }
+ };
/**
* Updates the microphone/camera devices menu with the given entries.
@@ -281,10 +273,9 @@ cr.define('options', function() {
*/
ContentSettings.enableProtectedContentExceptions = function(enable) {
var exceptionsButton = $('protected-content-exceptions');
- if (exceptionsButton) {
+ if (exceptionsButton)
exceptionsButton.disabled = !enable;
- }
- }
+ };
/**
* Set the default microphone device based on the popup selection.
@@ -310,5 +301,3 @@ cr.define('options', function() {
};
});
-
-}
diff --git a/chromium/chrome/browser/resources/options/content_settings2.html b/chromium/chrome/browser/resources/options/content_settings2.html
deleted file mode 100644
index e886bfdeb78..00000000000
--- a/chromium/chrome/browser/resources/options/content_settings2.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<div id="content-settings-page2" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="contentSettingsPage"></h1>
- <div class="content-area">
- This space intentionally left blank.
- </div>
- <div class="action-area">
- <div class="button-strip">
- <button id="content-settings-overlay-confirm2" i18n-content="done">
- </button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/content_settings2.js b/chromium/chrome/browser/resources/options/content_settings2.js
deleted file mode 100644
index 7c6d95137e3..00000000000
--- a/chromium/chrome/browser/resources/options/content_settings2.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// 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.
-
-if (loadTimeData.getBoolean('newContentSettings')) {
-
-cr.define('options', function() {
- /** @const */ var OptionsPage = options.OptionsPage;
-
- //////////////////////////////////////////////////////////////////////////////
- // ContentSettings class:
-
- /**
- * Encapsulated handling of content settings page.
- * @constructor
- */
- function ContentSettings() {
- this.activeNavTab = null;
- OptionsPage.call(this, 'content',
- loadTimeData.getString('contentSettingsPageTabTitle'),
- 'content-settings-page2');
- }
-
- cr.addSingletonGetter(ContentSettings);
-
- ContentSettings.prototype = {
- __proto__: OptionsPage.prototype,
-
- initializePage: function() {
- OptionsPage.prototype.initializePage.call(this);
-
- $('content-settings-overlay-confirm2').onclick =
- OptionsPage.closeOverlay.bind(OptionsPage);
- },
- };
-
- ContentSettings.updateHandlersEnabledRadios = function(enabled) {
- // Not implemented.
- };
-
- /**
- * Sets the values for all the content settings radios.
- * @param {Object} dict A mapping from radio groups to the checked value for
- * that group.
- */
- ContentSettings.setContentFilterSettingsValue = function(dict) {
- // Not implemented.
- };
-
- /**
- * Initializes an exceptions list.
- * @param {string} type The content type that we are setting exceptions for.
- * @param {Array} list An array of pairs, where the first element of each pair
- * is the filter string, and the second is the setting (allow/block).
- */
- ContentSettings.setExceptions = function(type, list) {
- // Not implemented.
- };
-
- ContentSettings.setHandlers = function(list) {
- // Not implemented.
- };
-
- ContentSettings.setIgnoredHandlers = function(list) {
- // Not implemented.
- };
-
- ContentSettings.setOTRExceptions = function(type, list) {
- // Not implemented.
- };
-
- /**
- * Enables the Pepper Flash camera and microphone settings.
- * Please note that whether the settings are actually showed or not is also
- * affected by the style class pepper-flash-settings.
- */
- ContentSettings.enablePepperFlashCameraMicSettings = function() {
- // Not implemented.
- }
-
- // Export
- return {
- ContentSettings: ContentSettings
- };
-
-});
-
-}
diff --git a/chromium/chrome/browser/resources/options/content_settings_exceptions_area.html b/chromium/chrome/browser/resources/options/content_settings_exceptions_area.html
index 1306379022b..70ee5ce8c80 100644
--- a/chromium/chrome/browser/resources/options/content_settings_exceptions_area.html
+++ b/chromium/chrome/browser/resources/options/content_settings_exceptions_area.html
@@ -6,7 +6,12 @@
<div id="exception-pattern-column" i18n-content="exceptionPatternHeader">
</div>
<div id="exception-behavior-column"
- i18n-content="exceptionBehaviorHeader">
+ i18n-content="exceptionBehaviorHeader"
+ class="exception-value-column-header">
+ </div>
+ <div id="exception-zoom-column"
+ i18n-content="exceptionZoomHeader"
+ class="exception-value-column-header" hidden>
</div>
</div>
<div contentType="cookies">
@@ -123,6 +128,14 @@
<list mode="otr"></list>
</div>
</div>
+ <div contentType="zoomlevels">
+ <list mode="normal"></list>
+ <div>
+ <span class="otr-explanation" i18n-content="otr_exceptions_explanation">
+ </span>
+ <list mode="otr"></list>
+ </div>
+ </div>
</div>
<div class="action-area">
<div class="hbox stretch">
diff --git a/chromium/chrome/browser/resources/options/content_settings_exceptions_area.js b/chromium/chrome/browser/resources/options/content_settings_exceptions_area.js
index 31c6a5ed07e..66a71c93ed6 100644
--- a/chromium/chrome/browser/resources/options/content_settings_exceptions_area.js
+++ b/chromium/chrome/browser/resources/options/content_settings_exceptions_area.js
@@ -104,8 +104,10 @@ cr.define('options.contentSettings', function() {
this.editable = false;
}
- this.addEditField(select, this.settingLabel);
- this.contentElement.appendChild(select);
+ if (this.contentType != 'zoomlevels') {
+ this.addEditField(select, this.settingLabel);
+ this.contentElement.appendChild(select);
+ }
select.className = 'exception-setting';
select.setAttribute('aria-labelledby', 'exception-behavior-column');
@@ -123,6 +125,19 @@ cr.define('options.contentSettings', function() {
this.contentElement.appendChild(videoSettingLabel);
}
+ if (this.contentType == 'zoomlevels') {
+ this.deletable = true;
+ this.editable = false;
+
+ var zoomLabel = cr.doc.createElement('span');
+ zoomLabel.textContent = this.dataItem.zoom;
+ zoomLabel.className = 'exception-setting';
+ zoomLabel.setAttribute('displaymode', 'static');
+ zoomLabel.setAttribute('aria-labelledby', 'exception-zoom-column');
+ this.contentElement.appendChild(zoomLabel);
+ this.zoomLabel = zoomLabel;
+ }
+
// Used to track whether the URL pattern in the input is valid.
// This will be true if the browser process has informed us that the
// current text in the input is valid. Changing the text resets this to
@@ -541,7 +556,8 @@ cr.define('options.contentSettings', function() {
return !(this.contentType == 'notifications' ||
this.contentType == 'location' ||
this.contentType == 'fullscreen' ||
- this.contentType == 'media-stream');
+ this.contentType == 'media-stream' ||
+ this.contentType == 'zoomlevels');
},
/**
@@ -614,6 +630,9 @@ cr.define('options.contentSettings', function() {
* @param {string} type The content type.
*/
showList: function(type) {
+ // Update the title for the type that was shown.
+ this.title = loadTimeData.getString(type + 'TabTitle');
+
var header = this.pageDiv.querySelector('h1');
header.textContent = loadTimeData.getString(type + '_header');
@@ -627,6 +646,9 @@ cr.define('options.contentSettings', function() {
var mediaHeader = this.pageDiv.querySelector('.media-header');
mediaHeader.hidden = type != 'media-stream';
+
+ $('exception-behavior-column').hidden = type == 'zoomlevels';
+ $('exception-zoom-column').hidden = type != 'zoomlevels';
},
/**
diff --git a/chromium/chrome/browser/resources/options/controlled_setting.css b/chromium/chrome/browser/resources/options/controlled_setting.css
index 089e27dbbd7..ad2051ad8bb 100644
--- a/chromium/chrome/browser/resources/options/controlled_setting.css
+++ b/chromium/chrome/browser/resources/options/controlled_setting.css
@@ -27,11 +27,6 @@
padding: 0;
}
-input:-webkit-any([type='text'],[type='url'],:not([type])) +
- .controlled-setting-indicator {
- -webkit-margin-start: 5px;
-}
-
.controlled-setting-indicator:not([controlled-by]) {
display: none;
}
@@ -41,50 +36,30 @@ input:-webkit-any([type='text'],[type='url'],:not([type])) +
}
.controlled-setting-indicator[controlled-by='owner'] > div {
- background-image: url('chrome://theme/IDR_CONTROLLED_SETTING_MANDATORY');
+ background-image: url('chrome://theme/IDR_CONTROLLED_SETTING_OWNER');
}
.controlled-setting-indicator[controlled-by='extension'] > div {
background-image: url('chrome://theme/IDR_CONTROLLED_SETTING_EXTENSION');
}
-.controlled-setting-indicator:-webkit-any([controlled-by='recommended'],
- [controlled-by='hasRecommendation']) > div {
- background-image: url('chrome://theme/IDR_CONTROLLED_SETTING_MANDATORY');
-}
-
-.controlled-setting-bubble-content {
- -webkit-padding-start: 30px;
- background-repeat: no-repeat;
- background-size: 22px;
- min-height: 32px;
-}
-
-.controlled-setting-bubble-content[controlled-by='policy'] {
- background-image: url('chrome://theme/IDR_CONTROLLED_SETTING_MANDATORY');
-}
-
-.controlled-setting-bubble-content[controlled-by='owner'] {
- background-image: url('chrome://theme/IDR_CONTROLLED_SETTING_MANDATORY');
+.controlled-setting-indicator[controlled-by='shared'] > div {
+ background-image: url('chrome://theme/IDR_CONTROLLED_SETTING_SHARED');
}
-.controlled-setting-bubble-content[controlled-by='extension'] {
- background-image: url('chrome://theme/IDR_CONTROLLED_SETTING_EXTENSION');
-}
-
-.controlled-setting-bubble-content:-webkit-any([controlled-by='recommended'],
- [controlled-by='hasRecommendation']) {
+.controlled-setting-indicator:-webkit-any([controlled-by='recommended'],
+ [controlled-by='hasRecommendation']) > div {
background-image: url('chrome://theme/IDR_CONTROLLED_SETTING_MANDATORY');
}
-html[dir='rtl'] .controlled-setting-bubble-content {
- background-position: right top;
-}
-
.controlled-setting-bubble-action {
padding: 0 !important;
}
+.controlled-setting-bubble-header {
+ margin-top: 3px;
+}
+
.controlled-setting-bubble-content-row {
height: 35px;
position: relative;
@@ -95,7 +70,7 @@ html[dir='rtl'] .controlled-setting-bubble-content {
background-repeat: no-repeat;
font-weight: bold;
height: 24px;
- margin-top: -12px;
+ margin-top: -9px;
overflow: hidden;
padding-top: 3px;
position: absolute;
@@ -110,7 +85,8 @@ html[dir='rtl'] .controlled-setting-bubble-extension-name {
}
.controlled-setting-bubble-extension-manage-link {
- margin-top: -0.5em;
+ margin-left: -0.35em;
+ margin-top: -0.30em;
position: absolute;
top: 50%;
}
diff --git a/chromium/chrome/browser/resources/options/controlled_setting.js b/chromium/chrome/browser/resources/options/controlled_setting.js
index 28674bd888b..5ac42d971e4 100644
--- a/chromium/chrome/browser/resources/options/controlled_setting.js
+++ b/chromium/chrome/browser/resources/options/controlled_setting.js
@@ -61,19 +61,9 @@ cr.define('options', function() {
if (!this.value || String(event.value.value) == this.value) {
this.controlledBy = event.value.controlledBy;
if (event.value.extension) {
- if (this.pref == 'session.restore_on_startup' ||
- this.pref == 'homepage_is_newtabpage') {
- // Special case for the restore on startup, which is implied
- // by the startup pages settings being controlled by an
- // extension, and same for the home page as NTP, so we don't want
- // to show two buttons in these cases.
- // TODO(mad): Find a better way to handle this.
- this.controlledBy = null;
- } else {
- this.extensionId = event.value.extension.id;
- this.extensionIcon = event.value.extension.icon;
- this.extensionName = event.value.extension.name;
- }
+ this.extensionId = event.value.extension.id;
+ this.extensionIcon = event.value.extension.icon;
+ this.extensionName = event.value.extension.name;
}
} else {
this.controlledBy = null;
@@ -105,6 +95,10 @@ cr.define('options', function() {
'extensionWithName': loadTimeData.getString(
'controlledSettingsExtensionWithName'),
};
+ if (cr.isChromeOS) {
+ defaultStrings.shared =
+ loadTimeData.getString('controlledSettingsShared');
+ }
} else {
var defaultStrings = {
'policy': loadTimeData.getString('controlledSettingPolicy'),
@@ -119,6 +113,8 @@ cr.define('options', function() {
if (cr.isChromeOS) {
defaultStrings.owner =
loadTimeData.getString('controlledSettingOwner');
+ defaultStrings.shared =
+ loadTimeData.getString('controlledSettingShared');
}
}
@@ -136,8 +132,7 @@ cr.define('options', function() {
// Create the DOM tree.
var content = document.createElement('div');
- content.className = 'controlled-setting-bubble-content';
- content.setAttribute('controlled-by', this.controlledBy);
+ content.classList.add('controlled-setting-bubble-header');
content.textContent = text;
if (this.controlledBy == 'hasRecommendation' && this.resetHandler_ &&
@@ -169,13 +164,15 @@ cr.define('options', function() {
var manageLink = extensionContainer.querySelector(
'.controlled-setting-bubble-extension-manage-link');
+ var extensionId = this.extensionId;
manageLink.onclick = function() {
uber.invokeMethodOnWindow(
- window.top, 'showPage', {pageId: 'extensions'});
+ window.top, 'showPage', {pageId: 'extensions',
+ path: '?id=' + extensionId});
};
- var disableButton = extensionContainer.querySelector('button');
- var extensionId = this.extensionId;
+ var disableButton = extensionContainer.querySelector(
+ '.controlled-setting-bubble-extension-disable-button');
disableButton.onclick = function() {
chrome.send('disableExtension', [extensionId]);
};
@@ -223,6 +220,10 @@ cr.define('options', function() {
* override this recommendation but has not done so.
* - 'hasRecommendation': A value is recommended by policy. The user has
* overridden this recommendation.
+ * - 'owner': A value is controlled by the owner of the device
+ * (Chrome OS only).
+ * - 'shared': A value belongs to the primary user but can be
+ * modified (Chrome OS only).
* - unset: The value is controlled by the user alone.
* @type {string}
*/
diff --git a/chromium/chrome/browser/resources/options/cookies_view.js b/chromium/chrome/browser/resources/options/cookies_view.js
index 4d496684c42..a6af2978005 100644
--- a/chromium/chrome/browser/resources/options/cookies_view.js
+++ b/chromium/chrome/browser/resources/options/cookies_view.js
@@ -88,6 +88,10 @@ cr.define('options', function() {
* @private
*/
handleSearchQueryChange_: function(e) {
+ var stringId = document.querySelector('.cookies-search-box').value ?
+ 'remove_all_shown_cookie' : 'remove_all_cookie';
+ document.querySelector('.remove-all-cookies-button').innerHTML =
+ loadTimeData.getString(stringId);
if (this.queryDelayTimerId_)
window.clearTimeout(this.queryDelayTimerId_);
diff --git a/chromium/chrome/browser/resources/options/deletable_item_list.js b/chromium/chrome/browser/resources/options/deletable_item_list.js
index 403dc0fc1dc..4f223bad578 100644
--- a/chromium/chrome/browser/resources/options/deletable_item_list.js
+++ b/chromium/chrome/browser/resources/options/deletable_item_list.js
@@ -54,6 +54,8 @@ cr.define('options', function() {
this.handleMouseDownUpOnClose_);
this.closeButtonElement_.addEventListener('focus',
this.handleFocus_.bind(this));
+ this.closeButtonElement_.title =
+ loadTimeData.getString('deletableItemDeleteButtonTitle');
this.appendChild(this.closeButtonElement_);
},
diff --git a/chromium/chrome/browser/resources/options/do_not_track_confirm_overlay.html b/chromium/chrome/browser/resources/options/do_not_track_confirm_overlay.html
index e39d00f0af1..2c6ec530945 100644
--- a/chromium/chrome/browser/resources/options/do_not_track_confirm_overlay.html
+++ b/chromium/chrome/browser/resources/options/do_not_track_confirm_overlay.html
@@ -5,19 +5,23 @@
<span id="do-not-track-confirm-text"
i18n-content="doNotTrackConfirmMessage">
</span>
- <a target="_blank" i18n-content="learnMore"
- i18n-values="href:doNotTrackLearnMoreURL">
- </a>
</div>
<div class="action-area">
- <div class="button-strip">
- <button id="do-not-track-confirm-ok" class="default-button"
- i18n-content="doNotTrackConfirmEnable">
- </button>
- <button id="do-not-track-confirm-cancel"
- i18n-content="doNotTrackConfirmDisable"
- class="cancel-button">
- </button>
+ <div class="hbox stretch">
+ <a target="_blank" i18n-content="learnMore"
+ i18n-values="href:doNotTrackLearnMoreURL">
+ </a>
+ </div>
+ <div class="action-area-right">
+ <div class="button-strip">
+ <button id="do-not-track-confirm-ok" class="default-button"
+ i18n-content="doNotTrackConfirmEnable">
+ </button>
+ <button id="do-not-track-confirm-cancel"
+ i18n-content="doNotTrackConfirmDisable"
+ class="cancel-button">
+ </button>
+ </div>
</div>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/options/font_settings.js b/chromium/chrome/browser/resources/options/font_settings.js
index 0b3f3f70a9b..1d09f5ae8fb 100644
--- a/chromium/chrome/browser/resources/options/font_settings.js
+++ b/chromium/chrome/browser/resources/options/font_settings.js
@@ -34,6 +34,8 @@ cr.define('options', function() {
22, 24, 26, 28, 30, 32, 34, 36, 40, 44, 48, 56, 64, 72];
standardFontRange.addEventListener(
'change', this.standardRangeChanged_.bind(this, standardFontRange));
+ standardFontRange.addEventListener(
+ 'input', this.standardRangeChanged_.bind(this, standardFontRange));
standardFontRange.customChangeHandler =
this.standardFontSizeChanged_.bind(standardFontRange);
@@ -42,6 +44,8 @@ cr.define('options', function() {
18, 20, 22, 24];
minimumFontRange.addEventListener(
'change', this.minimumRangeChanged_.bind(this, minimumFontRange));
+ minimumFontRange.addEventListener(
+ 'input', this.minimumRangeChanged_.bind(this, minimumFontRange));
minimumFontRange.customChangeHandler =
this.minimumFontSizeChanged_.bind(minimumFontRange);
diff --git a/chromium/chrome/browser/resources/options/handler_options.html b/chromium/chrome/browser/resources/options/handler_options.html
index 4f45f018a3a..4b4e8e55b13 100644
--- a/chromium/chrome/browser/resources/options/handler_options.html
+++ b/chromium/chrome/browser/resources/options/handler_options.html
@@ -29,10 +29,16 @@
</div>
</div>
<div class="action-area">
- <div class="button-strip">
- <button id="handler-options-overlay-confirm" class="default-button"
- i18n-content="done">
- </button>
+ <div class="hbox stretch">
+ <a target="_blank" i18n-content="learnMore"
+ i18n-values="href:handlers_learn_more_url"></a>
+ </div>
+ <div class="action-area-right">
+ <div class="button-strip">
+ <button id="handler-options-overlay-confirm" class="default-button"
+ i18n-content="done">
+ </button>
+ </div>
</div>
</div>
</div>
diff --git a/chromium/chrome/browser/resources/options/handler_options.js b/chromium/chrome/browser/resources/options/handler_options.js
index 894e13f72c0..0918e0f2889 100644
--- a/chromium/chrome/browser/resources/options/handler_options.js
+++ b/chromium/chrome/browser/resources/options/handler_options.js
@@ -27,7 +27,7 @@ cr.define('options', function() {
/**
* The handlers list.
- * @type {DeletableItemList}
+ * @type {options.HandlersList}
* @private
*/
handlersList_: null,
diff --git a/chromium/chrome/browser/resources/options/handler_options_list.js b/chromium/chrome/browser/resources/options/handler_options_list.js
index 5572a55445f..12129a89a25 100644
--- a/chromium/chrome/browser/resources/options/handler_options_list.js
+++ b/chromium/chrome/browser/resources/options/handler_options_list.js
@@ -6,7 +6,6 @@ cr.define('options', function() {
/** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
/** @const */ var List = cr.ui.List;
/** @const */ var ListItem = cr.ui.ListItem;
- /** @const */ var HandlerOptions = options.HandlerOptions;
/** @const */ var DeletableItem = options.DeletableItem;
/** @const */ var DeletableItemList = options.DeletableItemList;
@@ -14,7 +13,7 @@ cr.define('options', function() {
* Creates a new ignored protocol / content handler list item.
*
* Accepts values in the form
- * ['mailto', 'http://www.thesite.com/%s', 'The title of the protocol'],
+ * ['mailto', 'http://www.thesite.com/%s', 'www.thesite.com'],
* @param {Object} entry A dictionary describing the handlers for a given
* protocol.
* @constructor
@@ -41,12 +40,12 @@ cr.define('options', function() {
protocolElement.className = 'handlers-type-column';
this.contentElement_.appendChild(protocolElement);
- // Site title.
- var titleElement = document.createElement('div');
- titleElement.textContent = this.dataItem[2];
- titleElement.className = 'handlers-site-column';
- titleElement.title = this.dataItem[1];
- this.contentElement_.appendChild(titleElement);
+ // Host name.
+ var hostElement = document.createElement('div');
+ hostElement.textContent = this.dataItem[2];
+ hostElement.className = 'handlers-site-column';
+ hostElement.title = this.dataItem[1];
+ this.contentElement_.appendChild(hostElement);
},
};
@@ -91,7 +90,7 @@ cr.define('options', function() {
* Accepts values in the form
* { protocol: 'mailto',
* handlers: [
- * ['mailto', 'http://www.thesite.com/%s', 'The title of the protocol'],
+ * ['mailto', 'http://www.thesite.com/%s', 'www.thesite.com'],
* ...,
* ],
* }
@@ -168,7 +167,6 @@ cr.define('options', function() {
decorate: function() {
ListItem.prototype.decorate.call(this);
- var self = this;
var delegate = {
removeHandler: function(index, handler) {
chrome.send('removeHandler', [handler]);
diff --git a/chromium/chrome/browser/resources/options/home_page_overlay.html b/chromium/chrome/browser/resources/options/home_page_overlay.html
index 7fc78398d50..a51016813ad 100644
--- a/chromium/chrome/browser/resources/options/home_page_overlay.html
+++ b/chromium/chrome/browser/resources/options/home_page_overlay.html
@@ -31,7 +31,7 @@
<input id="homepage-url-field" type="url" data-type="url"
class="weakrtl favicon-cell stretch" pref="homepage"
aria-labelledby="homepage-use-url-label"
- dialog-pref>
+ metric="Options_Homepage_URL" dialog-pref>
</input>
<span id="homepage-url-field-indicator"
class="controlled-setting-indicator" pref="homepage"
diff --git a/chromium/chrome/browser/resources/options/hotword_confirm_overlay.css b/chromium/chrome/browser/resources/options/hotword_confirm_overlay.css
new file mode 100644
index 00000000000..6fc7648e239
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/hotword_confirm_overlay.css
@@ -0,0 +1,12 @@
+/* Copyright 2014 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.
+ */
+
+#hotword-confirm-overlay {
+ width: 500px;
+}
+
+#audio-logging-bar input {
+ bottom: 6px;
+}
diff --git a/chromium/chrome/browser/resources/options/hotword_confirm_overlay.html b/chromium/chrome/browser/resources/options/hotword_confirm_overlay.html
new file mode 100644
index 00000000000..25a61b3719d
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/hotword_confirm_overlay.html
@@ -0,0 +1,38 @@
+<div id="hotword-confirm-overlay" class="page" hidden>
+ <div class="close-button"></div>
+ <h1 i18n-content="hotwordConfirmOverlay"></h1>
+ <div class="content-area">
+ <span id="hotword-confirm-text" i18n-content="hotwordConfirmMessage">
+ </span>
+ </div>
+ <div class="action-area">
+ <div class="hbox stretch">
+ <a target="_blank" i18n-content="learnMore"
+ i18n-values="href:hotwordLearnMoreURL">
+ </a>
+ </div>
+ <div class="action-area-right">
+ <div class="button-strip">
+ <button id="hotword-confirm-cancel"
+ i18n-content="hotwordConfirmDisable">
+ </button>
+ <button id="hotword-confirm-ok" class="default-button"
+ i18n-content="hotwordConfirmEnable">
+ </button>
+ </div>
+ </div>
+ </div>
+ <div id="audio-logging-bar" class="gray-bottom-bar checkbox">
+ <span class="controlled-setting-with-label">
+ <input id="hotword-audio-logging-enable"
+ pref="hotword.audio_logging_enabled"
+ metric="Options_Hotword_AudioLogging_Checkbox"
+ type="checkbox" dialog-pref checked>
+ <span>
+ <label for="hotword-audio-logging-enable"
+ i18n-content="hotwordAudioLoggingEnable">
+ </label>
+ </span>
+ </span>
+ </div>
+</div>
diff --git a/chromium/chrome/browser/resources/options/hotword_search_setting_indicator.css b/chromium/chrome/browser/resources/options/hotword_search_setting_indicator.css
new file mode 100644
index 00000000000..1abdeb6a076
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/hotword_search_setting_indicator.css
@@ -0,0 +1,10 @@
+/* Copyright 2014 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. */
+
+/* Hotword extension-specific controlled setting indicator and bubble. */
+
+#hotword-search-setting-indicator > div {
+ background: url('chrome://theme/IDR_WARNING') left top no-repeat;
+ background-size: 18px;
+}
diff --git a/chromium/chrome/browser/resources/options/hotword_search_setting_indicator.js b/chromium/chrome/browser/resources/options/hotword_search_setting_indicator.js
new file mode 100644
index 00000000000..035a1d317ab
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/hotword_search_setting_indicator.js
@@ -0,0 +1,115 @@
+// Copyright 2014 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 */ var ControlledSettingIndicator =
+ options.ControlledSettingIndicator;
+
+ /**
+ * A variant of the {@link ControlledSettingIndicator} that shows the status
+ * of the hotword search setting, including a bubble to show setup errors
+ * (such as failures to download extension resources).
+ * @constructor
+ * @extends {HTMLSpanElement}
+ */
+ var HotwordSearchSettingIndicator = cr.ui.define('span');
+
+ HotwordSearchSettingIndicator.prototype = {
+ __proto__: ControlledSettingIndicator.prototype,
+
+ /**
+ * Decorates the base element to show the proper icon.
+ * @override
+ */
+ decorate: function() {
+ ControlledSettingIndicator.prototype.decorate.call(this);
+ this.hidden = true;
+ },
+
+ /* Handle changes to the associated pref by hiding any currently visible
+ * bubble.
+ * @param {Event} event Pref change event.
+ * @override
+ */
+ handlePrefChange: function(event) {
+ OptionsPage.hideBubble();
+ },
+
+ /**
+ * Sets the variable tracking thesection which becomes disabled if an
+ * error exists.
+ * @param {HTMLElement} section The section to disable.
+ */
+ set disabledOnErrorSection(section) {
+ this.disabledOnErrorSection_ = section;
+ },
+
+ /**
+ * Assigns a value to the error message and updates the hidden state
+ * and whether the disabled section is disabled or not.
+ * @param {string} errorMsg The error message to be displayed. If none,
+ * there is no error.
+ */
+ set errorText(errorMsg) {
+ this.setAttribute('controlled-by', 'policy');
+ this.errorText_ = errorMsg;
+ if (errorMsg)
+ this.hidden = false;
+ if (this.disabledOnErrorSection_)
+ this.disabledOnErrorSection_.disabled = (errorMsg ? true : false);
+ },
+
+ /**
+ * Assigns a value to the help link variable.
+ * @param {string} helpLink The text that links to a troubleshooting page.
+ */
+ set helpLink(helpLinkText) {
+ this.helpLink_ = helpLinkText;
+ },
+
+ /**
+ * Toggles showing and hiding the error message bubble. An empty
+ * |errorText_| indicates that there is no error message. So the bubble
+ * only be shown if |errorText_| has a value.
+ */
+ toggleBubble_: function() {
+ if (this.showingBubble) {
+ OptionsPage.hideBubble();
+ return;
+ }
+
+ if (!this.errorText_)
+ return;
+
+ var self = this;
+ // Create the DOM tree for the bubble content.
+ var closeButton = document.createElement('div');
+ closeButton.classList.add('close-button');
+
+ var text = document.createElement('p');
+ text.innerHTML = this.errorText_;
+
+ var help = document.createElement('p');
+ help.innerHTML = this.helpLink_;
+
+ var textDiv = document.createElement('div');
+ textDiv.appendChild(text);
+ textDiv.appendChild(help);
+
+ var container = document.createElement('div');
+ container.appendChild(closeButton);
+ container.appendChild(textDiv);
+
+ var content = document.createElement('div');
+ content.appendChild(container);
+
+ OptionsPage.showBubble(content, this.image, this, this.location);
+ },
+ };
+
+ // Export
+ return {
+ HotwordSearchSettingIndicator: HotwordSearchSettingIndicator
+ };
+});
diff --git a/chromium/chrome/browser/resources/options/import_data_overlay.html b/chromium/chrome/browser/resources/options/import_data_overlay.html
index 57215089b87..4aca7cfcb4c 100644
--- a/chromium/chrome/browser/resources/options/import_data_overlay.html
+++ b/chromium/chrome/browser/resources/options/import_data_overlay.html
@@ -116,7 +116,9 @@
</div>
</div>
</div>
+<if expr="is_macosx">
<div id="mac-password-keychain" class="gray-bottom-bar">
<span i18n-content="macPasswordKeychain"></span>
</div>
+</if>
</div>
diff --git a/chromium/chrome/browser/resources/options/import_data_overlay.js b/chromium/chrome/browser/resources/options/import_data_overlay.js
index 16b8cca6ff2..f6fb061af30 100644
--- a/chromium/chrome/browser/resources/options/import_data_overlay.js
+++ b/chromium/chrome/browser/resources/options/import_data_overlay.js
@@ -62,13 +62,6 @@ cr.define('options', function() {
chrome.send('chooseBookmarksFile');
};
- $('import-data-show-bookmarks-bar').onchange = function() {
- // Note: The callback 'toggleShowBookmarksBar' is handled within the
- // browser options handler -- rather than the import data handler --
- // as the implementation is shared by several clients.
- chrome.send('toggleShowBookmarksBar');
- }
-
$('import-data-confirm').onclick = function() {
ImportDataOverlay.dismiss();
};
@@ -100,7 +93,9 @@ cr.define('options', function() {
this.setUpCheckboxState_(checkboxes[i], enabled);
$('import-data-commit').disabled = !enabled;
$('import-choose-file').hidden = !enabled;
+<if expr="is_macosx">
$('mac-password-keychain').hidden = !enabled;
+</if>
},
/**
@@ -147,7 +142,9 @@ cr.define('options', function() {
if (this.browserProfiles.length > index)
browserProfile = this.browserProfiles[index];
var enable = browserProfile && browserProfile['show_bottom_bar'];
+<if expr="is_macosx">
$('mac-password-keychain').hidden = !enable;
+</if>
},
/**
diff --git a/chromium/chrome/browser/resources/options/language_options.css b/chromium/chrome/browser/resources/options/language_options.css
index 4e86bbbe02b..07f968f1ccb 100644
--- a/chromium/chrome/browser/resources/options/language_options.css
+++ b/chromium/chrome/browser/resources/options/language_options.css
@@ -2,6 +2,10 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
+#languagePage .content-area {
+ width: 660px;
+}
+
.language-options {
display: -webkit-box;
margin: 10px 0;
@@ -25,7 +29,8 @@
padding: 0 12px 4px;
}
-.language-options-contents > span:not(.input-method-label) {
+.language-options-contents >
+ span:not(.input-method-label):not(.controlled-setting-indicator) {
display: inline-block;
margin: 1px;
padding: 0.42em 10px;
@@ -59,9 +64,10 @@
}
#language-options-details {
+ -webkit-box-flex: 1;
/* To share the center line with the left pane. */
-webkit-margin-start: -1px;
- width: 360px;
+ overflow-y: auto;
}
#language-options-details h3:not(:first-of-type) {
diff --git a/chromium/chrome/browser/resources/options/language_options.html b/chromium/chrome/browser/resources/options/language_options.html
index e2d420cb61a..cc8ef30d698 100644
--- a/chromium/chrome/browser/resources/options/language_options.html
+++ b/chromium/chrome/browser/resources/options/language_options.html
@@ -7,10 +7,12 @@
<span class="link"><span class="link-color"></span></span>
</div>
<div class="language-options-header">
- <div i18n-content="addLanguageInstructions"></div>
-<if expr="pp_ifdef('chromeos')">
- <div i18n-content="inputMethodInstructions"></div>
+ <span i18n-content="addLanguageInstructions"></span>
+<if expr="chromeos">
+ <span i18n-content="inputMethodInstructions"></span>
</if>
+ <a target="_blank" i18n-content="learnMore"
+ i18n-values="href:languagesLearnMoreURL"></a>
</div>
<div class="language-options">
<div id="language-options-languages">
@@ -25,11 +27,12 @@
</div>
<div id="language-options-details">
<h3 id="language-options-language-name"></h3>
-<if expr="os == 'win32' or pp_ifdef('chromeos')">
+<if expr="os == 'win32' or chromeos">
<div class="language-options-contents">
<button id="language-options-ui-language-button"
i18n-content="displayInThisLanguage">
</button>
+ <span class="controlled-setting-indicator"></span>
<span id="language-options-ui-language-message" hidden></span>
</div>
</if>
@@ -59,7 +62,7 @@
<div id="language-options-ui-notification-bar"
class="language-options-notification" hidden>
<div i18n-content="restartRequired"></div>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<button id="language-options-ui-restart-button"
i18n-content="restartButton">
</button>
@@ -78,7 +81,7 @@
<span id="cannot-translate-in-this-language"
i18n-content="cannotTranslateInThisLanguage" hidden></span>
</div>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<h3 i18n-content="inputMethod"></h3>
<div id="language-options-input-method-template" class="input-method"
hidden>
@@ -99,14 +102,14 @@
</div>
</div>
<div class="language-options-footer">
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<div i18n-content="switchInputMethodsHint"></div>
<div i18n-content="selectPreviousInputMethodHint"></div>
<button id="edit-dictionary-button"
class="link-button standalone-link-button"
i18n-content="languageDictionaryOverlayTitle"></button>
</if>
-<if expr="not pp_ifdef('chromeos') and not is_macosx">
+<if expr="not chromeos and not is_macosx">
<div id="spell-check-option" class="checkbox">
<label>
<input id="enable-spell-check" pref="browser.enable_spellchecking"
diff --git a/chromium/chrome/browser/resources/options/language_options.js b/chromium/chrome/browser/resources/options/language_options.js
index 3ebf7d2665b..f8801975253 100644
--- a/chromium/chrome/browser/resources/options/language_options.js
+++ b/chromium/chrome/browser/resources/options/language_options.js
@@ -8,6 +8,8 @@
cr.define('options', function() {
/** @const */ var OptionsPage = options.OptionsPage;
/** @const */ var LanguageList = options.LanguageList;
+ /** @const */ var ThirdPartyImeConfirmOverlay =
+ options.ThirdPartyImeConfirmOverlay;
/**
* Spell check dictionary download status.
@@ -318,6 +320,7 @@ cr.define('options', function() {
var input = element.querySelector('input');
input.inputMethodId = inputMethod.id;
+ input.imeProvider = inputMethod.extensionName;
var span = element.querySelector('span');
span.textContent = inputMethod.displayName;
@@ -426,14 +429,6 @@ cr.define('options', function() {
},
/**
- * Happens when a user changes back to the language they're currently using.
- */
- currentLocaleWasReselected: function() {
- this.updateUiLanguageButton_(
- loadTimeData.getString('currentUiLanguageCode'));
- },
-
- /**
* Handles languageOptionsList's save event.
* @param {Event} e Save event.
* @private
@@ -557,6 +552,11 @@ cr.define('options', function() {
// hidden by a language change.
uiLanguageButton.hidden = false;
+ // Hide the controlled setting indicator.
+ var uiLanguageIndicator = document.querySelector(
+ '.language-options-contents .controlled-setting-indicator');
+ uiLanguageIndicator.removeAttribute('controlled-by');
+
if (languageCode == this.prospectiveUiLanguageCode_) {
uiLanguageMessage.textContent =
loadTimeData.getString('isDisplayedInThisLanguage');
@@ -571,11 +571,18 @@ cr.define('options', function() {
} else {
uiLanguageButton.textContent =
loadTimeData.getString('displayInThisLanguage');
+
+ if (loadTimeData.valueExists('secondaryUser') &&
+ loadTimeData.getBoolean('secondaryUser')) {
+ uiLanguageButton.disabled = true;
+ uiLanguageIndicator.setAttribute('controlled-by', 'shared');
+ } else {
+ uiLanguageButton.onclick = function(e) {
+ chrome.send('uiLanguageChange', [languageCode]);
+ };
+ }
showMutuallyExclusiveNodes(
[uiLanguageButton, uiLanguageMessage, uiLanguageNotification], 0);
- uiLanguageButton.onclick = function(e) {
- chrome.send('uiLanguageChange', [languageCode]);
- };
}
} else {
uiLanguageMessage.textContent =
@@ -819,6 +826,31 @@ cr.define('options', function() {
handleCheckboxClick_: function(e) {
var checkbox = e.target;
+ // Third party IMEs require additional confirmation prior to enabling due
+ // to privacy risk.
+ if (/^_ext_ime_/.test(checkbox.inputMethodId) && checkbox.checked) {
+ var confirmationCallback = this.handleCheckboxUpdate_.bind(this,
+ checkbox);
+ var cancellationCallback = function() {
+ checkbox.checked = false;
+ };
+ ThirdPartyImeConfirmOverlay.showConfirmationDialog({
+ extension: checkbox.imeProvider,
+ confirm: confirmationCallback,
+ cancel: cancellationCallback
+ });
+ } else {
+ this.handleCheckboxUpdate_(checkbox);
+ }
+ },
+
+ /**
+ * Updates active IMEs based on change in state of a checkbox for an input
+ * method.
+ * @param {!Element} checkbox Updated checkbox element.
+ * @private
+ */
+ handleCheckboxUpdate_: function(checkbox) {
if (checkbox.inputMethodId.match(/^_ext_ime_/)) {
this.updateEnabledExtensionsFromCheckboxes_();
this.saveEnabledExtensionPref_();
@@ -842,7 +874,12 @@ cr.define('options', function() {
this.savePreloadEnginesPref_();
},
- handleAddLanguageOkButtonClick_: function() {
+ /**
+ * Handles clicks on the "OK" button of the "Add language" dialog.
+ * @param {Event} e Click event.
+ * @private
+ */
+ handleAddLanguageOkButtonClick_: function(e) {
var languagesSelect = $('add-language-overlay-language-list');
var selectedIndex = languagesSelect.selectedIndex;
if (selectedIndex >= 0) {
@@ -1181,6 +1218,39 @@ cr.define('options', function() {
delayedHide();
},
+ /**
+ * Chrome callback for when the UI language preference is saved.
+ * @param {string} languageCode The newly selected language to use.
+ * @private
+ */
+ uiLanguageSaved_: function(languageCode) {
+ this.prospectiveUiLanguageCode_ = languageCode;
+
+ // If the user is no longer on the same language code, ignore.
+ if ($('language-options-list').getSelectedLanguageCode() != languageCode)
+ return;
+
+ // Special case for when a user changes to a different language, and
+ // changes back to the same language without having restarted Chrome or
+ // logged in/out of ChromeOS.
+ if (languageCode == loadTimeData.getString('currentUiLanguageCode')) {
+ this.updateUiLanguageButton_(languageCode);
+ return;
+ }
+
+ // Otherwise, show a notification telling the user that their changes will
+ // only take effect after restart.
+ showMutuallyExclusiveNodes([$('language-options-ui-language-button'),
+ $('language-options-ui-notification-bar')],
+ 1);
+ },
+
+ /**
+ * A handler for when dictionary for |languageCode| begins downloading.
+ * @param {string} languageCode The language of the dictionary that just
+ * began downloading.
+ * @private
+ */
onDictionaryDownloadBegin_: function(languageCode) {
this.spellcheckDictionaryDownloadStatus_[languageCode] =
DOWNLOAD_STATUS.IN_PROGRESS;
@@ -1191,6 +1261,12 @@ cr.define('options', function() {
}
},
+ /**
+ * A handler for when dictionary for |languageCode| successfully downloaded.
+ * @param {string} languageCode The language of the dictionary that
+ * succeeded downloading.
+ * @private
+ */
onDictionaryDownloadSuccess_: function(languageCode) {
delete this.spellcheckDictionaryDownloadStatus_[languageCode];
this.spellcheckDictionaryDownloadFailures_ = 0;
@@ -1201,6 +1277,12 @@ cr.define('options', function() {
}
},
+ /**
+ * A handler for when dictionary for |languageCode| fails to download.
+ * @param {string} languageCode The language of the dictionary that failed
+ * to download.
+ * @private
+ */
onDictionaryDownloadFailure_: function(languageCode) {
this.spellcheckDictionaryDownloadStatus_[languageCode] =
DOWNLOAD_STATUS.FAILED;
@@ -1256,29 +1338,8 @@ cr.define('options', function() {
}
}
- /**
- * Chrome callback for when the UI language preference is saved.
- * @param {string} languageCode The newly selected language to use.
- */
LanguageOptions.uiLanguageSaved = function(languageCode) {
- this.prospectiveUiLanguageCode_ = languageCode;
-
- // If the user is no longer on the same language code, ignore.
- if ($('language-options-list').getSelectedLanguageCode() != languageCode)
- return;
-
- // Special case for when a user changes to a different language, and changes
- // back to the same language without having restarted Chrome or logged
- // in/out of ChromeOS.
- if (languageCode == loadTimeData.getString('currentUiLanguageCode')) {
- LanguageOptions.getInstance().currentLocaleWasReselected();
- return;
- }
-
- // Otherwise, show a notification telling the user that their changes will
- // only take effect after restart.
- showMutuallyExclusiveNodes([$('language-options-ui-language-button'),
- $('language-options-ui-notification-bar')], 1);
+ LanguageOptions.getInstance().uiLanguageSaved_(languageCode);
};
LanguageOptions.onDictionaryDownloadBegin = function(languageCode) {
diff --git a/chromium/chrome/browser/resources/options/manage_profile_overlay.css b/chromium/chrome/browser/resources/options/manage_profile_overlay.css
index 760030db3d2..1c2ed4416f8 100644
--- a/chromium/chrome/browser/resources/options/manage_profile_overlay.css
+++ b/chromium/chrome/browser/resources/options/manage_profile_overlay.css
@@ -23,6 +23,10 @@
margin-top: 5px;
}
+#create-profile-name-input-container {
+ margin-bottom: 5px;
+}
+
#create-profile-name,
#manage-profile-name {
margin-left: 10px;
@@ -33,6 +37,19 @@
background-color: pink;
}
+#disconnect-managed-profile-domain-name {
+ font-weight: bold;
+}
+
+#disconnect-managed-profile-domain-information {
+ background-color: #f0f0f0;
+ padding: 14px 0 14px 17px;
+}
+
+#disconnect-managed-profile-message {
+ padding-top: 9px;
+}
+
#create-profile-error-bubble,
#manage-profile-error-bubble {
-webkit-transition: max-height 200ms, padding 200ms;
@@ -43,11 +60,21 @@
margin-right: auto;
max-height: 50px;
overflow: hidden;
- padding: 1px 10px;
+ padding: 10px 10px;
text-align: center;
width: 80%;
}
+html[dir='ltr'] #create-profile-error-bubble {
+ margin-left: 20px;
+ width: 90%;
+}
+
+html[dir='rtl'] #create-profile-error-bubble {
+ margin-right: 20px;
+ width: 90%;
+}
+
#create-profile-error-bubble[hidden],
#manage-profile-error-bubble[hidden] {
display: block !important;
@@ -121,10 +148,15 @@ html[dir='rtl'] #delete-profile-icon {
}
#create-profile-managed-content-area {
- padding-top: 0;
+ padding-top: 5px;
}
#import-existing-managed-user-link {
left: 17px;
position: absolute;
}
+
+#supervised-user-import {
+ margin: 0;
+ padding: 0;
+}
diff --git a/chromium/chrome/browser/resources/options/manage_profile_overlay.html b/chromium/chrome/browser/resources/options/manage_profile_overlay.html
index 42ccfb21cae..e8a6515c92e 100644
--- a/chromium/chrome/browser/resources/options/manage_profile_overlay.html
+++ b/chromium/chrome/browser/resources/options/manage_profile_overlay.html
@@ -52,6 +52,29 @@
i18n-content="deleteProfileOK"></button>
</div>
</div>
+ <!-- Dialog for disconnecting enterprise managed profiles. -->
+ <div id="manage-profile-overlay-disconnect-managed" hidden>
+ <h1 i18n-content="disconnectManagedProfileTitle"></h1>
+ <div class="content-area"
+ id="disconnect-managed-profile-domain-information"
+ i18n-values=".innerHTML:disconnectManagedProfileDomainInformation">
+ </div>
+ <div class="content-area">
+ <div id="disconnect-managed-profile-message">
+ <div id="disconnect-managed-profile-text"
+ i18n-values=".innerHTML:disconnectManagedProfileText">
+ </div>
+ </div>
+ </div>
+ <div class="action-area">
+ <div class="button-strip">
+ <button id="disconnect-managed-profile-ok"
+ i18n-content="disconnectManagedProfileOK"></button>
+ <button id="disconnect-managed-profile-cancel" class="default-button"
+ i18n-content="cancel"></button>
+ </div>
+ </div>
+ </div>
<!-- Dialog for creating profiles. -->
<div id="manage-profile-overlay-create" hidden>
<h1 i18n-content="createProfileTitle"></h1>
@@ -66,7 +89,6 @@
<input id="create-profile-name" type="text" required>
</label>
</div>
- <div id="create-profile-error-bubble" hidden></div>
</div>
<div id="create-profile-managed-content-area" class="content-area">
<div id="create-shortcut-container" class="checkbox" hidden>
@@ -107,11 +129,12 @@
class="bubble-button controlled-setting-indicator">
</span>
</div>
+ <div id="create-profile-error-bubble" hidden></div>
</div>
<div class="action-area">
<div id="create-profile-throbber" class="throbber"></div>
<button id="import-existing-managed-user-link" class="link-button"
- i18n-content="importExistingManagedUserLink">
+ i18n-content="importExistingManagedUserLink" hidden>
</button>
<div class="button-strip">
<button id="create-profile-cancel" i18n-content="cancel"></button>
diff --git a/chromium/chrome/browser/resources/options/manage_profile_overlay.js b/chromium/chrome/browser/resources/options/manage_profile_overlay.js
index 2d6e64c717f..723d6cd1cc8 100644
--- a/chromium/chrome/browser/resources/options/manage_profile_overlay.js
+++ b/chromium/chrome/browser/resources/options/manage_profile_overlay.js
@@ -27,8 +27,16 @@ cr.define('options', function() {
// Info about the currently managed/deleted profile.
profileInfo_: null,
- // An object containing all known profile names.
- profileNames_: {},
+ // Whether the currently chosen name for a new profile was assigned
+ // automatically by choosing an avatar. Set on receiveNewProfileDefaults;
+ // cleared on first edit (in onNameChanged_).
+ profileNameIsDefault_: false,
+
+ // List of default profile names corresponding to the respective icons.
+ defaultProfileNames_: [],
+
+ // An object containing all names of existing profiles.
+ existingProfileNames_: {},
// The currently selected icon in the icon grid.
iconGridSelectedURL_: null,
@@ -58,10 +66,8 @@ cr.define('options', function() {
CreateProfileOverlay.cancelCreateProfile();
};
- $('import-existing-managed-user-link').hidden =
- !loadTimeData.getBoolean('allowCreateExistingManagedUsers');
-
$('manage-profile-cancel').onclick =
+ $('disconnect-managed-profile-cancel').onclick =
$('delete-profile-cancel').onclick = function(event) {
OptionsPage.closeOverlay();
};
@@ -70,6 +76,7 @@ cr.define('options', function() {
if (BrowserOptions.getCurrentProfile().isManaged)
return;
chrome.send('deleteProfile', [self.profileInfo_.filePath]);
+ options.ManagedUserListData.resetPromise();
};
$('add-shortcut-button').onclick = function(event) {
chrome.send('addProfileShortcut', [self.profileInfo_.filePath]);
@@ -78,6 +85,12 @@ cr.define('options', function() {
chrome.send('removeProfileShortcut', [self.profileInfo_.filePath]);
};
+ $('disconnect-managed-profile-ok').onclick = function(event) {
+ OptionsPage.closeOverlay();
+ chrome.send('deleteProfile',
+ [BrowserOptions.getCurrentProfile().filePath]);
+ }
+
$('create-profile-managed-signed-in-learn-more-link').onclick =
function(event) {
OptionsPage.navigateToPage('managedUserLearnMore');
@@ -100,14 +113,17 @@ cr.define('options', function() {
};
$('import-existing-managed-user-link').onclick = function(event) {
- OptionsPage.closeOverlay();
+ // Hide the import button to trigger a cursor update. The import button
+ // is shown again when the import overlay loads. TODO(akuegel): Remove
+ // this temporary fix when crbug/246304 is resolved.
+ $('import-existing-managed-user-link').hidden = true;
OptionsPage.navigateToPage('managedUserImport');
};
},
/** @override */
didShowPage: function() {
- chrome.send('requestDefaultProfileIcons');
+ chrome.send('requestDefaultProfileIcons', ['manage']);
// Just ignore the manage profile dialog on Chrome OS, they use /accounts.
if (!cr.isChromeOS && window.location.pathname == '/manageProfile')
@@ -130,13 +146,14 @@ cr.define('options', function() {
$('manage-profile-ok').focus();
else
manageNameField.focus();
+
+ this.profileNameIsDefault_ = false;
},
/**
* Registers event handlers that are common between create and manage modes.
- * @param {string} mode A label that specifies the type of dialog
- * box which is currently being viewed (i.e. 'create' or
- * 'manage').
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
* @param {function()} submitFunction The function that should be called
* when the user chooses to submit (e.g. by clicking the OK button).
* @private
@@ -147,7 +164,7 @@ cr.define('options', function() {
self.onIconGridSelectionChanged_(mode);
});
$(mode + '-profile-name').oninput = function(event) {
- self.onNameChanged_(event, mode);
+ self.onNameChanged_(mode);
};
$(mode + '-profile-ok').onclick = function(event) {
OptionsPage.closeOverlay();
@@ -165,9 +182,8 @@ cr.define('options', function() {
* isCurrentProfile: false,
* isManaged: false
* };
- * @param {string} mode A label that specifies the type of dialog
- * box which is currently being viewed (i.e. 'create' or
- * 'manage').
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
* @private
*/
setProfileInfo_: function(profileInfo, mode) {
@@ -178,28 +194,38 @@ cr.define('options', function() {
},
/**
- * Sets the name of the currently edited profile.
+ * Sets the name of the profile being edited or created.
+ * @param {string} name New profile name.
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
* @private
*/
- setProfileName_: function(name) {
+ setProfileName_: function(name, mode) {
if (this.profileInfo_)
this.profileInfo_.name = name;
- $('manage-profile-name').value = name;
+ $(mode + '-profile-name').value = name;
},
/**
* Set an array of default icon URLs. These will be added to the grid that
* the user will use to choose their profile icon.
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
* @param {Array.<string>} iconURLs An array of icon URLs.
+ * @param {Array.<string>} names An array of default names
+ * corresponding to the icons.
* @private
*/
- receiveDefaultProfileIcons_: function(iconGrid, iconURLs) {
- $(iconGrid).dataModel = new ArrayDataModel(iconURLs);
+ receiveDefaultProfileIconsAndNames_: function(mode, iconURLs, names) {
+ this.defaultProfileNames_ = names;
+
+ var grid = $(mode + '-profile-icon-grid');
+
+ grid.dataModel = new ArrayDataModel(iconURLs);
if (this.profileInfo_)
- $(iconGrid).selectedItem = this.profileInfo_.iconURL;
+ grid.selectedItem = this.profileInfo_.iconURL;
- var grid = $(iconGrid);
// Recalculate the measured item size.
grid.measured_ = null;
grid.columns = 0;
@@ -217,6 +243,7 @@ cr.define('options', function() {
*/
receiveNewProfileDefaults_: function(profileInfo) {
ManageProfileOverlay.setProfileInfo(profileInfo, 'create');
+ this.profileNameIsDefault_ = true;
$('create-profile-name-label').hidden = false;
$('create-profile-name').hidden = false;
// Trying to change the focus if this isn't the topmost overlay can
@@ -239,8 +266,8 @@ cr.define('options', function() {
* @param {Object} profileNames A dictionary of profile names.
* @private
*/
- receiveProfileNames_: function(profileNames) {
- this.profileNames_ = profileNames;
+ receiveExistingProfileNames_: function(profileNames) {
+ this.existingProfileNames_ = profileNames;
},
/**
@@ -256,20 +283,19 @@ cr.define('options', function() {
},
/**
- * Display the error bubble, with |errorText| in the bubble.
- * @param {string} errorText The string to display as an error.
- * @param {string} mode A label that specifies the type of dialog
- * box which is currently being viewed (i.e. 'create' or
- * 'manage').
+ * Display the error bubble, with |errorHtml| in the bubble.
+ * @param {string} errorHtml The html string to display as an error.
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
* @param {boolean} disableOKButton True if the dialog's OK button should be
* disabled when the error bubble is shown. It will be (re-)enabled when
* the error bubble is hidden.
* @private
*/
- showErrorBubble_: function(errorText, mode, disableOKButton) {
+ showErrorBubble_: function(errorHtml, mode, disableOKButton) {
var nameErrorEl = $(mode + '-profile-error-bubble');
nameErrorEl.hidden = false;
- nameErrorEl.textContent = errorText;
+ nameErrorEl.innerHTML = errorHtml;
if (disableOKButton)
$(mode + '-profile-ok').disabled = true;
@@ -277,34 +303,123 @@ cr.define('options', function() {
/**
* Hide the error bubble.
- * @param {string} mode A label that specifies the type of dialog
- * box which is currently being viewed (i.e. 'create' or
- * 'manage').
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
* @private
*/
hideErrorBubble_: function(mode) {
+ $(mode + '-profile-error-bubble').innerHTML = '';
$(mode + '-profile-error-bubble').hidden = true;
$(mode + '-profile-ok').disabled = false;
},
/**
* oninput callback for <input> field.
- * @param {Event} event The event object.
- * @param {string} mode A label that specifies the type of dialog
- * box which is currently being viewed (i.e. 'create' or
- * 'manage').
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
* @private
*/
- onNameChanged_: function(event, mode) {
- var newName = event.target.value;
- var oldName = this.profileInfo_.name;
+ onNameChanged_: function(mode) {
+ this.profileNameIsDefault_ = false;
+ this.updateCreateOrImport_(mode);
+ },
- if (newName == oldName) {
- this.hideErrorBubble_(mode);
- } else if (this.profileNames_[newName] != undefined) {
- var errorText =
+ /**
+ * Called when the profile name is changed or the 'create managed' checkbox
+ * is toggled. Updates the 'ok' button and the 'import existing supervised
+ * user' link.
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
+ * @private
+ */
+ updateCreateOrImport_: function(mode) {
+ // In 'create' mode, check for existing managed users with the same name.
+ if (mode == 'create' && $('create-profile-managed').checked) {
+ options.ManagedUserListData.requestExistingManagedUsers().then(
+ this.receiveExistingManagedUsers_.bind(this),
+ this.onSigninError_.bind(this));
+ } else {
+ this.updateOkButton_(mode);
+ }
+ },
+
+ /**
+ * Callback which receives the list of existing managed users. Checks if the
+ * currently entered name is the name of an already existing managed user.
+ * If yes, the user is prompted to import the existing managed user, and the
+ * create button is disabled.
+ * @param {Array.<Object>} The list of existing managed users.
+ * @private
+ */
+ receiveExistingManagedUsers_: function(managedUsers) {
+ var newName = $('create-profile-name').value;
+ var i;
+ for (i = 0; i < managedUsers.length; ++i) {
+ if (managedUsers[i].name == newName &&
+ !managedUsers[i].onCurrentDevice) {
+ var errorHtml = loadTimeData.getStringF(
+ 'manageProfilesExistingSupervisedUser',
+ HTMLEscape(elide(newName, /* maxLength */ 50)));
+ this.showErrorBubble_(errorHtml, 'create', true);
+
+ // Check if another supervised user also exists with that name.
+ var nameIsUnique = true;
+ var j;
+ for (j = i + 1; j < managedUsers.length; ++j) {
+ if (managedUsers[j].name == newName) {
+ nameIsUnique = false;
+ break;
+ }
+ }
+ var self = this;
+ function getImportHandler(managedUser, nameIsUnique) {
+ return function() {
+ if (managedUser.needAvatar || !nameIsUnique) {
+ OptionsPage.navigateToPage('managedUserImport');
+ } else {
+ self.hideErrorBubble_('create');
+ CreateProfileOverlay.updateCreateInProgress(true);
+ chrome.send('createProfile',
+ [managedUser.name, managedUser.iconURL, false, true,
+ managedUser.id]);
+ }
+ }
+ };
+ $('supervised-user-import').onclick =
+ getImportHandler(managedUsers[i], nameIsUnique);
+ $('create-profile-ok').disabled = true;
+ return;
+ }
+ }
+ this.updateOkButton_('create');
+ },
+
+ /**
+ * Called in case the request for the list of managed users fails because of
+ * a signin error.
+ * @private
+ */
+ onSigninError_: function() {
+ this.updateImportExistingManagedUserLink_(false);
+ },
+
+ /**
+ * Called to update the state of the ok button depending if the name is
+ * already used or not.
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
+ * @private
+ */
+ updateOkButton_: function(mode) {
+ var oldName = this.profileInfo_.name;
+ var newName = $(mode + '-profile-name').value;
+ var nameIsDuplicate = this.existingProfileNames_[newName] != undefined;
+ if (mode == 'manage' && oldName == newName)
+ nameIsDuplicate = false;
+ if (nameIsDuplicate) {
+ var errorHtml =
loadTimeData.getString('manageProfilesDuplicateNameError');
- this.showErrorBubble_(errorText, mode, true);
+ this.showErrorBubble_(errorHtml, mode, true);
} else {
this.hideErrorBubble_(mode);
@@ -324,6 +439,8 @@ cr.define('options', function() {
chrome.send('setProfileIconAndName',
[this.profileInfo_.filePath, iconURL, name]);
+ if (name != this.profileInfo_.name)
+ options.ManagedUserListData.resetPromise();
},
/**
@@ -356,9 +473,8 @@ cr.define('options', function() {
/**
* Called when the selected icon in the icon grid changes.
- * @param {string} mode A label that specifies the type of dialog
- * box which is currently being viewed (i.e. 'create' or
- * 'manage').
+ * @param {string} mode A label that specifies the type of dialog box which
+ * is currently being viewed (i.e. 'create' or 'manage').
* @private
*/
onIconGridSelectionChanged_: function(mode) {
@@ -366,6 +482,13 @@ cr.define('options', function() {
if (!iconURL || iconURL == this.iconGridSelectedURL_)
return;
this.iconGridSelectedURL_ = iconURL;
+ if (this.profileNameIsDefault_) {
+ var index = $(mode + '-profile-icon-grid').selectionModel.selectedIndex;
+ var name = this.defaultProfileNames_[index];
+ if (name) {
+ this.setProfileName_(name, mode);
+ }
+ }
if (this.profileInfo_ && this.profileInfo_.filePath) {
chrome.send('profileIconSelectionChanged',
[this.profileInfo_.filePath, iconURL]);
@@ -378,11 +501,13 @@ cr.define('options', function() {
* @private
*/
prepareForManageDialog_: function() {
+ chrome.send('refreshGaiaPicture');
var profileInfo = BrowserOptions.getCurrentProfile();
ManageProfileOverlay.setProfileInfo(profileInfo, 'manage');
$('manage-profile-overlay-create').hidden = true;
$('manage-profile-overlay-manage').hidden = false;
$('manage-profile-overlay-delete').hidden = true;
+ $('manage-profile-overlay-disconnect-managed').hidden = true;
$('manage-profile-name').disabled = profileInfo.isManaged;
this.hideErrorBubble_('manage');
},
@@ -409,10 +534,12 @@ cr.define('options', function() {
$('manage-profile-overlay-create').hidden = true;
$('manage-profile-overlay-manage').hidden = true;
$('manage-profile-overlay-delete').hidden = false;
+ $('manage-profile-overlay-disconnect-managed').hidden = true;
$('delete-profile-icon').style.content =
- imageset(profileInfo.iconURL + '@scalefactorx');
+ getProfileAvatarIcon(profileInfo.iconURL);
$('delete-profile-text').textContent =
- loadTimeData.getStringF('deleteProfileMessage', profileInfo.name);
+ loadTimeData.getStringF('deleteProfileMessage',
+ elide(profileInfo.name, /* maxLength */ 50));
$('delete-managed-profile-addendum').hidden = !profileInfo.isManaged;
// Because this dialog isn't useful when refreshing or as part of the
@@ -421,6 +548,26 @@ cr.define('options', function() {
},
/**
+ * Display the "Disconnect Managed Profile" dialog.
+ * @private
+ */
+ showDisconnectManagedProfileDialog_: function(replacements) {
+ loadTimeData.overrideValues(replacements);
+ $('manage-profile-overlay-create').hidden = true;
+ $('manage-profile-overlay-manage').hidden = true;
+ $('manage-profile-overlay-delete').hidden = true;
+ $('disconnect-managed-profile-domain-information').innerHTML =
+ loadTimeData.getString('disconnectManagedProfileDomainInformation');
+ $('disconnect-managed-profile-text').innerHTML =
+ loadTimeData.getString('disconnectManagedProfileText');
+ $('manage-profile-overlay-disconnect-managed').hidden = false;
+
+ // Because this dialog isn't useful when refreshing or as part of the
+ // history, don't create a history entry for it when showing.
+ OptionsPage.showPageByName('manageProfile', false);
+ },
+
+ /**
* Display the "Create Profile" dialog.
* @private
*/
@@ -431,14 +578,15 @@ cr.define('options', function() {
// Forward public APIs to private implementations.
[
- 'receiveDefaultProfileIcons',
+ 'receiveDefaultProfileIconsAndNames',
'receiveNewProfileDefaults',
- 'receiveProfileNames',
+ 'receiveExistingProfileNames',
'receiveHasProfileShortcuts',
'setProfileInfo',
'setProfileName',
'showManageDialog',
'showDeleteDialog',
+ 'showDisconnectManagedProfileDialog',
'showCreateDialog',
].forEach(function(name) {
ManageProfileOverlay[name] = function() {
@@ -474,12 +622,13 @@ cr.define('options', function() {
*/
didShowPage: function() {
chrome.send('requestCreateProfileUpdate');
- chrome.send('requestDefaultProfileIcons');
+ chrome.send('requestDefaultProfileIcons', ['create']);
chrome.send('requestNewProfileDefaults');
$('manage-profile-overlay-create').hidden = false;
$('manage-profile-overlay-manage').hidden = true;
$('manage-profile-overlay-delete').hidden = true;
+ $('manage-profile-overlay-disconnect-managed').hidden = true;
$('create-profile-instructions').textContent =
loadTimeData.getStringF('createProfileInstructions');
this.hideErrorBubble_();
@@ -494,9 +643,15 @@ cr.define('options', function() {
$('create-profile-ok').disabled = true;
$('create-profile-managed').checked = false;
+ $('import-existing-managed-user-link').hidden = true;
+ $('create-profile-managed').onchange = function() {
+ ManageProfileOverlay.getInstance().updateCreateOrImport_('create');
+ };
$('create-profile-managed-signed-in').disabled = true;
$('create-profile-managed-signed-in').hidden = true;
$('create-profile-managed-not-signed-in').hidden = true;
+
+ this.profileNameIsDefault_ = false;
},
/** @override */
@@ -505,8 +660,8 @@ cr.define('options', function() {
},
/** @override */
- showErrorBubble_: function(errorText) {
- ManageProfileOverlay.getInstance().showErrorBubble_(errorText,
+ showErrorBubble_: function(errorHtml) {
+ ManageProfileOverlay.getInstance().showErrorBubble_(errorHtml,
'create',
false);
},
@@ -532,6 +687,7 @@ cr.define('options', function() {
$('create-profile-name').disabled = inProgress;
$('create-shortcut').disabled = inProgress;
$('create-profile-ok').disabled = inProgress;
+ $('import-existing-managed-user-link').disabled = inProgress;
$('create-profile-throbber').hidden = !inProgress;
},
@@ -585,6 +741,7 @@ cr.define('options', function() {
this.updateCreateInProgress_(false);
OptionsPage.closeOverlay();
if (profileInfo.isManaged) {
+ options.ManagedUserListData.resetPromise();
profileInfo.custodianEmail = this.signedInEmail_;
ManagedUserCreateConfirmOverlay.setProfileInfo(profileInfo);
OptionsPage.showPageByName('managedUserCreateConfirm', false);
@@ -638,7 +795,8 @@ cr.define('options', function() {
*/
updateImportExistingManagedUserLink_: function(enable) {
var importManagedUserElement = $('import-existing-managed-user-link');
- importManagedUserElement.disabled = !enable;
+ importManagedUserElement.hidden = false;
+ importManagedUserElement.disabled = !enable || this.createInProgress_;
importManagedUserElement.textContent = enable ?
loadTimeData.getString('importExistingManagedUserLink') :
loadTimeData.getString('signInToImportManagedUsers');
diff --git a/chromium/chrome/browser/resources/options/managed_user_create_confirm.js b/chromium/chrome/browser/resources/options/managed_user_create_confirm.js
index de91bf9be9d..84bce024659 100644
--- a/chromium/chrome/browser/resources/options/managed_user_create_confirm.js
+++ b/chromium/chrome/browser/resources/options/managed_user_create_confirm.js
@@ -64,23 +64,9 @@ cr.define('options', function() {
* @private
*/
setProfileInfo_: function(info) {
- function HTMLEscape(original) {
- return original.replace(/&/g, '&amp;')
- .replace(/</g, '&lt;')
- .replace(/>/g, '&gt;')
- .replace(/"/g, '&quot;')
- .replace(/'/g, '&#39;');
- }
-
- var MAX_LENGTH = 50;
- function elide(original) {
- if (original.length <= MAX_LENGTH)
- return original;
- return original.substring(0, MAX_LENGTH - 3) + '...';
- }
-
this.profileInfo_ = info;
- var elidedName = elide(info.name);
+ var MAX_LENGTH = 50;
+ var elidedName = elide(info.name, MAX_LENGTH);
$('managed-user-created-title').textContent =
loadTimeData.getStringF('managedUserCreatedTitle', elidedName);
$('managed-user-created-switch').textContent =
@@ -92,7 +78,8 @@ cr.define('options', function() {
$('managed-user-created-text').innerHTML =
loadTimeData.getStringF('managedUserCreatedText',
HTMLEscape(elidedName),
- HTMLEscape(elide(info.custodianEmail)));
+ HTMLEscape(elide(info.custodianEmail,
+ MAX_LENGTH)));
},
/** @override */
diff --git a/chromium/chrome/browser/resources/options/managed_user_import.css b/chromium/chrome/browser/resources/options/managed_user_import.css
index 9dae8f1db4e..b0f94f571f8 100644
--- a/chromium/chrome/browser/resources/options/managed_user_import.css
+++ b/chromium/chrome/browser/resources/options/managed_user_import.css
@@ -2,15 +2,12 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-#create-new-user-link {
- position: absolute;
-}
-
#managed-user-import {
width: 612px;
}
-#managed-user-import-text {
+#managed-user-import-text,
+#managed-user-select-avatar-text {
padding-bottom: 10px;
padding-left: 17px;
white-space: pre-wrap;
diff --git a/chromium/chrome/browser/resources/options/managed_user_import.html b/chromium/chrome/browser/resources/options/managed_user_import.html
index db2674dc953..377002c5eba 100644
--- a/chromium/chrome/browser/resources/options/managed_user_import.html
+++ b/chromium/chrome/browser/resources/options/managed_user_import.html
@@ -1,24 +1,38 @@
<div id="managed-user-import" class="page" hidden>
<div class="close-button"></div>
<!-- Overlay to import an existing managed user during user creation -->
- <h1 id="managed-user-import-title"></h1>
- <div id="managed-user-import-text">
+ <h1 id="managed-user-import-title" i18n-content="managedUserImportTitle"
+ class="managed-user-import">
+ </h1>
+ <h1 id="managed-user-select-avatar-title"
+ i18n-content="managedUserSelectAvatarTitle"
+ class="managed-user-select-avatar" hidden>
+ </h1>
+ <div id="managed-user-import-text" i18n-content="managedUserImportText"
+ class="managed-user-import">
+ </div>
+ <div id="managed-user-select-avatar-text"
+ i18n-content="managedUserSelectAvatarText"
+ class="managed-user-select-avatar" hidden>
</div>
<div id="managed-user-import-content-area" class="content-area">
- <list id="managed-user-list" class="settings-list"></list>
- <grid id="select-avatar-grid" hidden></grid>
+ <list id="managed-user-list" class="settings-list managed-user-import">
+ </list>
+ <grid id="select-avatar-grid" class="managed-user-select-avatar" hidden></grid>
</div>
<div id="managed-user-import-error-bubble" hidden></div>
<div id="managed-user-import-action-area" class="action-area">
- <button id="create-new-user-link" class="link-button"
- i18n-content="createNewUserLink">
- </button>
<div class="button-strip">
<div id="managed-user-import-throbber" class="throbber"></div>
<button id="managed-user-import-cancel" i18n-content="cancel">
</button>
- <button id="managed-user-import-ok" class="default-button">
+ <button id="managed-user-import-ok" i18n-content="managedUserImportOk"
+ class="default-button managed-user-import">
+ </button>
+ <button id="managed-user-select-avatar-ok"
+ i18n-content="managedUserSelectAvatarOk"
+ class="default-button managed-user-select-avatar" hidden>
</button>
</div>
</div>
-</div> \ No newline at end of file
+</div>
diff --git a/chromium/chrome/browser/resources/options/managed_user_import.js b/chromium/chrome/browser/resources/options/managed_user_import.js
index 70a54dd2cab..f37e2209598 100644
--- a/chromium/chrome/browser/resources/options/managed_user_import.js
+++ b/chromium/chrome/browser/resources/options/managed_user_import.js
@@ -55,40 +55,65 @@ cr.define('options', function() {
var self = this;
$('managed-user-import-cancel').onclick = function(event) {
- OptionsPage.closeOverlay();
- self.updateImportInProgress_(false);
+ if (self.inProgress_) {
+ self.updateImportInProgress_(false);
- // 'cancelCreateProfile' is handled by CreateProfileHandler.
- chrome.send('cancelCreateProfile');
+ // 'cancelCreateProfile' is handled by CreateProfileHandler.
+ chrome.send('cancelCreateProfile');
+ }
+ OptionsPage.closeOverlay();
};
$('managed-user-import-ok').onclick =
this.showAvatarGridOrSubmit_.bind(this);
-
- $('create-new-user-link').onclick = function(event) {
- OptionsPage.closeOverlay();
- OptionsPage.navigateToPage('createProfile');
- };
+ $('managed-user-select-avatar-ok').onclick =
+ this.showAvatarGridOrSubmit_.bind(this);
},
/**
* @override
*/
didShowPage: function() {
- chrome.send('requestManagedUserImportUpdate');
+ // When the import link is clicked to open this overlay, it is hidden in
+ // order to trigger a cursor update. We can show the import link again
+ // now. TODO(akuegel): Remove this temporary fix when crbug/246304 is
+ // resolved.
+ $('import-existing-managed-user-link').hidden = false;
+
+ options.ManagedUserListData.requestExistingManagedUsers().then(
+ this.receiveExistingManagedUsers_, this.onSigninError_.bind(this));
+ options.ManagedUserListData.addObserver(this);
this.updateImportInProgress_(false);
$('managed-user-import-error-bubble').hidden = true;
$('managed-user-import-ok').disabled = true;
- $('select-avatar-grid').hidden = true;
- $('managed-user-list').hidden = false;
-
- $('managed-user-import-ok').textContent =
- loadTimeData.getString('managedUserImportOk');
- $('managed-user-import-text').textContent =
- loadTimeData.getString('managedUserImportText');
- $('managed-user-import-title').textContent =
- loadTimeData.getString('managedUserImportTitle');
+ this.showAppropriateElements_(/* isSelectAvatarMode */ false);
+ },
+
+ /**
+ * @override
+ */
+ didClosePage: function() {
+ options.ManagedUserListData.removeObserver(this);
+ },
+
+ /**
+ * Shows either the managed user import dom elements or the select avatar
+ * dom elements.
+ * @param {boolean} isSelectAvatarMode True if the overlay should show the
+ * select avatar grid, and false if the overlay should show the managed
+ * user list.
+ * @private
+ */
+ showAppropriateElements_: function(isSelectAvatarMode) {
+ var avatarElements =
+ this.pageDiv.querySelectorAll('.managed-user-select-avatar');
+ for (var i = 0; i < avatarElements.length; i++)
+ avatarElements[i].hidden = !isSelectAvatarMode;
+ var importElements =
+ this.pageDiv.querySelectorAll('.managed-user-import');
+ for (var i = 0; i < importElements.length; i++)
+ importElements[i].hidden = isSelectAvatarMode;
},
/**
@@ -128,18 +153,10 @@ cr.define('options', function() {
* @private
*/
showAvatarGridHelper_: function() {
- $('managed-user-list').hidden = true;
- $('select-avatar-grid').hidden = false;
+ this.showAppropriateElements_(/* isSelectAvatarMode */ true);
$('select-avatar-grid').redraw();
$('select-avatar-grid').selectedItem =
loadTimeData.getValue('avatarIcons')[0];
-
- $('managed-user-import-ok').textContent =
- loadTimeData.getString('managedUserSelectAvatarOk');
- $('managed-user-import-text').textContent =
- loadTimeData.getString('managedUserSelectAvatarText');
- $('managed-user-import-title').textContent =
- loadTimeData.getString('managedUserSelectAvatarTitle');
},
/**
@@ -149,16 +166,16 @@ cr.define('options', function() {
* @private
*/
updateImportInProgress_: function(inProgress) {
+ this.inProgress_ = inProgress;
$('managed-user-import-ok').disabled = inProgress;
+ $('managed-user-select-avatar-ok').disabled = inProgress;
$('managed-user-list').disabled = inProgress;
$('select-avatar-grid').disabled = inProgress;
- $('create-new-user-link').disabled = inProgress;
$('managed-user-import-throbber').hidden = !inProgress;
},
/**
- * Adds all the existing |managedUsers| to the list. If |managedUsers|
- * is undefined, then the list is cleared.
+ * Sets the data model of the managed user list to |managedUsers|.
* @param {Array.<Object>} managedUsers An array of managed user objects.
* Each object is of the form:
* managedUser = {
@@ -171,12 +188,9 @@ cr.define('options', function() {
* @private
*/
receiveExistingManagedUsers_: function(managedUsers) {
- if (!managedUsers) {
- $('managed-user-list').dataModel = null;
- return;
- }
-
managedUsers.sort(function(a, b) {
+ if (a.onCurrentDevice != b.onCurrentDevice)
+ return a.onCurrentDevice ? 1 : -1;
return a.name.localeCompare(b.name);
});
@@ -184,14 +198,15 @@ cr.define('options', function() {
if (managedUsers.length == 0) {
this.onError_(loadTimeData.getString('noExistingManagedUsers'));
$('managed-user-import-ok').disabled = true;
+ } else {
+ // Hide the error bubble.
+ $('managed-user-import-error-bubble').hidden = true;
}
},
- /**
- * @private
- */
- hideErrorBubble_: function() {
- $('managed-user-import-error-bubble').hidden = true;
+ onSigninError_: function() {
+ $('managed-user-list').dataModel = null;
+ this.onError_(loadTimeData.getString('managedUserImportSigninError'));
},
/**
@@ -209,21 +224,21 @@ cr.define('options', function() {
},
/**
- * Closes the overlay if importing the managed user was successful.
+ * Closes the overlay if importing the managed user was successful. Also
+ * reset the cached list of managed users in order to get an updated list
+ * when the overlay is reopened.
* @private
*/
onSuccess_: function() {
this.updateImportInProgress_(false);
- OptionsPage.closeOverlay();
+ options.ManagedUserListData.resetPromise();
+ OptionsPage.closeAllOverlays();
},
};
// Forward public APIs to private implementations.
[
- 'hideErrorBubble',
- 'onError',
'onSuccess',
- 'receiveExistingManagedUsers',
].forEach(function(name) {
ManagedUserImportOverlay[name] = function() {
var instance = ManagedUserImportOverlay.getInstance();
diff --git a/chromium/chrome/browser/resources/options/managed_user_list.js b/chromium/chrome/browser/resources/options/managed_user_list.js
index 4af84c64c14..2d4ec61d2e9 100644
--- a/chromium/chrome/browser/resources/options/managed_user_list.js
+++ b/chromium/chrome/browser/resources/options/managed_user_list.js
@@ -62,8 +62,7 @@ cr.define('options.managedUserOptions', function() {
// Add the avatar.
var iconElement = this.ownerDocument.createElement('img');
iconElement.className = 'profile-img';
- iconElement.style.content =
- imageset(managedUser.iconURL + '@scalefactorx');
+ iconElement.style.content = getProfileAvatarIcon(managedUser.iconURL);
this.appendChild(iconElement);
// Add the profile name.
diff --git a/chromium/chrome/browser/resources/options/managed_user_list_data.js b/chromium/chrome/browser/resources/options/managed_user_list_data.js
new file mode 100644
index 00000000000..91619ede6a8
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/managed_user_list_data.js
@@ -0,0 +1,152 @@
+// Copyright 2014 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() {
+ /**
+ * ManagedUserListData class.
+ * Handles requests for retrieving a list of existing managed users which are
+ * supervised by the current profile. For each request a promise is returned,
+ * which is cached in order to reuse the retrieved managed users for future
+ * requests. The first request will be handled asynchronously.
+ * @constructor
+ * @class
+ */
+ function ManagedUserListData() {
+ this.observers_ = [];
+ };
+
+ cr.addSingletonGetter(ManagedUserListData);
+
+ /**
+ * Receives a list of managed users and resolves the promise.
+ * @param {Array.<Object>} managedUsers An array of managed user objects.
+ * Each object is of the form:
+ * managedUser = {
+ * id: "Managed User ID",
+ * name: "Managed User Name",
+ * iconURL: "chrome://path/to/icon/image",
+ * onCurrentDevice: true or false,
+ * needAvatar: true or false
+ * }
+ * @private
+ */
+ ManagedUserListData.prototype.receiveExistingManagedUsers_ = function(
+ managedUsers) {
+ if (!this.promise_) {
+ this.onDataChanged_(managedUsers);
+ return;
+ }
+ this.resolve_(managedUsers);
+ };
+
+ /**
+ * Called when there is a signin error when retrieving the list of managed
+ * users. Rejects the promise and resets the cached promise to null.
+ * @private
+ */
+ ManagedUserListData.prototype.onSigninError_ = function() {
+ assert(this.promise_);
+ this.reject_();
+ this.resetPromise_();
+ };
+
+ /**
+ * Handles the request for the list of existing managed users by returning a
+ * promise for the requested data. If there is no cached promise yet, a new
+ * one will be created.
+ * @return {Promise} The promise containing the list of managed users.
+ * @private
+ */
+ ManagedUserListData.prototype.requestExistingManagedUsers_ = function() {
+ if (this.promise_)
+ return this.promise_;
+ this.promise_ = this.createPromise_();
+ chrome.send('requestManagedUserImportUpdate');
+ return this.promise_;
+ };
+
+ /**
+ * Creates the promise containing the list of managed users. The promise is
+ * resolved in receiveExistingManagedUsers_() or rejected in
+ * onSigninError_(). The promise is cached, so that for future requests it can
+ * be resolved immediately.
+ * @return {Promise} The promise containing the list of managed users.
+ * @private
+ */
+ ManagedUserListData.prototype.createPromise_ = function() {
+ var self = this;
+ return new Promise(function(resolve, reject) {
+ self.resolve_ = resolve;
+ self.reject_ = reject;
+ });
+ };
+
+ /**
+ * Resets the promise to null in order to avoid stale data. For the next
+ * request, a new promise will be created.
+ * @private
+ */
+ ManagedUserListData.prototype.resetPromise_ = function() {
+ this.promise_ = null;
+ };
+
+ /**
+ * Initializes |promise| with the new data and also passes the new data to
+ * observers.
+ * @param {Array.<Object>} managedUsers An array of managed user objects.
+ * For the format of the objects, see receiveExistingManagedUsers_().
+ * @private
+ */
+ ManagedUserListData.prototype.onDataChanged_ = function(managedUsers) {
+ this.promise_ = this.createPromise_();
+ this.resolve_(managedUsers);
+ for (var i = 0; i < this.observers_.length; ++i)
+ this.observers_[i].receiveExistingManagedUsers_(managedUsers);
+ };
+
+ /**
+ * Adds an observer to the list of observers.
+ * @param {Object} observer The observer to be added.
+ * @private
+ */
+ ManagedUserListData.prototype.addObserver_ = function(observer) {
+ for (var i = 0; i < this.observers_.length; ++i)
+ assert(this.observers_[i] != observer);
+ this.observers_.push(observer);
+ };
+
+ /**
+ * Removes an observer from the list of observers.
+ * @param {Object} observer The observer to be removed.
+ * @private
+ */
+ ManagedUserListData.prototype.removeObserver_ = function(observer) {
+ for (var i = 0; i < this.observers_.length; ++i) {
+ if (this.observers_[i] == observer) {
+ this.observers_.splice(i, 1);
+ return;
+ }
+ }
+ };
+
+ // Forward public APIs to private implementations.
+ [
+ 'addObserver',
+ 'onSigninError',
+ 'receiveExistingManagedUsers',
+ 'removeObserver',
+ 'requestExistingManagedUsers',
+ 'resetPromise',
+ ].forEach(function(name) {
+ ManagedUserListData[name] = function() {
+ var instance = ManagedUserListData.getInstance();
+ return instance[name + '_'].apply(instance, arguments);
+ };
+ });
+
+ // Export
+ return {
+ ManagedUserListData: ManagedUserListData,
+ };
+});
diff --git a/chromium/chrome/browser/resources/options/media_galleries_list.js b/chromium/chrome/browser/resources/options/media_galleries_list.js
deleted file mode 100644
index 8d892bcdd00..00000000000
--- a/chromium/chrome/browser/resources/options/media_galleries_list.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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() {
- /** @const */ var DeletableItem = options.DeletableItem;
- /** @const */ var DeletableItemList = options.DeletableItemList;
-
- /**
- * @constructor
- * @extends {DeletableItem}
- */
- function MediaGalleriesListItem(galleryInfo) {
- var el = cr.doc.createElement('div');
- el.galleryInfo_ = galleryInfo;
- el.__proto__ = MediaGalleriesListItem.prototype;
- el.decorate();
- return el;
- }
-
- MediaGalleriesListItem.prototype = {
- __proto__: DeletableItem.prototype,
-
- decorate: function() {
- DeletableItem.prototype.decorate.call(this);
-
- var span = this.ownerDocument.createElement('span');
- span.textContent = this.galleryInfo_.displayName;
- this.contentElement.appendChild(span);
- this.contentElement.title = this.galleryInfo_.path;
- },
- };
-
- var MediaGalleriesList = cr.ui.define('list');
-
- MediaGalleriesList.prototype = {
- __proto__: DeletableItemList.prototype,
-
- /** @override */
- decorate: function() {
- DeletableItemList.prototype.decorate.call(this);
- this.autoExpands_ = true;
- },
-
- /** @override */
- createItem: function(galleryInfo) {
- return new MediaGalleriesListItem(galleryInfo);
- },
-
- /** @override */
- deleteItemAtIndex: function(index) {
- chrome.send('forgetGallery', [this.dataModel.item(index).id]);
- },
- };
-
- return {
- MediaGalleriesList: MediaGalleriesList
- };
-});
diff --git a/chromium/chrome/browser/resources/options/media_galleries_manager_overlay.html b/chromium/chrome/browser/resources/options/media_galleries_manager_overlay.html
deleted file mode 100644
index 05c4db1c6af..00000000000
--- a/chromium/chrome/browser/resources/options/media_galleries_manager_overlay.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<div id="manage-media-galleries-overlay" class="page" hidden>
- <div class="close-button"></div>
- <h1 i18n-content="manageMediaGalleries"></h1>
- <div class="content-area">
- <list id="available-galleries-list"></list>
- </div>
- <div class="action-area">
- <div class="stretch">
- <button id="new-media-gallery" i18n-content="addNewGalleryButton"
- disabled></button>
- </div>
- </stretch>
- <div class="button-strip">
- <button id="manage-media-confirm" class="default-button"
- i18n-content="done">
- </button>
- </div>
- </div>
-</div>
diff --git a/chromium/chrome/browser/resources/options/media_galleries_manager_overlay.js b/chromium/chrome/browser/resources/options/media_galleries_manager_overlay.js
deleted file mode 100644
index ac8e5271580..00000000000
--- a/chromium/chrome/browser/resources/options/media_galleries_manager_overlay.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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() {
- /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
- /** @const */ var OptionsPage = options.OptionsPage;
-
- /**
- * This class is an overlay which allows the user to add or remove media
- * galleries, and displays known media galleries.
- * @constructor
- * @extends {OptionsPage}
- */
- function MediaGalleriesManager() {
- OptionsPage.call(this, 'manageGalleries',
- loadTimeData.getString('manageMediaGalleriesTabTitle'),
- 'manage-media-galleries-overlay');
- }
-
- cr.addSingletonGetter(MediaGalleriesManager);
-
- MediaGalleriesManager.prototype = {
- __proto__: OptionsPage.prototype,
-
- /**
- * Decorate the overlay and set up event handlers.
- */
- initializePage: function() {
- OptionsPage.prototype.initializePage.call(this);
-
- this.availableGalleriesList_ = $('available-galleries-list');
- options.MediaGalleriesList.decorate(this.availableGalleriesList_);
-
- $('new-media-gallery').addEventListener('click', function() {
- chrome.send('addNewGallery');
- });
-
- $('manage-media-confirm').addEventListener(
- 'click', OptionsPage.closeOverlay.bind(OptionsPage));
-
- this.addEventListener('visibleChange', this.handleVisibleChange_);
- },
-
- /** @private */
- handleVisibleChange_: function() {
- if (!this.visible)
- return;
-
- chrome.send('initializeMediaGalleries');
-
- if (this.availableGalleriesList_)
- this.availableGalleriesList_.redraw();
- },
-
- /**
- * @param {Array} galleries List of structs describibing galleries.
- * @private
- */
- setAvailableMediaGalleries_: function(galleries) {
- $('available-galleries-list').dataModel = new ArrayDataModel(galleries);
- $('new-media-gallery').disabled = false;
- $('media-galleries-section').hidden = false;
- },
- },
-
- // Forward public APIs to private implementations.
- [
- 'setAvailableMediaGalleries',
- ].forEach(function(name) {
- MediaGalleriesManager[name] = function() {
- var instance = MediaGalleriesManager.getInstance();
- return instance[name + '_'].apply(instance, arguments);
- };
- });
-
- // Export
- return {
- MediaGalleriesManager: MediaGalleriesManager
- };
-});
diff --git a/chromium/chrome/browser/resources/options/options.html b/chromium/chrome/browser/resources/options/options.html
index 0d1f0cbb896..f6fcfd48aa3 100644
--- a/chromium/chrome/browser/resources/options/options.html
+++ b/chromium/chrome/browser/resources/options/options.html
@@ -17,7 +17,7 @@
<link rel="stylesheet" href="autofill_edit_overlay.css">
<link rel="stylesheet" href="autofill_options.css">
<link rel="stylesheet" href="browser_options.css">
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<link rel="stylesheet" href="chromeos/browser_options.css">
</if>
<link rel="stylesheet" href="clear_browser_data_overlay.css">
@@ -28,6 +28,8 @@
<link rel="stylesheet" href="font_settings.css">
<link rel="stylesheet" href="handler_options.css">
<link rel="stylesheet" href="home_page_overlay.css">
+<link rel="stylesheet" href="hotword_confirm_overlay.css">
+<link rel="stylesheet" href="hotword_search_setting_indicator.css">
<link rel="stylesheet" href="import_data_overlay.css">
<if expr="not is_macosx">
<link rel="stylesheet" href="language_dictionary_overlay.css">
@@ -39,15 +41,16 @@
<link rel="stylesheet" href="managed_user_learn_more.css">
<link rel="stylesheet" href="password_manager.css">
<link rel="stylesheet" href="password_manager_list.css">
-<link rel="stylesheet" href="reset_profile_settings_banner.css">
<link rel="stylesheet" href="reset_profile_settings_overlay.css">
<link rel="stylesheet" href="search_engine_manager.css">
<link rel="stylesheet" href="search_page.css">
+<link rel="stylesheet" href="settings_banner.css">
<link rel="stylesheet" href="spelling_confirm_overlay.css">
<link rel="stylesheet" href="subpages_tab_controls.css">
<link rel="stylesheet" href="startup_overlay.css">
<link rel="stylesheet" href="../sync_setup_overlay.css">
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
+<link rel="stylesheet" href="chromeos/third_party_ime_confirm_overlay.css">
<link rel="stylesheet" href="chromeos/accounts_options_page.css">
<link rel="stylesheet" href="chromeos/bluetooth.css">
<link rel="stylesheet" href="chromeos/change_picture_options.css">
@@ -58,11 +61,11 @@
<link rel="stylesheet" href="chromeos/pointer_overlay.css">
<link rel="stylesheet" href="factory_reset_overlay.css">
</if>
-<if expr="pp_ifdef('use_nss')">
+<if expr="use_nss">
<link rel="stylesheet" href="certificate_manager.css">
<link rel="stylesheet" href="certificate_tree.css">
</if>
-<if expr="pp_ifdef('enable_settings_app')">
+<if expr="enable_settings_app">
<link rel="stylesheet" href="options_settings_app.css">
</if>
<script src="chrome://resources/css/tree.css.js"></script>
@@ -91,6 +94,7 @@
<script src="chrome://resources/js/cr/ui/repeating_button.js"></script>
<script src="chrome://resources/js/cr/ui/tree.js"></script>
<script src="chrome://resources/js/load_time_data.js"></script>
+<script src="chrome://resources/js/parse_html_subset.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://settings-frame/strings.js"></script>
@@ -103,22 +107,21 @@
<include src="autofill_options.html">
<include src="clear_browser_data_overlay.html">
<include src="content_settings.html">
- <include src="content_settings2.html">
<include src="do_not_track_confirm_overlay.html">
<include src="font_settings.html">
<include src="home_page_overlay.html">
+ <include src="hotword_confirm_overlay.html">
<include src="import_data_overlay.html">
<include src="language_options.html">
<include src="manage_profile_overlay.html">
<include src="managed_user_create_confirm.html">
- <include src="managed_user_import.html">
<include src="password_manager.html">
<include src="reset_profile_settings_overlay.html">
<include src="search_engine_manager.html">
<include src="spelling_confirm_overlay.html">
<include src="startup_overlay.html">
<include src="../sync_setup_overlay.html">
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<include src="chromeos/accounts_options.html">
<include src="chromeos/bluetooth_add_device_overlay.html">
<include src="chromeos/bluetooth_pair_device_overlay.html">
@@ -128,7 +131,7 @@
<include src="chromeos/pointer_overlay.html">
<include src="factory_reset_overlay.html">
</if>
-<if expr="pp_ifdef('use_nss')">
+<if expr="use_nss">
<include src="certificate_manager.html">
</if>
</div>
@@ -140,15 +143,16 @@
<include src="cookies_view.html">
<include src="handler_options.html">
<include src="language_add_language_overlay.html">
+ <include src="managed_user_import.html">
<include src="managed_user_learn_more.html">
<if expr="not is_macosx">
<include src="language_dictionary_overlay.html">
</if>
- <include src="media_galleries_manager_overlay.html">
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<include src="chromeos/display_overscan.html">
<include src="chromeos/internet_detail.html">
<include src="chromeos/preferred_networks.html">
+ <include src="chromeos/third_party_ime_confirm_overlay.html">
</if>
<if expr="not is_win and not is_macosx">
<include src="certificate_restore_overlay.html">
@@ -164,13 +168,19 @@
<div class="controlled-setting-bubble-extension-name"></div>
</div>
<div class="controlled-setting-bubble-content-row">
- <div class="controlled-setting-bubble-extension-manage-link link-button"
- i18n-content="controlledSettingManageExtensions"></div>
+ <button class="controlled-setting-bubble-extension-manage-link link-button"
+ i18n-content="controlledSettingManageExtension"></button>
<button class='controlled-setting-bubble-extension-disable-button'
i18n-content="controlledSettingDisableExtension"></button>
</div>
</div>
+<div id="extension-controlled-warning-template"
+ class="extension-controlled-warning-box" hidden>
+ <div class="extension-controlled-warning"></div>
+ <button i18n-content="extensionDisable"></button>
+</div>
+
<div id="main-content">
<div id="mainview">
<div id="mainview-content">
diff --git a/chromium/chrome/browser/resources/options/options.js b/chromium/chrome/browser/resources/options/options.js
index 1aeb352c218..dea67ba23ff 100644
--- a/chromium/chrome/browser/resources/options/options.js
+++ b/chromium/chrome/browser/resources/options/options.js
@@ -7,6 +7,7 @@ var AlertOverlay = options.AlertOverlay;
var AutofillEditAddressOverlay = options.AutofillEditAddressOverlay;
var AutofillEditCreditCardOverlay = options.AutofillEditCreditCardOverlay;
var AutofillOptions = options.AutofillOptions;
+var AutomaticSettingsResetBanner = options.AutomaticSettingsResetBanner;
var BrowserOptions = options.BrowserOptions;
var ClearBrowserDataOverlay = options.ClearBrowserDataOverlay;
var ConfirmDialog = options.ConfirmDialog;
@@ -17,7 +18,7 @@ var CookiesView = options.CookiesView;
var CreateProfileOverlay = options.CreateProfileOverlay;
var EditDictionaryOverlay = cr.IsMac ? null : options.EditDictionaryOverlay;
var FactoryResetOverlay = options.FactoryResetOverlay;
-<if expr="pp_ifdef('enable_google_now')">
+<if expr="enable_google_now">
var GeolocationOptions = options.GeolocationOptions;
</if>
var FontSettings = options.FontSettings;
@@ -29,7 +30,6 @@ var ManageProfileOverlay = options.ManageProfileOverlay;
var ManagedUserCreateConfirmOverlay = options.ManagedUserCreateConfirmOverlay;
var ManagedUserImportOverlay = options.ManagedUserImportOverlay;
var ManagedUserLearnMoreOverlay = options.ManagedUserLearnMoreOverlay;
-var MediaGalleriesManager = options.MediaGalleriesManager;
var OptionsFocusManager = options.OptionsFocusManager;
var OptionsPage = options.OptionsPage;
var PasswordManager = options.PasswordManager;
@@ -41,6 +41,7 @@ var SearchEngineManager = options.SearchEngineManager;
var SearchPage = options.SearchPage;
var StartupOverlay = options.StartupOverlay;
var SyncSetupOverlay = options.SyncSetupOverlay;
+var ThirdPartyImeConfirmOverlay = options.ThirdPartyImeConfirmOverlay;
/**
* DOMContentLoaded handler, sets up the page.
@@ -104,6 +105,16 @@ function load() {
$('spelling-enabled-control').metric),
BrowserOptions.getInstance());
}
+ OptionsPage.registerOverlay(
+ new ConfirmDialog(
+ 'hotwordConfirm',
+ loadTimeData.getString('hotwordConfirmOverlayTabTitle'),
+ 'hotword-confirm-overlay',
+ $('hotword-confirm-ok'),
+ $('hotword-confirm-cancel'),
+ $('hotword-search-enable').pref,
+ $('hotword-search-enable').metric),
+ BrowserOptions.getInstance());
OptionsPage.registerOverlay(ContentSettings.getInstance(),
BrowserOptions.getInstance(),
[$('privacyContentSettingsButton')]);
@@ -142,16 +153,11 @@ function load() {
if (!cr.isChromeOS) {
OptionsPage.registerOverlay(ManagedUserCreateConfirmOverlay.getInstance(),
BrowserOptions.getInstance());
- if (loadTimeData.getBoolean('allowCreateExistingManagedUsers')) {
- OptionsPage.registerOverlay(ManagedUserImportOverlay.getInstance(),
- BrowserOptions.getInstance());
- }
+ OptionsPage.registerOverlay(ManagedUserImportOverlay.getInstance(),
+ CreateProfileOverlay.getInstance());
OptionsPage.registerOverlay(ManagedUserLearnMoreOverlay.getInstance(),
CreateProfileOverlay.getInstance());
}
- OptionsPage.registerOverlay(MediaGalleriesManager.getInstance(),
- ContentSettings.getInstance(),
- [$('manage-galleries-button')]);
OptionsPage.registerOverlay(PasswordManager.getInstance(),
BrowserOptions.getInstance(),
[$('manage-passwords')]);
@@ -196,6 +202,8 @@ function load() {
[$('pointer-settings-button')]);
OptionsPage.registerOverlay(PreferredNetworks.getInstance(),
BrowserOptions.getInstance());
+ OptionsPage.registerOverlay(ThirdPartyImeConfirmOverlay.getInstance(),
+ LanguageOptions.getInstance());
}
if (!cr.isWindows && !cr.isMac) {
@@ -216,17 +224,14 @@ function load() {
OptionsFocusManager.getInstance().initialize();
Preferences.getInstance().initialize();
ResetProfileSettingsBanner.getInstance().initialize();
+ AutomaticSettingsResetBanner.getInstance().initialize();
OptionsPage.initialize();
- var path = document.location.pathname;
-
- if (path.length > 1) {
- // Skip starting slash and remove trailing slash (if any).
- var pageName = path.slice(1).replace(/\/$/, '');
- OptionsPage.showPageByName(pageName, true, {replaceState: true});
- } else {
- OptionsPage.showDefaultPage();
- }
+ var pageName = OptionsPage.getPageNameFromPath();
+ // Still update history so that chrome://settings/nonexistant redirects
+ // appropriately to chrome://settings/. If the URL matches, updateHistory_
+ // will avoid the extra replaceState.
+ OptionsPage.showPageByName(pageName, true, {replaceState: true});
var subpagesNavTabs = document.querySelectorAll('.subpages-nav-tabs');
for (var i = 0; i < subpagesNavTabs.length; i++) {
@@ -237,6 +242,7 @@ function load() {
window.setTimeout(function() {
document.documentElement.classList.remove('loading');
+ chrome.send('onFinishedLoadingOptions');
});
}
@@ -255,5 +261,6 @@ window.onbeforeunload = function() {
* @param {Event} e The |popstate| event.
*/
window.onpopstate = function(e) {
- options.OptionsPage.setState(e.state);
+ var pageName = options.OptionsPage.getPageNameFromPath();
+ options.OptionsPage.setState(pageName, e.state);
};
diff --git a/chromium/chrome/browser/resources/options/options_bundle.js b/chromium/chrome/browser/resources/options/options_bundle.js
index 8f450648e5a..24c1c6c31a7 100644
--- a/chromium/chrome/browser/resources/options/options_bundle.js
+++ b/chromium/chrome/browser/resources/options/options_bundle.js
@@ -9,11 +9,13 @@
<include src="controlled_setting.js"></include>
<include src="deletable_item_list.js"></include>
<include src="editable_text_field.js"></include>
+<include src="hotword_search_setting_indicator.js"></include>
<include src="inline_editable_list.js"></include>
<include src="options_page.js"></include>
<include src="pref_ui.js"></include>
<include src="settings_dialog.js"></include>
-<if expr="pp_ifdef('chromeos')">
+<include src="settings_banner.js"></include>
+<if expr="chromeos">
<include src="../chromeos/user_images_grid.js"></include>
// DO NOT BREAK THE FOLLOWING INCLUDE LINE INTO SEPARATE LINES!
// Even though the include line spans more than 80 characters,
@@ -36,6 +38,7 @@
<include src="chromeos/display_overscan.js"></include>
<include src="chromeos/keyboard_overlay.js"></include>
<include src="chromeos/pointer_overlay.js"></include>
+<include src="chromeos/third_party_ime_confirm_overlay.js"></include>
var AccountsOptions = options.AccountsOptions;
var ChangePictureOptions = options.ChangePictureOptions;
var DetailsInternetPage = options.internet.DetailsInternetPage;
@@ -47,7 +50,7 @@ var KeyboardOverlay = options.KeyboardOverlay;
var PointerOverlay = options.PointerOverlay;
var UIAccountTweaks = uiAccountTweaks.UIAccountTweaks;
</if>
-<if expr="pp_ifdef('use_nss')">
+<if expr="use_nss">
<include src="certificate_tree.js"></include>
<include src="certificate_manager.js"></include>
<include src="certificate_restore_overlay.js"></include>
@@ -65,20 +68,20 @@ var CertificateImportErrorOverlay = options.CertificateImportErrorOverlay;
<include src="autofill_edit_creditcard_overlay.js"></include>
<include src="autofill_options_list.js"></include>
<include src="autofill_options.js"></include>
+<include src="automatic_settings_reset_banner.js"></include>
<include src="browser_options.js"></include>
<include src="browser_options_profile_list.js"></include>
<include src="browser_options_startup_page_list.js"></include>
<include src="clear_browser_data_overlay.js"></include>
<include src="confirm_dialog.js"></include>
<include src="content_settings.js"></include>
-<include src="content_settings2.js"></include>
<include src="content_settings_exceptions_area.js"></include>
<include src="content_settings_ui.js"></include>
<include src="cookies_list.js"></include>
<include src="cookies_view.js"></include>
<include src="factory_reset_overlay.js"></include>
<include src="font_settings.js"></include>
-<if expr="pp_ifdef('enable_google_now')">
+<if expr="enable_google_now">
<include src="geolocation_options.js"></include>
</if>
<include src="handler_options.js"></include>
@@ -97,8 +100,7 @@ var CertificateImportErrorOverlay = options.CertificateImportErrorOverlay;
<include src="managed_user_import.js"></include>
<include src="managed_user_learn_more.js"</include>
<include src="managed_user_list.js"></include>
-<include src="media_galleries_list.js"></include>
-<include src="media_galleries_manager_overlay.js"></include>
+<include src="managed_user_list_data.js"></include>
<include src="options_focus_manager.js"></include>
<include src="password_manager.js"></include>
<include src="password_manager_list.js"></include>
@@ -112,6 +114,6 @@ var CertificateImportErrorOverlay = options.CertificateImportErrorOverlay;
<include src="../sync_setup_overlay.js"></include>
<include src="../uber/uber_utils.js"></include>
<include src="options.js"></include>
-<if expr="pp_ifdef('enable_settings_app')">
+<if expr="enable_settings_app">
<include src="options_settings_app.js"></include>
</if>
diff --git a/chromium/chrome/browser/resources/options/options_page.css b/chromium/chrome/browser/resources/options/options_page.css
index b4223ec7e32..f8efff87805 100644
--- a/chromium/chrome/browser/resources/options/options_page.css
+++ b/chromium/chrome/browser/resources/options/options_page.css
@@ -213,38 +213,38 @@ list:not([disabled]) > :hover {
* these rules can be simplified (since they wont need to override other rules).
*/
-list:not([hasElementFocus]) > [selected],
-list:not([hasElementFocus]) > [lead][selected] {
+list:not([has-element-focus]) > [selected],
+list:not([has-element-focus]) > [lead][selected] {
background-color: #d0d0d0;
background-image: none;
}
-list[hasElementFocus] > [selected],
-list[hasElementFocus] > [lead][selected],
-list:not([hasElementFocus]) > [selected]:hover,
-list:not([hasElementFocus]) > [selected][lead]:hover {
+list[has-element-focus] > [selected],
+list[has-element-focus] > [lead][selected],
+list:not([has-element-focus]) > [selected]:hover,
+list:not([has-element-focus]) > [selected][lead]:hover {
background-color: rgb(187, 206, 233);
background-image: none;
}
-list[hasElementFocus] > [lead],
-list[hasElementFocus] > [lead][selected] {
+.settings-list[has-element-focus] > [lead],
+.settings-list[has-element-focus] > [lead][selected] {
border-bottom: 1px solid rgb(120, 146, 180);
border-top: 1px solid rgb(120, 146, 180);
}
-list[hasElementFocus] > [lead]:nth-child(2),
-list[hasElementFocus] > [lead][selected]:nth-child(2) {
+.settings-list[has-element-focus] > [lead]:nth-child(2),
+.settings-list[has-element-focus] > [lead][selected]:nth-child(2) {
border-top: 1px solid transparent;
}
-list[hasElementFocus] > [lead]:nth-last-child(2),
-list[hasElementFocus] > [lead][selected]:nth-last-child(2) {
+.settings-list[has-element-focus] > [lead]:nth-last-child(2),
+.settings-list[has-element-focus] > [lead][selected]:nth-last-child(2) {
border-bottom: 1px solid transparent;
}
-list[disabled] > [lead][selected],
-list[disabled]:focus > [lead][selected] {
+.settings-list[disabled] > [lead][selected],
+.settings-list[disabled]:focus > [lead][selected] {
border: none;
}
@@ -287,7 +287,8 @@ list .row-delete-button {
}
list > *:not(:hover):not([selected]):not([lead]) .row-delete-button,
-list:not([hasElementFocus]) > *:not(:hover):not([selected]) .row-delete-button,
+list:not([has-element-focus]) > *:not(:hover):not([selected])
+ .row-delete-button,
list[disabled] .row-delete-button,
list .row-delete-button[disabled] {
opacity: 0;
@@ -334,10 +335,9 @@ list > :not([editing]) [displaymode='edit'] {
list > [editing] [displaymode='static'] {
/* Don't use display:none because we need to keep an element focusable. */
left: 0;
- opacity: 0;
pointer-events: none;
position: absolute;
- top: -10em;
+ visibility: hidden;
}
list > [editing] input:invalid {
@@ -404,7 +404,7 @@ html[enable-background-mode=false] #background-mode-section {
/* UI Controls */
/* LIST */
-list[hasElementFocus] {
+.settings-list[has-element-focus] {
<if expr="not is_macosx">
outline: 1px solid rgba(0, 128, 256, 0.5);
outline-offset: -2px;
@@ -436,8 +436,8 @@ list.autocomplete-suggestions > div {
height: auto;
}
-list.autocomplete-suggestions:not([hasElementFocus]) > [selected],
-list.autocomplete-suggestions:not([hasElementFocus]) > [lead][selected] {
+list.autocomplete-suggestions:not([has-element-focus]) > [selected],
+list.autocomplete-suggestions:not([has-element-focus]) > [lead][selected] {
background-color: rgb(187, 206, 233);
}
diff --git a/chromium/chrome/browser/resources/options/options_page.js b/chromium/chrome/browser/resources/options/options_page.js
index befb7c81398..968bb4794a0 100644
--- a/chromium/chrome/browser/resources/options/options_page.js
+++ b/chromium/chrome/browser/resources/options/options_page.js
@@ -58,6 +58,11 @@ cr.define('options', function() {
OptionsPage.registeredOverlayPages = {};
/**
+ * True if options page is served from a dialog.
+ */
+ OptionsPage.isDialog = false;
+
+ /**
* Gets the default page (to be shown on initial load).
*/
OptionsPage.getDefaultPage = function() {
@@ -115,6 +120,7 @@ cr.define('options', function() {
if (!targetPage && this.showOverlay_(pageName, rootPage)) {
if (updateHistory)
this.updateHistoryState_(!!opt_propertyBag.replaceState);
+ this.updateTitle_();
return;
} else {
targetPage = this.getDefaultPage();
@@ -161,9 +167,6 @@ cr.define('options', function() {
if (updateHistory)
this.updateHistoryState_(!!opt_propertyBag.replaceState);
- // Update tab title.
- this.setTitle_(targetPage.title);
-
// Update focus if any other control was focused on the previous page,
// or the previous page is not known.
if (document.activeElement != document.body &&
@@ -183,16 +186,10 @@ cr.define('options', function() {
page.didShowPage();
}
}
- };
- /**
- * Sets the title of the page. This is accomplished by calling into the
- * parent page API.
- * @param {string} title The title string.
- * @private
- */
- OptionsPage.setTitle_ = function(title) {
- uber.invokeMethodOnParent('setTitle', {title: title});
+ // Update the document title. Do this after didShowPage was called, in case
+ // a page decides to change its title.
+ this.updateTitle_();
};
/**
@@ -208,42 +205,40 @@ cr.define('options', function() {
};
/**
- * Pushes the current page onto the history stack, overriding the last page
- * if it is the generic chrome://settings/.
+ * Updates the title to title of the current page.
+ * @private
+ */
+ OptionsPage.updateTitle_ = function() {
+ var page = this.getTopmostVisiblePage();
+ uber.setTitle(page.title);
+ };
+
+ /**
+ * Pushes the current page onto the history stack, replacing the current entry
+ * if appropriate.
* @param {boolean} replace If true, allow no history events to be created.
* @param {object=} opt_params A bag of optional params, including:
* {boolean} ignoreHash Whether to include the hash or not.
* @private
*/
OptionsPage.updateHistoryState_ = function(replace, opt_params) {
+ if (OptionsPage.isDialog)
+ return;
+
var page = this.getTopmostVisiblePage();
var path = window.location.pathname + window.location.hash;
if (path)
path = path.slice(1).replace(/\/(?:#|$)/, ''); // Remove trailing slash.
- // Update tab title.
- this.setTitle_(page.title);
-
- // The page is already in history (the user may have clicked the same link
- // twice). Do nothing.
- if (path == page.name && !OptionsPage.isLoading())
- return;
-
+ // If the page is already in history (the user may have clicked the same
+ // link twice, or this is the initial load), do nothing.
var hash = opt_params && opt_params.ignoreHash ? '' : window.location.hash;
+ var newPath = (page == this.getDefaultPage() ? '' : page.name) + hash;
+ if (path == newPath)
+ return;
- // If settings are embedded, tell the outer page to set its "path" to the
- // inner frame's path.
- var outerPath = (page == this.getDefaultPage() ? '' : page.name) + hash;
- uber.invokeMethodOnParent('setPath', {path: outerPath});
-
- // If there is no path, the current location is chrome://settings/.
- // Override this with the new page.
- var historyFunction = path && !replace ? window.history.pushState :
- window.history.replaceState;
- historyFunction.call(window.history,
- {pageName: page.name},
- page.title,
- '/' + page.name + hash);
+ var historyFunction = replace ? uber.replaceState : uber.pushState;
+ historyFunction.call(uber, {}, newPath);
};
/**
@@ -273,9 +268,6 @@ cr.define('options', function() {
if (overlay.didShowPage) overlay.didShowPage();
}
- // Update tab title.
- this.setTitle_(overlay.title);
-
// Change focus to the overlay if any other control was focused by keyboard
// before. Otherwise, no one should have focus.
if (document.activeElement != document.body) {
@@ -286,7 +278,7 @@ cr.define('options', function() {
}
}
- if ($('search-field').value == '') {
+ if ($('search-field') && $('search-field').value == '') {
var section = overlay.associatedSection;
if (section)
options.BrowserOptions.scrollToSection(section);
@@ -342,11 +334,21 @@ cr.define('options', function() {
if (overlay.didClosePage) overlay.didClosePage();
this.updateHistoryState_(false, {ignoreHash: true});
+ this.updateTitle_();
this.restoreLastFocusedElement_();
};
/**
+ * Closes all overlays and updates the history after each closed overlay.
+ */
+ OptionsPage.closeAllOverlays = function() {
+ while (this.isOverlayVisible_()) {
+ this.closeOverlay();
+ }
+ };
+
+ /**
* Cancels (closes) the overlay, due to the user pressing <Esc>.
*/
OptionsPage.cancelOverlay = function() {
@@ -534,9 +536,9 @@ cr.define('options', function() {
}
}
- // Reverse the button strip for views. See the documentation of
+ // Reverse the button strip for Windows and CrOS. See the documentation of
// reverseButtonStripIfNecessary_() for an explanation of why this is done.
- if (cr.isViews)
+ if (cr.isWindows || cr.isChromeOS)
this.reverseButtonStripIfNecessary_(overlay);
overlay.tab = undefined;
@@ -570,22 +572,33 @@ cr.define('options', function() {
};
/**
+ * Returns the name of the page from the current path.
+ */
+ OptionsPage.getPageNameFromPath = function() {
+ var path = location.pathname;
+ if (path.length <= 1)
+ return this.getDefaultPage().name;
+
+ // Skip starting slash and remove trailing slash (if any).
+ return path.slice(1).replace(/\/$/, '');
+ };
+
+ /**
* Callback for window.onpopstate to handle back/forward navigations.
+ * @param {string} pageName The current page name.
* @param {Object} data State data pushed into history.
*/
- OptionsPage.setState = function(data) {
- if (data && data.pageName) {
- var currentOverlay = this.getVisibleOverlay_();
- var lowercaseName = data.pageName.toLowerCase();
- var newPage = this.registeredPages[lowercaseName] ||
- this.registeredOverlayPages[lowercaseName] ||
- this.getDefaultPage();
- if (currentOverlay && !currentOverlay.isAncestorOfPage(newPage)) {
- currentOverlay.visible = false;
- if (currentOverlay.didClosePage) currentOverlay.didClosePage();
- }
- this.showPageByName(data.pageName, false);
+ OptionsPage.setState = function(pageName, data) {
+ var currentOverlay = this.getVisibleOverlay_();
+ var lowercaseName = pageName.toLowerCase();
+ var newPage = this.registeredPages[lowercaseName] ||
+ this.registeredOverlayPages[lowercaseName] ||
+ this.getDefaultPage();
+ if (currentOverlay && !currentOverlay.isAncestorOfPage(newPage)) {
+ currentOverlay.visible = false;
+ if (currentOverlay.didClosePage) currentOverlay.didClosePage();
}
+ this.showPageByName(pageName, false);
};
/**
@@ -887,11 +900,16 @@ cr.define('options', function() {
// TODO(flackr): Use an event delegate to avoid having to subscribe and
// unsubscribe for webkitTransitionEnd events.
container.addEventListener('webkitTransitionEnd', function f(e) {
- if (e.target != e.currentTarget || e.propertyName != 'opacity')
+ var propName = e.propertyName;
+ if (e.target != e.currentTarget ||
+ (propName && propName != 'opacity')) {
return;
+ }
container.removeEventListener('webkitTransitionEnd', f);
self.fadeCompleted_();
});
+ // -webkit-transition is 200ms. Let's wait for 400ms.
+ ensureTransitionEndEvent(container, 400);
}
if (visible) {
diff --git a/chromium/chrome/browser/resources/options/options_settings_app.js b/chromium/chrome/browser/resources/options/options_settings_app.js
index 02ab5569aaa..c556340d8e6 100644
--- a/chromium/chrome/browser/resources/options/options_settings_app.js
+++ b/chromium/chrome/browser/resources/options/options_settings_app.js
@@ -22,7 +22,6 @@
'downloads-section',
'handlers-section',
'languages-section',
- 'media-galleries-section',
'network-section',
'notifications-section',
'sync-section'
diff --git a/chromium/chrome/browser/resources/options/password_manager_list.js b/chromium/chrome/browser/resources/options/password_manager_list.js
index 9442dee28a5..2a77ea3281a 100644
--- a/chromium/chrome/browser/resources/options/password_manager_list.js
+++ b/chromium/chrome/browser/resources/options/password_manager_list.js
@@ -56,6 +56,7 @@ cr.define('options.passwordManager', function() {
var usernameLabel = this.ownerDocument.createElement('div');
usernameLabel.className = 'name';
usernameLabel.textContent = this.username;
+ usernameLabel.title = this.username;
this.contentElement.appendChild(usernameLabel);
// The stored password.
diff --git a/chromium/chrome/browser/resources/options/pref_ui.js b/chromium/chrome/browser/resources/options/pref_ui.js
index 0775306d776..b4f28308bf8 100644
--- a/chromium/chrome/browser/resources/options/pref_ui.js
+++ b/chromium/chrome/browser/resources/options/pref_ui.js
@@ -160,6 +160,11 @@ cr.define('options', function() {
decorate: function() {
PrefInputElement.prototype.decorate.call(this);
this.type = 'checkbox';
+
+ // Consider a checked dialog checkbox as a 'suggestion' which is committed
+ // once the user confirms the dialog.
+ if (this.dialogPref && this.checked)
+ this.updatePrefFromState_();
},
/**
diff --git a/chromium/chrome/browser/resources/options/preferences.js b/chromium/chrome/browser/resources/options/preferences.js
index 6f8cc829417..ef1ed18cf90 100644
--- a/chromium/chrome/browser/resources/options/preferences.js
+++ b/chromium/chrome/browser/resources/options/preferences.js
@@ -214,12 +214,11 @@ cr.define('options', function() {
var event = new Event(name);
// Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
- event.value = {
- value: value,
- recommendedValue: pref.orig.recommendedValue,
- disabled: pref.orig.disabled,
- uncommitted: true,
- };
+ event.value = {value: value, uncommitted: true};
+ if (pref.orig) {
+ event.value.recommendedValue = pref.orig.recommendedValue;
+ event.value.disabled = pref.orig.disabled;
+ }
this.dispatchEvent(event);
},
diff --git a/chromium/chrome/browser/resources/options/profiles_icon_grid.js b/chromium/chrome/browser/resources/options/profiles_icon_grid.js
index a35b23fe436..f8e7b61d13b 100644
--- a/chromium/chrome/browser/resources/options/profiles_icon_grid.js
+++ b/chromium/chrome/browser/resources/options/profiles_icon_grid.js
@@ -37,7 +37,7 @@ cr.define('options', function() {
ListItem.prototype.decorate.call(this);
var imageEl = cr.doc.createElement('img');
imageEl.className = 'profile-icon';
- imageEl.style.content = imageset(this.iconURL_ + '@scalefactorx');
+ imageEl.style.content = getProfileAvatarIcon(this.iconURL_);
this.appendChild(imageEl);
this.className = 'profile-icon-grid-item';
@@ -65,4 +65,3 @@ cr.define('options', function() {
ProfilesIconGrid: ProfilesIconGrid
};
});
-
diff --git a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.html b/chromium/chrome/browser/resources/options/reset_profile_settings_banner.html
index 77b6d592eca..fd95c3c7ec9 100644
--- a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.html
+++ b/chromium/chrome/browser/resources/options/reset_profile_settings_banner.html
@@ -1,4 +1,4 @@
-<div id="reset-profile-settings-banner" hidden>
+<div id="reset-profile-settings-banner" class="settings-banner" hidden>
<div id="reset-profile-settings-banner-close" class="close-button"></div>
<div class="content-area">
<div class="badge"></div>
diff --git a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.js b/chromium/chrome/browser/resources/options/reset_profile_settings_banner.js
index 4517e9151c7..ffa2b07c1c5 100644
--- a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.js
+++ b/chromium/chrome/browser/resources/options/reset_profile_settings_banner.js
@@ -6,6 +6,7 @@
cr.define('options', function() {
/** @const */ var OptionsPage = options.OptionsPage;
+ /** @const */ var SettingsBannerBase = options.SettingsBannerBase;
/**
* ResetProfileSettingsBanner class
@@ -17,28 +18,19 @@ cr.define('options', function() {
cr.addSingletonGetter(ResetProfileSettingsBanner);
ResetProfileSettingsBanner.prototype = {
- /**
- * Whether or not the banner has already been dismissed.
- *
- * This is needed because of the surprising ordering of asynchronous
- * JS<->native calls when the settings page is opened with specifying a
- * given sub-page, e.g. chrome://settings/resetProfileSettings.
- *
- * In such a case, ResetProfileSettingsOverlay's didShowPage(), which calls
- * our dismiss() method, would be called before the native Handlers'
- * InitalizePage() methods have an effect in the JS, which includes calling
- * our show() method. This would mean that the banner would be first
- * dismissed, then shown. We want to prevent this.
- *
- * @type {boolean}
- * @private
- */
- hadBeenDismissed_: false,
+ __proto__: SettingsBannerBase.prototype,
/**
* Initializes the banner's event handlers.
*/
initialize: function() {
+ this.showMetricName_ = 'AutomaticReset_WebUIBanner_BannerShown';
+
+ this.dismissNativeCallbackName_ =
+ 'onDismissedResetProfileSettingsBanner';
+
+ this.setVisibilibyDomElement_ = $('reset-profile-settings-banner');
+
$('reset-profile-settings-banner-close').onclick = function(event) {
chrome.send('metricsHandler:recordAction',
['AutomaticReset_WebUIBanner_ManuallyClosed']);
@@ -50,39 +42,6 @@ cr.define('options', function() {
OptionsPage.navigateToPage('resetProfileSettings');
};
},
-
- /**
- * Called by the native code to show the banner if needed.
- * @private
- */
- show_: function() {
- if (!this.hadBeenDismissed_) {
- chrome.send('metricsHandler:recordAction',
- ['AutomaticReset_WebUIBanner_BannerShown']);
- this.setVisibility_(true);
- }
- },
-
- /**
- * Called when the banner should be closed as a result of something taking
- * place on the WebUI page, i.e. when its close button is pressed, or when
- * the confirmation dialog for the profile settings reset feature is opened.
- * @private
- */
- dismiss_: function() {
- chrome.send('onDismissedResetProfileSettingsBanner');
- this.hadBeenDismissed_ = true;
- this.setVisibility_(false);
- },
-
- /**
- * Sets whether or not the reset profile settings banner shall be visible.
- * @param {boolean} show Whether or not to show the banner.
- * @private
- */
- setVisibility_: function(show) {
- $('reset-profile-settings-banner').hidden = !show;
- }
};
// Forward public APIs to private implementations.
diff --git a/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html b/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html
index e348c818d91..98d5248bf82 100644
--- a/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html
+++ b/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.html
@@ -1,4 +1,4 @@
-<div id="reset-profile-settings-overlay" class="page" hidden>
+<div id="reset-profile-settings-overlay" class="page not-resizable" hidden>
<div class="close-button"></div>
<h1 i18n-content="resetProfileSettingsOverlay"></h1>
<div id="reset-profile-settings-content-area" class="content-area">
@@ -42,4 +42,4 @@
</div>
</div>
</div>
-<script src="chrome://resources/js/jstemplate_compiled.js"></script> \ No newline at end of file
+<script src="chrome://resources/js/jstemplate_compiled.js"></script>
diff --git a/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js b/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js
index ab4d830b714..30a6d44f4b2 100644
--- a/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js
+++ b/chromium/chrome/browser/resources/options/reset_profile_settings_overlay.js
@@ -49,6 +49,11 @@ cr.define('options', function() {
ResetProfileSettingsBanner.dismiss();
chrome.send('onShowResetProfileDialog');
},
+
+ /** @override */
+ didClosePage: function() {
+ chrome.send('onHideResetProfileDialog');
+ },
};
/**
@@ -67,12 +72,7 @@ cr.define('options', function() {
* operation has terminated.
*/
ResetProfileSettingsOverlay.doneResetting = function() {
- // The delay gives the user some feedback that the resetting
- // actually worked. Otherwise the dialog just vanishes instantly in most
- // cases.
- window.setTimeout(function() {
- ResetProfileSettingsOverlay.dismiss();
- }, 200);
+ ResetProfileSettingsOverlay.dismiss();
};
/**
diff --git a/chromium/chrome/browser/resources/options/search_engine_manager.css b/chromium/chrome/browser/resources/options/search_engine_manager.css
index c19734da4e4..68ad445ab7f 100644
--- a/chromium/chrome/browser/resources/options/search_engine_manager.css
+++ b/chromium/chrome/browser/resources/options/search_engine_manager.css
@@ -78,4 +78,12 @@
display: none;
}
+#default-search-engine-list {
+ z-index: 2;
+}
+
+#other-search-engine-list {
+ z-index: 1;
+}
+
/* End temporary Make Default button styling */
diff --git a/chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js b/chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js
index 9bc12b9f8b6..0be060294d4 100644
--- a/chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js
+++ b/chromium/chrome/browser/resources/options/search_engine_manager_engine_list.js
@@ -186,9 +186,8 @@ cr.define('options.search_engines', function() {
// CoreOptionsHandler::CreateValueForPref() does.
var event = new Event(this.contentType);
if (engine.extension) {
- event.value = { controlledBy: 'extension' };
- // TODO(mad): add id, name, and icon once we solved the issue with the
- // search engine manager in http://crbug.com/314507.
+ event.value = { controlledBy: 'extension',
+ extension: engine.extension };
} else {
event.value = { controlledBy: 'policy' };
}
diff --git a/chromium/chrome/browser/resources/options/search_page.js b/chromium/chrome/browser/resources/options/search_page.js
index 234399d7af2..cd72ba5f383 100644
--- a/chromium/chrome/browser/resources/options/search_page.js
+++ b/chromium/chrome/browser/resources/options/search_page.js
@@ -272,8 +272,7 @@ cr.define('options', function() {
// Set the hash on the current page, and the enclosing uber page
var hash = text ? '#' + encodeURIComponent(text) : '';
var path = text ? this.name : '';
- window.location.hash = hash;
- uber.invokeMethodOnParent('setPath', {path: path + hash});
+ uber.pushState({}, path + hash);
// Toggle the search page if necessary.
if (text) {
@@ -505,7 +504,7 @@ cr.define('options', function() {
/**
* Builds a list of sub-pages (and overlay pages) to search. Ignore pages
- * that have no associated controls.
+ * that have no associated controls, or whose controls are hidden.
* @return {Array} An array of pages to search.
* @private
*/
@@ -513,13 +512,19 @@ cr.define('options', function() {
var name, pageInfo, page, pages = [];
for (name in OptionsPage.registeredPages) {
page = OptionsPage.registeredPages[name];
- if (page.parentPage && page.associatedSection)
+ if (page.parentPage &&
+ page.associatedSection &&
+ !page.associatedSection.hidden) {
pages.push(page);
+ }
}
for (name in OptionsPage.registeredOverlayPages) {
page = OptionsPage.registeredOverlayPages[name];
- if (page.associatedSection && page.pageDiv != undefined)
+ if (page.associatedSection &&
+ !page.associatedSection.hidden &&
+ page.pageDiv != undefined) {
pages.push(page);
+ }
}
return pages;
},
diff --git a/chromium/chrome/browser/resources/options/secondary_user_banner.html b/chromium/chrome/browser/resources/options/secondary_user_banner.html
new file mode 100644
index 00000000000..84da4273451
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/secondary_user_banner.html
@@ -0,0 +1,11 @@
+<div id="secondary-user-banner" class="settings-banner" hidden>
+ <div class="content-area">
+ <div class="badge"></div>
+ <div class="text">
+ <p>
+ <span i18n-values=".innerHTML:secondaryUserBannerText">
+ </span>
+ </p>
+ </div>
+ </div>
+</div>
diff --git a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.css b/chromium/chrome/browser/resources/options/settings_banner.css
index 21087f8aebd..44add992f64 100644
--- a/chromium/chrome/browser/resources/options/reset_profile_settings_banner.css
+++ b/chromium/chrome/browser/resources/options/settings_banner.css
@@ -1,8 +1,11 @@
-/* Copyright 2013 The Chromium Authors. All rights reserved.
+/* Copyright 2014 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. */
-#reset-profile-settings-banner {
+/* These styles are used bby both reset_profile_settings_banner.html and
+ * automatic_settings_reset_banner.html. */
+
+.settings-banner {
background-color: #f5f5f5;
border-color: #c8c8c8;
border-radius: 3px;
@@ -10,11 +13,11 @@
border-width: 1px;
margin-bottom: 24px;
margin-top: 20px;
+ max-width: 716px;
position: relative;
- width: 716px;
}
-#reset-profile-settings-banner > .close-button {
+.settings-banner > .close-button {
background-image: url('chrome://theme/IDR_CLOSE_DIALOG');
background-position: center;
background-repeat: no-repeat;
@@ -26,26 +29,26 @@
width: 14px;
}
-html[dir='rtl'] #reset-profile-settings-banner > .close-button {
+html[dir='rtl'] .settings-banner > .close-button {
left: 4px;
right: auto;
}
-#reset-profile-settings-banner > .close-button:hover {
+.settings-banner > .close-button:hover {
background-image: url('chrome://theme/IDR_CLOSE_DIALOG_H');
}
-#reset-profile-settings-banner > .close-button:active {
+.settings-banner > .close-button:active {
background-image: url('chrome://theme/IDR_CLOSE_DIALOG_P');
}
-#reset-profile-settings-banner .content-area {
+.settings-banner .content-area {
-webkit-box-align: center;
display: -webkit-box;
padding: 17px;
}
-#reset-profile-settings-banner .content-area .badge {
+.settings-banner .content-area .badge {
background-image: url(yellow_gear.png);
background-position: center;
background-repeat: no-repeat;
@@ -53,25 +56,30 @@ html[dir='rtl'] #reset-profile-settings-banner > .close-button {
width: 58px;
}
-#reset-profile-settings-banner .content-area .text {
+.settings-banner .content-area .text {
-webkit-box-flex: 1.0;
-webkit-margin-start: 18px;
}
-#reset-profile-settings-banner .content-area .text p {
+.settings-banner .content-area .text p {
-webkit-margin-after: 0;
-webkit-margin-before: 0;
}
-#reset-profile-settings-banner .content-area .button-area {
+.settings-banner .content-area .button-area {
-webkit-margin-start: 54px;
}
-#reset-profile-settings-banner .nowrap {
+.settings-banner .nowrap {
white-space: nowrap;
}
-#reset-profile-settings-banner button {
+.settings-banner button {
margin-bottom: 1px;
margin-right: 0;
}
+
+#secondary-user-banner .content-area .badge {
+ background-color: rgb(210, 210, 212);
+ background-image: url(chrome://theme/IDR_SECONDARY_USER_SETTINGS);
+}
diff --git a/chromium/chrome/browser/resources/options/settings_banner.js b/chromium/chrome/browser/resources/options/settings_banner.js
new file mode 100644
index 00000000000..1b253187e8c
--- /dev/null
+++ b/chromium/chrome/browser/resources/options/settings_banner.js
@@ -0,0 +1,86 @@
+// Copyright 2014 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() {
+
+ /**
+ * Base class for banners that appear at the top of the settings page.
+ */
+ function SettingsBannerBase() {}
+
+ cr.addSingletonGetter(SettingsBannerBase);
+
+ SettingsBannerBase.prototype = {
+ /**
+ * Whether or not the banner has already been dismissed.
+ *
+ * This is needed because of the surprising ordering of asynchronous
+ * JS<->native calls when the settings page is opened with specifying a
+ * given sub-page, e.g. chrome://settings/AutomaticSettingsReset.
+ *
+ * In such a case, AutomaticSettingsResetOverlay's didShowPage(), which
+ * calls our dismiss() method, would be called before the native Handlers'
+ * InitalizePage() methods have an effect in the JS, which includes calling
+ * our show() method. This would mean that the banner would be first
+ * dismissed, then shown. We want to prevent this.
+ *
+ * @type {boolean}
+ * @private
+ */
+ hadBeenDismissed_: false,
+
+ /**
+ * Metric name to send when a show event occurs.
+ */
+ showMetricName_: '',
+
+ /**
+ * Name of the native callback invoked when the banner is dismised.
+ */
+ dismissNativeCallbackName_: '',
+
+ /**
+ * DOM element whose visibility is set when setVisibility_ is called.
+ */
+ setVisibilibyDomElement_: null,
+
+ /**
+ * Called by the native code to show the banner if needed.
+ * @private
+ */
+ show_: function() {
+ if (!this.hadBeenDismissed_) {
+ chrome.send('metricsHandler:recordAction', [this.showMetricName_]);
+ this.setVisibility_(true);
+ }
+ },
+
+ /**
+ * Called when the banner should be closed as a result of something taking
+ * place on the WebUI page, i.e. when its close button is pressed, or when
+ * the confirmation dialog for the profile settings reset feature is opened.
+ * @private
+ */
+ dismiss_: function() {
+ chrome.send(this.dismissNativeCallbackName_);
+ this.hadBeenDismissed_ = true;
+ this.setVisibility_(false);
+ },
+
+ /**
+ * Sets whether or not the reset profile settings banner shall be visible.
+ * @param {boolean} show Whether or not to show the banner.
+ * @private
+ */
+ setVisibility_: function(show) {
+ this.setVisibilibyDomElement_.hidden = !show;
+ },
+
+ };
+
+ // Export
+ return {
+ SettingsBannerBase: SettingsBannerBase
+ };
+});
diff --git a/chromium/chrome/browser/resources/options/startup_section.html b/chromium/chrome/browser/resources/options/startup_section.html
index 2eaea81c0bf..41a34ecb47b 100644
--- a/chromium/chrome/browser/resources/options/startup_section.html
+++ b/chromium/chrome/browser/resources/options/startup_section.html
@@ -1,7 +1,7 @@
<section id="startup-section" guest-visibility="hidden">
<h3 i18n-content="sectionTitleStartup"></h3>
- <div>
- <div class="radio">
+ <div id="startup-section-content">
+ <div class="radio" id="newtab-section-content">
<span class="controlled-setting-with-label">
<input id="startup-newtab" type="radio" name="startup" value="5"
pref="session.restore_on_startup"
diff --git a/chromium/chrome/browser/resources/options/subpages_tab_controls.css b/chromium/chrome/browser/resources/options/subpages_tab_controls.css
index c49c07715fe..c8b6c970b0c 100644
--- a/chromium/chrome/browser/resources/options/subpages_tab_controls.css
+++ b/chromium/chrome/browser/resources/options/subpages_tab_controls.css
@@ -50,14 +50,12 @@ html[dir=rtl] .subpages-nav-tabs .tab-label {
}
.subpages-nav-tabs {
- background-image: -webkit-gradient(
- linear,
- left top,
- left bottom,
- color-stop(0, rgb(255,255,255)),
- color-stop(0.6, rgb(255,255,255)),
- color-stop(0.8, rgb(250, 250, 250)),
- color-stop(1.0, rgb(242,242,242))
+ background-image: linear-gradient(
+ to bottom,
+ rgb(255,255,255),
+ rgb(255,255,255) 60%,
+ rgb(250, 250, 250) 80%,
+ rgb(242,242,242)
);
border-bottom: 1px solid #ddd;
padding: 4px 20px;
diff --git a/chromium/chrome/browser/resources/options/sync_section.html b/chromium/chrome/browser/resources/options/sync_section.html
index fdf89885921..fea00770681 100644
--- a/chromium/chrome/browser/resources/options/sync_section.html
+++ b/chromium/chrome/browser/resources/options/sync_section.html
@@ -1,8 +1,8 @@
-<if expr="not pp_ifdef('chromeos')">
+<if expr="not chromeos">
<section id="sync-section">
<h3 i18n-content="sectionTitleSync"></h3>
</if>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<div id="sync-section">
</if>
@@ -12,7 +12,7 @@
target="_blank"></a>
</div>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<div id="account-picture-wrapper">
<div id="account-picture-control">
<input type="image" id="account-picture" tabindex="0"
@@ -23,17 +23,18 @@
</span>
</div>
<div id="sync-general">
-</if> <!-- pp_ifdef('chromeos') -->
+</if> <!-- chromeos -->
<div id="sync-status" class="settings-row" hidden>
<span id="sync-status-text"></span>
<button id="sync-action-link" class="link-button"></button>
</div>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<div class="checkbox">
<span class="controlled-setting-with-label">
<input id="enable-screen-lock" type="checkbox"
+ metric="Options_ScreenLock"
pref="settings.enable_screen_lock">
<span>
<label for="enable-screen-lock" i18n-content="enableScreenlock">
@@ -45,7 +46,7 @@
</span>
</div>
</div>
-</if> <!-- pp_ifdef('chromeos') -->
+</if> <!-- chromeos -->
<div id="sync-buttons" class="settings-row">
<button id="start-stop-sync" hidden></button>
@@ -55,23 +56,16 @@
<button id="customize-sync" i18n-content="customizeSync"
pref="sync.managed" hidden>
</button>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
<button id="manage-accounts-button"
i18n-content="manageAccountsButtonTitle">
</button>
-</if> <!-- pp_ifdef('chromeos') -->
- <div id="enable-auto-login-checkbox" class="checkbox" hidden>
- <label>
- <input id="enable-auto-login" pref="autologin.enabled"
- metric="Options_Autologin" type="checkbox">
- <span i18n-content="autologinEnabled"></span>
- </label>
- </div>
+</if> <!-- chromeos -->
</div>
-<if expr="not pp_ifdef('chromeos')">
+<if expr="not chromeos">
</section>
</if>
-<if expr="pp_ifdef('chromeos')">
+<if expr="chromeos">
</div>
</if>