Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2932)

Unified Diff: chrome/browser/resources/settings/prefs/prefs.js

Issue 1357183002: MD-Settings: convert cr-settings-prefs to a singleton model (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: unnecessary parens Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 ddb38be8ee478326abb67fec7a1cc1ffb9c149f1..05c60a11120818d0fa1fb557bb065acfe831417a 100644
--- a/chrome/browser/resources/settings/prefs/prefs.js
+++ b/chrome/browser/resources/settings/prefs/prefs.js
@@ -4,12 +4,12 @@
/**
* @fileoverview
- * 'cr-settings-prefs' models Chrome settings and preferences, listening for
- * changes to Chrome prefs whitelisted in chrome.settingsPrivate.
- * When changing prefs in this element's 'prefs' property via the UI, this
- * element tries to set those preferences in Chrome. Whether or not the calls to
- * settingsPrivate.setPref succeed, 'prefs' is eventually consistent with the
- * Chrome pref store.
+ * 'cr-settings-prefs' exposes a sinlgeton model of Chrome settings and
+ * preferences, which listens to changes to Chrome prefs whitelisted in
+ * chrome.settingsPrivate. When changing prefs in this element's 'prefs'
+ * property via the UI, the model tries to set those preferences in Chrome.
+ * Whether or not the calls to settingsPrivate.setPref succeed, 'prefs'
+ * is eventually consistent with the Chrome pref store.
*
* Example:
*
@@ -136,6 +136,117 @@
},
/**
+ * Shared private state.
+ * @type {!Element}
+ */
+ prefsPrivate_: {
+ type: Object,
+ value: document.createElement('cr-settings-prefs-private'),
+ },
+ },
+
+ observers: [
+ 'prefsChanged_(prefs.*)',
+ ],
+
+ /** @override */
+ ready: function() {
+ this.prefsPrivate_.initialize();
+ this.startListening_();
+ },
+
+ /**
+ * Binds this.prefs to the cr-settings-prefs-private's shared prefs once
+ * preferences are initialized.
+ * @private
+ */
+ startListening_: function() {
+ CrSettingsPrefs.initialized.then(function() {
+ // Ignore changes to prevent prefsChanged_ from notifying prefsPrivate_.
+ this.runWhileIgnoringChanges_(function() {
+ this.prefs = this.prefsPrivate_.prefs;
+ this.stopListening_();
+ this.listen(
+ this.prefsPrivate_, 'prefs-changed', 'prefsPrivateChanged_');
+ });
+ }.bind(this));
+ },
+
+ /**
+ * Stops listening for changes to cr-settings-prefs-private's shared prefs.
+ * @private
+ */
+ stopListening_: function() {
+ this.unlisten(
+ this.prefsPrivate_, 'prefs-changed', 'prefsPrivateChanged_');
+ },
+
+ /**
+ * Handles changes reported by prefsPrivate_.
+ * @private
+ */
+ prefsPrivateChanged_: function(e) {
+ // Ignore changes because we've defeated Polymer's dirty-checking.
+ this.runWhileIgnoringChanges_(function() {
+ // Forward notification to host.
+ this.fire(e.type, e.detail, {bubbles: false});
+ });
+ },
+
+ /**
+ * Forwards changes to this.prefs to cr-settings-prefs-private.
+ * @private
+ */
+ prefsChanged_: function(info) {
+ // Ignore prefsPrivate_ of changes that came from it so we don't
+ // re-processing changes made in other instances of this element.
+ if (!this.ignoreChanges_)
+ this.prefsPrivate_.fire('prefs-changed', info, {bubbles: false});
+ },
+
+ /**
+ * Sets ignoreChanged_ before calling the function to suppress change
+ * events that are manually handled.
+ * @param {!function()} fn
+ * @private
+ */
+ runWhileIgnoringChanges_: function(fn) {
Dan Beam 2015/09/22 06:12:31 assert(!this.ignoreChanges_, 'update the code to s
michaelpg 2015/09/22 21:38:36 Done.
+ this.ignoreChanges_ = true;
+ fn.call(this);
+ // We can unset ignoreChanges_ now because change notifications
+ // are synchronous.
+ this.ignoreChanges_ = false;
+ },
+
+ /**
+ * Uninitializes this element to remove it from tests. Also resets
+ * cr-settings-prefs-private, allowing newly created elements to
+ * re-initialize it.
+ */
+ resetForTesting: function() {
+ this.stopListening_();
+ this.prefsPrivate_.resetForTesting();
+ },
+ });
+
+ /**
+ * Privately used element that contains, listens to and updates the shared
+ * prefs state.
+ */
+ Polymer({
+ is: 'cr-settings-prefs-private',
+
+ 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<*>}
@@ -147,19 +258,23 @@
},
},
- observers: [
- 'prefsChanged_(prefs.*)',
- ],
+ // Listen for the manually fired prefs-changed event.
+ listeners: {
+ 'prefs-changed': 'prefsChanged_',
+ },
settingsApi_: chrome.settingsPrivate,
- /** @override */
- ready: function() {
+ initialize: function() {
+ // Only initialize once (or after resetForTesting() is called).
+ if (this.initialized_)
+ return;
+ this.initialized_ = true;
+
// Set window.mockApi to pass a custom settings API, i.e. for tests.
// TODO(michaelpg): don't use a global.
if (window.mockApi)
this.settingsApi_ = window.mockApi;
- CrSettingsPrefs.isInitialized = false;
this.settingsApi_.onPrefsChanged.addListener(
this.onSettingsPrivatePrefsChanged_.bind(this));
@@ -169,10 +284,11 @@
/**
* Polymer callback for changes to this.prefs.
- * @param {!{path: string, value: *}} change
+ * @param {!CustomEvent} e
+ * @param {!{path: string}} change
* @private
*/
- prefsChanged_: function(change) {
+ prefsChanged_: function(e, change) {
if (!CrSettingsPrefs.isInitialized)
return;
@@ -213,9 +329,8 @@
*/
onSettingsPrivatePrefsFetched_: function(prefs) {
this.updatePrefs_(prefs);
-
- CrSettingsPrefs.isInitialized = true;
- document.dispatchEvent(new Event(CrSettingsPrefs.INITIALIZED));
+ // Prefs are now initialized.
Dan Beam 2015/09/22 06:12:31 nit: useless comment
michaelpg 2015/09/22 21:38:37 Done.
+ CrSettingsPrefs.setInitialized();
},
/**
@@ -248,11 +363,13 @@
// lastPrefValues_ at the pref's key.
this.lastPrefValues_[newPrefObj.key] = deepCopy(newPrefObj.value);
- // 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);
+ 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;
@@ -280,5 +397,14 @@
}
return '';
},
+
+ /**
+ * Resets the element so it can be re-initialized with a new prefs state.
+ */
+ resetForTesting: function() {
+ this.prefs = undefined;
+ this.lastPrefValues_ = {};
+ this.initialized_ = false;
+ },
});
})();

Powered by Google App Engine
This is Rietveld 408576698