| Index: chrome/browser/resources/settings/prefs/prefs.js
|
| diff --git a/chrome/browser/resources/settings/prefs/prefs.js b/chrome/browser/resources/settings/prefs/prefs.js
|
| index 7e96f7930a30da630ed8e39a90774c84e0c59402..537da2e75298d26966fb26ee5aebd4cd579a105d 100644
|
| --- a/chrome/browser/resources/settings/prefs/prefs.js
|
| +++ b/chrome/browser/resources/settings/prefs/prefs.js
|
| @@ -13,302 +13,304 @@
|
| */
|
|
|
| (function() {
|
| - 'use strict';
|
| +'use strict';
|
|
|
| - /**
|
| - * Checks whether two values are recursively equal. Only compares serializable
|
| - * data (primitives, serializable arrays and serializable objects).
|
| - * @param {*} val1 Value to compare.
|
| - * @param {*} val2 Value to compare with val1.
|
| - * @return {boolean} True if the values are recursively equal.
|
| - */
|
| - function deepEqual(val1, val2) {
|
| - if (val1 === val2)
|
| - return true;
|
| -
|
| - if (Array.isArray(val1) || Array.isArray(val2)) {
|
| - if (!Array.isArray(val1) || !Array.isArray(val2))
|
| - return false;
|
| - return arraysEqual(/** @type {!Array} */(val1),
|
| - /** @type {!Array} */(val2));
|
| - }
|
| -
|
| - if (val1 instanceof Object && val2 instanceof Object)
|
| - return objectsEqual(val1, val2);
|
| +/**
|
| + * Checks whether two values are recursively equal. Only compares serializable
|
| + * data (primitives, serializable arrays and serializable objects).
|
| + * @param {*} val1 Value to compare.
|
| + * @param {*} val2 Value to compare with val1.
|
| + * @return {boolean} True if the values are recursively equal.
|
| + */
|
| +function deepEqual(val1, val2) {
|
| + if (val1 === val2)
|
| + return true;
|
|
|
| - return false;
|
| + if (Array.isArray(val1) || Array.isArray(val2)) {
|
| + if (!Array.isArray(val1) || !Array.isArray(val2))
|
| + return false;
|
| + return arraysEqual(
|
| + /** @type {!Array} */ (val1),
|
| + /** @type {!Array} */ (val2));
|
| }
|
|
|
| - /**
|
| - * @param {!Array} arr1
|
| - * @param {!Array} arr2
|
| - * @return {boolean} True if the arrays are recursively equal.
|
| - */
|
| - function arraysEqual(arr1, arr2) {
|
| - if (arr1.length != arr2.length)
|
| - return false;
|
| + if (val1 instanceof Object && val2 instanceof Object)
|
| + return objectsEqual(val1, val2);
|
|
|
| - for (var i = 0; i < arr1.length; i++) {
|
| - if (!deepEqual(arr1[i], arr2[i]))
|
| - return false;
|
| - }
|
| + return false;
|
| +}
|
|
|
| - return true;
|
| - }
|
| +/**
|
| + * @param {!Array} arr1
|
| + * @param {!Array} arr2
|
| + * @return {boolean} True if the arrays are recursively equal.
|
| + */
|
| +function arraysEqual(arr1, arr2) {
|
| + if (arr1.length != arr2.length)
|
| + return false;
|
|
|
| - /**
|
| - * @param {!Object} obj1
|
| - * @param {!Object} obj2
|
| - * @return {boolean} True if the objects are recursively equal.
|
| - */
|
| - function objectsEqual(obj1, obj2) {
|
| - var keys1 = Object.keys(obj1);
|
| - var keys2 = Object.keys(obj2);
|
| - if (keys1.length != keys2.length)
|
| + for (var i = 0; i < arr1.length; i++) {
|
| + if (!deepEqual(arr1[i], arr2[i]))
|
| return false;
|
| -
|
| - for (var i = 0; i < keys1.length; i++) {
|
| - var key = keys1[i];
|
| - if (!deepEqual(obj1[key], obj2[key]))
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| }
|
|
|
| - /**
|
| - * Returns a recursive copy of the value.
|
| - * @param {*} val Value to copy. Should be a primitive or only contain
|
| - * serializable data (primitives, serializable arrays and
|
| - * serializable objects).
|
| - * @return {*} A deep copy of the value.
|
| - */
|
| - function deepCopy(val) {
|
| - if (!(val instanceof Object))
|
| - return val;
|
| - return Array.isArray(val) ? deepCopyArray(/** @type {!Array} */(val)) :
|
| - deepCopyObject(val);
|
| - }
|
| + return true;
|
| +}
|
|
|
| - /**
|
| - * @param {!Array} arr
|
| - * @return {!Array} Deep copy of the array.
|
| - */
|
| - function deepCopyArray(arr) {
|
| - var copy = [];
|
| - for (var i = 0; i < arr.length; i++)
|
| - copy.push(deepCopy(arr[i]));
|
| - return copy;
|
| - }
|
| +/**
|
| + * @param {!Object} obj1
|
| + * @param {!Object} obj2
|
| + * @return {boolean} True if the objects are recursively equal.
|
| + */
|
| +function objectsEqual(obj1, obj2) {
|
| + var keys1 = Object.keys(obj1);
|
| + var keys2 = Object.keys(obj2);
|
| + if (keys1.length != keys2.length)
|
| + return false;
|
|
|
| - /**
|
| - * @param {!Object} obj
|
| - * @return {!Object} Deep copy of the object.
|
| - */
|
| - function deepCopyObject(obj) {
|
| - var copy = {};
|
| - var keys = Object.keys(obj);
|
| - for (var i = 0; i < keys.length; i++) {
|
| - var key = keys[i];
|
| - copy[key] = deepCopy(obj[key]);
|
| - }
|
| - return copy;
|
| + for (var i = 0; i < keys1.length; i++) {
|
| + var key = keys1[i];
|
| + if (!deepEqual(obj1[key], obj2[key]))
|
| + return false;
|
| }
|
|
|
| - Polymer({
|
| - is: 'settings-prefs',
|
| -
|
| - properties: {
|
| - /**
|
| - * Object containing all preferences, for use by Polymer controls.
|
| - * @type {Object|undefined}
|
| - */
|
| - prefs: {
|
| - type: Object,
|
| - notify: true,
|
| - },
|
| -
|
| - /**
|
| - * Map of pref keys to values representing the state of the Chrome
|
| - * pref store as of the last update from the API.
|
| - * @type {Object<*>}
|
| - * @private
|
| - */
|
| - lastPrefValues_: {
|
| - type: Object,
|
| - value: function() { return {}; },
|
| - },
|
| - },
|
| + return true;
|
| +}
|
|
|
| - observers: [
|
| - 'prefsChanged_(prefs.*)',
|
| - ],
|
| +/**
|
| + * Returns a recursive copy of the value.
|
| + * @param {*} val Value to copy. Should be a primitive or only contain
|
| + * serializable data (primitives, serializable arrays and
|
| + * serializable objects).
|
| + * @return {*} A deep copy of the value.
|
| + */
|
| +function deepCopy(val) {
|
| + if (!(val instanceof Object))
|
| + return val;
|
| + return Array.isArray(val) ? deepCopyArray(/** @type {!Array} */ (val)) :
|
| + deepCopyObject(val);
|
| +}
|
|
|
| - /** @type {SettingsPrivate} */
|
| - settingsApi_: /** @type {SettingsPrivate} */(chrome.settingsPrivate),
|
| +/**
|
| + * @param {!Array} arr
|
| + * @return {!Array} Deep copy of the array.
|
| + */
|
| +function deepCopyArray(arr) {
|
| + var copy = [];
|
| + for (var i = 0; i < arr.length; i++)
|
| + copy.push(deepCopy(arr[i]));
|
| + return copy;
|
| +}
|
|
|
| - /** @override */
|
| - created: function() {
|
| - if (!CrSettingsPrefs.deferInitialization)
|
| - this.initialize();
|
| - },
|
| +/**
|
| + * @param {!Object} obj
|
| + * @return {!Object} Deep copy of the object.
|
| + */
|
| +function deepCopyObject(obj) {
|
| + var copy = {};
|
| + var keys = Object.keys(obj);
|
| + for (var i = 0; i < keys.length; i++) {
|
| + var key = keys[i];
|
| + copy[key] = deepCopy(obj[key]);
|
| + }
|
| + return copy;
|
| +}
|
|
|
| - /** @override */
|
| - detached: function() {
|
| - CrSettingsPrefs.resetForTesting();
|
| - },
|
| +Polymer({
|
| + is: 'settings-prefs',
|
|
|
| + properties: {
|
| /**
|
| - * @param {SettingsPrivate=} opt_settingsApi SettingsPrivate implementation
|
| - * to use (chrome.settingsPrivate by default).
|
| + * Object containing all preferences, for use by Polymer controls.
|
| + * @type {Object|undefined}
|
| */
|
| - initialize: function(opt_settingsApi) {
|
| - // Only initialize once (or after resetForTesting() is called).
|
| - if (this.initialized_)
|
| - return;
|
| - this.initialized_ = true;
|
| -
|
| - if (opt_settingsApi)
|
| - this.settingsApi_ = opt_settingsApi;
|
| -
|
| - /** @private {function(!Array<!chrome.settingsPrivate.PrefObject>)} */
|
| - this.boundPrefsChanged_ = this.onSettingsPrivatePrefsChanged_.bind(this);
|
| - this.settingsApi_.onPrefsChanged.addListener(this.boundPrefsChanged_);
|
| - this.settingsApi_.getAllPrefs(
|
| - this.onSettingsPrivatePrefsFetched_.bind(this));
|
| + prefs: {
|
| + type: Object,
|
| + notify: true,
|
| },
|
|
|
| /**
|
| - * @param {!{path: string}} e
|
| + * Map of pref keys to values representing the state of the Chrome
|
| + * pref store as of the last update from the API.
|
| + * @type {Object<*>}
|
| * @private
|
| */
|
| - prefsChanged_: function(e) {
|
| - // |prefs| can be directly set or unset in tests.
|
| - if (!CrSettingsPrefs.isInitialized || e.path == 'prefs')
|
| - return;
|
| -
|
| - var key = this.getPrefKeyFromPath_(e.path);
|
| - var prefStoreValue = this.lastPrefValues_[key];
|
| -
|
| - var prefObj = /** @type {chrome.settingsPrivate.PrefObject} */(
|
| - this.get(key, this.prefs));
|
| -
|
| - // If settingsPrivate already has this value, ignore it. (Otherwise,
|
| - // a change event from settingsPrivate could make us call
|
| - // settingsPrivate.setPref and potentially trigger an IPC loop.)
|
| - if (!deepEqual(prefStoreValue, prefObj.value)) {
|
| - this.settingsApi_.setPref(
|
| - key,
|
| - prefObj.value,
|
| - /* pageId */ '',
|
| - /* callback */ this.setPrefCallback_.bind(this, key));
|
| - }
|
| + lastPrefValues_: {
|
| + type: Object,
|
| + value: function() {
|
| + return {};
|
| + },
|
| },
|
| + },
|
|
|
| - /**
|
| - * Called when prefs in the underlying Chrome pref store are changed.
|
| - * @param {!Array<!chrome.settingsPrivate.PrefObject>} prefs
|
| - * The prefs that changed.
|
| - * @private
|
| - */
|
| - onSettingsPrivatePrefsChanged_: function(prefs) {
|
| - if (CrSettingsPrefs.isInitialized)
|
| - this.updatePrefs_(prefs);
|
| - },
|
| + observers: [
|
| + 'prefsChanged_(prefs.*)',
|
| + ],
|
|
|
| - /**
|
| - * Called when prefs are fetched from settingsPrivate.
|
| - * @param {!Array<!chrome.settingsPrivate.PrefObject>} prefs
|
| - * @private
|
| - */
|
| - onSettingsPrivatePrefsFetched_: function(prefs) {
|
| + /** @type {SettingsPrivate} */
|
| + settingsApi_: /** @type {SettingsPrivate} */ (chrome.settingsPrivate),
|
| +
|
| + /** @override */
|
| + created: function() {
|
| + if (!CrSettingsPrefs.deferInitialization)
|
| + this.initialize();
|
| + },
|
| +
|
| + /** @override */
|
| + detached: function() {
|
| + CrSettingsPrefs.resetForTesting();
|
| + },
|
| +
|
| + /**
|
| + * @param {SettingsPrivate=} opt_settingsApi SettingsPrivate implementation
|
| + * to use (chrome.settingsPrivate by default).
|
| + */
|
| + initialize: function(opt_settingsApi) {
|
| + // Only initialize once (or after resetForTesting() is called).
|
| + if (this.initialized_)
|
| + return;
|
| + this.initialized_ = true;
|
| +
|
| + if (opt_settingsApi)
|
| + this.settingsApi_ = opt_settingsApi;
|
| +
|
| + /** @private {function(!Array<!chrome.settingsPrivate.PrefObject>)} */
|
| + this.boundPrefsChanged_ = this.onSettingsPrivatePrefsChanged_.bind(this);
|
| + this.settingsApi_.onPrefsChanged.addListener(this.boundPrefsChanged_);
|
| + this.settingsApi_.getAllPrefs(
|
| + this.onSettingsPrivatePrefsFetched_.bind(this));
|
| + },
|
| +
|
| + /**
|
| + * @param {!{path: string}} e
|
| + * @private
|
| + */
|
| + prefsChanged_: function(e) {
|
| + // |prefs| can be directly set or unset in tests.
|
| + if (!CrSettingsPrefs.isInitialized || e.path == 'prefs')
|
| + return;
|
| +
|
| + var key = this.getPrefKeyFromPath_(e.path);
|
| + var prefStoreValue = this.lastPrefValues_[key];
|
| +
|
| + var prefObj = /** @type {chrome.settingsPrivate.PrefObject} */ (
|
| + this.get(key, this.prefs));
|
| +
|
| + // If settingsPrivate already has this value, ignore it. (Otherwise,
|
| + // a change event from settingsPrivate could make us call
|
| + // settingsPrivate.setPref and potentially trigger an IPC loop.)
|
| + if (!deepEqual(prefStoreValue, prefObj.value)) {
|
| + this.settingsApi_.setPref(
|
| + key, prefObj.value,
|
| + /* pageId */ '',
|
| + /* callback */ this.setPrefCallback_.bind(this, key));
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Called when prefs in the underlying Chrome pref store are changed.
|
| + * @param {!Array<!chrome.settingsPrivate.PrefObject>} prefs
|
| + * The prefs that changed.
|
| + * @private
|
| + */
|
| + onSettingsPrivatePrefsChanged_: function(prefs) {
|
| + if (CrSettingsPrefs.isInitialized)
|
| this.updatePrefs_(prefs);
|
| - CrSettingsPrefs.setInitialized();
|
| - },
|
| + },
|
|
|
| - /**
|
| - * Checks the result of calling settingsPrivate.setPref.
|
| - * @param {string} key The key used in the call to setPref.
|
| - * @param {boolean} success True if setting the pref succeeded.
|
| - * @private
|
| - */
|
| - setPrefCallback_: function(key, success) {
|
| - if (!success)
|
| - this.refresh(key);
|
| - },
|
| + /**
|
| + * Called when prefs are fetched from settingsPrivate.
|
| + * @param {!Array<!chrome.settingsPrivate.PrefObject>} prefs
|
| + * @private
|
| + */
|
| + onSettingsPrivatePrefsFetched_: function(prefs) {
|
| + this.updatePrefs_(prefs);
|
| + CrSettingsPrefs.setInitialized();
|
| + },
|
|
|
| - /**
|
| - * Get the current pref value from chrome.settingsPrivate to ensure the UI
|
| - * stays up to date.
|
| - * @param {string} key
|
| - */
|
| - refresh: function(key) {
|
| - this.settingsApi_.getPref(key, function(pref) {
|
| - this.updatePrefs_([pref]);
|
| - }.bind(this));
|
| - },
|
| + /**
|
| + * Checks the result of calling settingsPrivate.setPref.
|
| + * @param {string} key The key used in the call to setPref.
|
| + * @param {boolean} success True if setting the pref succeeded.
|
| + * @private
|
| + */
|
| + setPrefCallback_: function(key, success) {
|
| + if (!success)
|
| + this.refresh(key);
|
| + },
|
|
|
| - /**
|
| - * Updates the prefs model with the given prefs.
|
| - * @param {!Array<!chrome.settingsPrivate.PrefObject>} newPrefs
|
| - * @private
|
| - */
|
| - updatePrefs_: function(newPrefs) {
|
| - // Use the existing prefs object or create it.
|
| - var prefs = this.prefs || {};
|
| - newPrefs.forEach(function(newPrefObj) {
|
| - // Use the PrefObject from settingsPrivate to create a copy in
|
| - // lastPrefValues_ at the pref's key.
|
| - this.lastPrefValues_[newPrefObj.key] = deepCopy(newPrefObj.value);
|
| -
|
| - if (!deepEqual(this.get(newPrefObj.key, prefs), newPrefObj)) {
|
| - // Add the pref to |prefs|.
|
| - cr.exportPath(newPrefObj.key, newPrefObj, prefs);
|
| - // If this.prefs already exists, notify listeners of the change.
|
| - if (prefs == this.prefs)
|
| - this.notifyPath('prefs.' + newPrefObj.key, newPrefObj);
|
| - }
|
| - }, this);
|
| - if (!this.prefs)
|
| - this.prefs = prefs;
|
| - },
|
| + /**
|
| + * Get the current pref value from chrome.settingsPrivate to ensure the UI
|
| + * stays up to date.
|
| + * @param {string} key
|
| + */
|
| + refresh: function(key) {
|
| + this.settingsApi_.getPref(key, function(pref) {
|
| + this.updatePrefs_([pref]);
|
| + }.bind(this));
|
| + },
|
|
|
| - /**
|
| - * Given a 'property-changed' path, returns the key of the preference the
|
| - * path refers to. E.g., if the path of the changed property is
|
| - * 'prefs.search.suggest_enabled.value', the key of the pref that changed is
|
| - * 'search.suggest_enabled'.
|
| - * @param {string} path
|
| - * @return {string}
|
| - * @private
|
| - */
|
| - getPrefKeyFromPath_: function(path) {
|
| - // Skip the first token, which refers to the member variable (this.prefs).
|
| - var parts = path.split('.');
|
| - assert(parts.shift() == 'prefs', "Path doesn't begin with 'prefs'");
|
| -
|
| - for (var i = 1; i <= parts.length; i++) {
|
| - var key = parts.slice(0, i).join('.');
|
| - // The lastPrefValues_ keys match the pref keys.
|
| - if (this.lastPrefValues_.hasOwnProperty(key))
|
| - return key;
|
| + /**
|
| + * Updates the prefs model with the given prefs.
|
| + * @param {!Array<!chrome.settingsPrivate.PrefObject>} newPrefs
|
| + * @private
|
| + */
|
| + updatePrefs_: function(newPrefs) {
|
| + // Use the existing prefs object or create it.
|
| + var prefs = this.prefs || {};
|
| + newPrefs.forEach(function(newPrefObj) {
|
| + // Use the PrefObject from settingsPrivate to create a copy in
|
| + // lastPrefValues_ at the pref's key.
|
| + this.lastPrefValues_[newPrefObj.key] = deepCopy(newPrefObj.value);
|
| +
|
| + if (!deepEqual(this.get(newPrefObj.key, prefs), newPrefObj)) {
|
| + // Add the pref to |prefs|.
|
| + cr.exportPath(newPrefObj.key, newPrefObj, prefs);
|
| + // If this.prefs already exists, notify listeners of the change.
|
| + if (prefs == this.prefs)
|
| + this.notifyPath('prefs.' + newPrefObj.key, newPrefObj);
|
| }
|
| - return '';
|
| - },
|
| + }, this);
|
| + if (!this.prefs)
|
| + this.prefs = prefs;
|
| + },
|
|
|
| - /**
|
| - * Resets the element so it can be re-initialized with a new prefs state.
|
| - */
|
| - resetForTesting: function() {
|
| - if (!this.initialized_)
|
| - return;
|
| - this.prefs = undefined;
|
| - this.lastPrefValues_ = {};
|
| - this.initialized_ = false;
|
| - // Remove the listener added in initialize().
|
| - this.settingsApi_.onPrefsChanged.removeListener(this.boundPrefsChanged_);
|
| - this.settingsApi_ =
|
| - /** @type {SettingsPrivate} */(chrome.settingsPrivate);
|
| - },
|
| - });
|
| + /**
|
| + * Given a 'property-changed' path, returns the key of the preference the
|
| + * path refers to. E.g., if the path of the changed property is
|
| + * 'prefs.search.suggest_enabled.value', the key of the pref that changed is
|
| + * 'search.suggest_enabled'.
|
| + * @param {string} path
|
| + * @return {string}
|
| + * @private
|
| + */
|
| + getPrefKeyFromPath_: function(path) {
|
| + // Skip the first token, which refers to the member variable (this.prefs).
|
| + var parts = path.split('.');
|
| + assert(parts.shift() == 'prefs', 'Path doesn\'t begin with \'prefs\'');
|
| +
|
| + for (var i = 1; i <= parts.length; i++) {
|
| + var key = parts.slice(0, i).join('.');
|
| + // The lastPrefValues_ keys match the pref keys.
|
| + if (this.lastPrefValues_.hasOwnProperty(key))
|
| + return key;
|
| + }
|
| + return '';
|
| + },
|
| +
|
| + /**
|
| + * Resets the element so it can be re-initialized with a new prefs state.
|
| + */
|
| + resetForTesting: function() {
|
| + if (!this.initialized_)
|
| + return;
|
| + this.prefs = undefined;
|
| + this.lastPrefValues_ = {};
|
| + this.initialized_ = false;
|
| + // Remove the listener added in initialize().
|
| + this.settingsApi_.onPrefsChanged.removeListener(this.boundPrefsChanged_);
|
| + this.settingsApi_ =
|
| + /** @type {SettingsPrivate} */ (chrome.settingsPrivate);
|
| + },
|
| +});
|
| })();
|
|
|