Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview A singleton datastore for the Bookmarks page. Page state is | 6 * @fileoverview A singleton datastore for the Bookmarks page. Page state is |
| 7 * publicly readable, but can only be modified by dispatching an Action to | 7 * publicly readable, but can only be modified by dispatching an Action to |
| 8 * the store. | 8 * the store. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 cr.define('bookmarks', function() { | 11 cr.define('bookmarks', function() { |
| 12 /** @constructor */ | 12 /** @constructor */ |
| 13 function Store() { | 13 function Store() { |
| 14 /** @type {!BookmarksPageState} */ | 14 /** @type {!BookmarksPageState} */ |
| 15 this.data_ = bookmarks.util.createEmptyState(); | 15 this.data_ = bookmarks.util.createEmptyState(); |
| 16 /** @type {boolean} */ | 16 /** @type {boolean} */ |
| 17 this.initialized_ = false; | 17 this.initialized_ = false; |
| 18 /** @type {!Array<!Action>} */ | 18 /** @type {!Array<?Action|DeferredAction>} */ |
|
calamity
2017/05/02 08:27:15
This is an abomination of a type.
tsergeant
2017/05/03 02:57:31
Acknowledged.
| |
| 19 this.queuedActions_ = []; | 19 this.queuedActions_ = []; |
| 20 /** @type {!Array<!StoreObserver>} */ | 20 /** @type {!Array<!StoreObserver>} */ |
| 21 this.observers_ = []; | 21 this.observers_ = []; |
| 22 } | 22 } |
| 23 | 23 |
| 24 Store.prototype = { | 24 Store.prototype = { |
| 25 /** | 25 /** |
| 26 * @param {!BookmarksPageState} initialState | 26 * @param {!BookmarksPageState} initialState |
| 27 */ | 27 */ |
| 28 init: function(initialState) { | 28 init: function(initialState) { |
| 29 this.data_ = initialState; | 29 this.data_ = initialState; |
| 30 | 30 |
| 31 this.queuedActions_.forEach(function(action) { | 31 this.queuedActions_.forEach(function(action) { |
| 32 this.reduce_(action); | 32 this.handleActionInternal_(action); |
| 33 }.bind(this)); | 33 }.bind(this)); |
| 34 | 34 |
| 35 this.initialized_ = true; | 35 this.initialized_ = true; |
| 36 this.notifyObservers_(this.data_); | 36 this.notifyObservers_(this.data_); |
| 37 }, | 37 }, |
| 38 | 38 |
| 39 /** @type {!BookmarksPageState} */ | 39 /** @type {!BookmarksPageState} */ |
| 40 get data() { | 40 get data() { |
| 41 return this.data_; | 41 return this.data_; |
| 42 }, | 42 }, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 54 /** @param {!StoreObserver} observer */ | 54 /** @param {!StoreObserver} observer */ |
| 55 removeObserver: function(observer) { | 55 removeObserver: function(observer) { |
| 56 var index = this.observers_.indexOf(observer); | 56 var index = this.observers_.indexOf(observer); |
| 57 this.observers_.splice(index, 1); | 57 this.observers_.splice(index, 1); |
| 58 }, | 58 }, |
| 59 | 59 |
| 60 /** | 60 /** |
| 61 * Transition to a new UI state based on the supplied |action|, and notify | 61 * Transition to a new UI state based on the supplied |action|, and notify |
| 62 * observers of the change. If the Store has not yet been initialized, the | 62 * observers of the change. If the Store has not yet been initialized, the |
| 63 * action will be queued and performed upon initialization. | 63 * action will be queued and performed upon initialization. |
| 64 * @param {Action} action | 64 * If the action requires work to be performed asynchronously (eg, getting |
| 65 * results from the bookmarks API), it is possible to dispatch a | |
| 66 * DeferredAction (of the form `handleAction(function(dispatch) { ... })`). | |
| 67 * Inside that function, |dispatch| can be called asynchronously to dispatch | |
| 68 * Actions directly to the Store. | |
| 69 * @param {?Action|DeferredAction} action | |
| 65 */ | 70 */ |
| 66 handleAction: function(action) { | 71 handleAction: function(action) { |
| 72 if (!action) | |
| 73 return; | |
|
calamity
2017/05/02 08:27:15
When does this happen?
tsergeant
2017/05/03 02:57:31
It's the null check that replaces the no-op action
| |
| 74 | |
| 67 if (!this.initialized_) { | 75 if (!this.initialized_) { |
| 68 this.queuedActions_.push(action); | 76 this.queuedActions_.push(action); |
| 69 return; | 77 return; |
| 70 } | 78 } |
| 71 | 79 |
| 72 this.reduce_(action); | 80 this.handleActionInternal_(action); |
| 73 this.notifyObservers_(this.data_); | |
| 74 }, | 81 }, |
| 75 | 82 |
| 76 /** | 83 /** |
| 77 * @param {Action} action | 84 * @param {?Action|DeferredAction} action |
| 85 */ | |
| 86 handleActionInternal_: function(action) { | |
| 87 if (typeof action == 'function') { | |
|
calamity
2017/05/02 08:27:15
So one option is to make everything internally a D
tsergeant
2017/05/03 02:57:31
Hmmm. There is some precedent for passing in param
| |
| 88 action(this.reduce_.bind(this)); | |
| 89 return; | |
| 90 } | |
| 91 | |
| 92 this.reduce_(action); | |
| 93 }, | |
| 94 | |
| 95 /** | |
| 96 * @param {?Action} action | |
| 78 * @private | 97 * @private |
| 79 */ | 98 */ |
| 80 reduce_: function(action) { | 99 reduce_: function(action) { |
| 100 if (!action) | |
| 101 return; | |
| 102 | |
| 81 this.data_ = bookmarks.reduceAction(this.data_, action); | 103 this.data_ = bookmarks.reduceAction(this.data_, action); |
| 104 if (this.isInitialized()) | |
|
calamity
2017/05/02 08:27:15
// Batch notification until after all initializati
tsergeant
2017/05/03 02:57:31
Done.
| |
| 105 this.notifyObservers_(this.data_); | |
| 82 }, | 106 }, |
| 83 | 107 |
| 84 /** | 108 /** |
| 85 * @param {!BookmarksPageState} state | 109 * @param {!BookmarksPageState} state |
| 86 * @private | 110 * @private |
| 87 */ | 111 */ |
| 88 notifyObservers_: function(state) { | 112 notifyObservers_: function(state) { |
| 89 this.observers_.forEach(function(o) { | 113 this.observers_.forEach(function(o) { |
| 90 o.onStateChanged(state); | 114 o.onStateChanged(state); |
| 91 }); | 115 }); |
| 92 }, | 116 }, |
| 93 }; | 117 }; |
| 94 | 118 |
| 95 cr.addSingletonGetter(Store); | 119 cr.addSingletonGetter(Store); |
| 96 | 120 |
| 97 return { | 121 return { |
| 98 Store: Store, | 122 Store: Store, |
| 99 }; | 123 }; |
| 100 }); | 124 }); |
| OLD | NEW |