| 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<DeferredAction>} */ | 18 /** @type {!Array<DeferredAction>} */ |
| 19 this.queuedActions_ = []; | 19 this.queuedActions_ = []; |
| 20 /** @type {!Array<!StoreObserver>} */ | 20 /** @type {!Array<!StoreObserver>} */ |
| 21 this.observers_ = []; | 21 this.observers_ = []; |
| 22 /** @private {boolean} */ |
| 23 this.batchMode_ = false; |
| 22 } | 24 } |
| 23 | 25 |
| 24 Store.prototype = { | 26 Store.prototype = { |
| 25 /** | 27 /** |
| 26 * @param {!BookmarksPageState} initialState | 28 * @param {!BookmarksPageState} initialState |
| 27 */ | 29 */ |
| 28 init: function(initialState) { | 30 init: function(initialState) { |
| 29 this.data_ = initialState; | 31 this.data_ = initialState; |
| 30 | 32 |
| 31 this.queuedActions_.forEach(function(action) { | 33 this.queuedActions_.forEach(function(action) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 51 this.observers_.push(observer); | 53 this.observers_.push(observer); |
| 52 }, | 54 }, |
| 53 | 55 |
| 54 /** @param {!StoreObserver} observer */ | 56 /** @param {!StoreObserver} observer */ |
| 55 removeObserver: function(observer) { | 57 removeObserver: function(observer) { |
| 56 var index = this.observers_.indexOf(observer); | 58 var index = this.observers_.indexOf(observer); |
| 57 this.observers_.splice(index, 1); | 59 this.observers_.splice(index, 1); |
| 58 }, | 60 }, |
| 59 | 61 |
| 60 /** | 62 /** |
| 63 * Begin a batch update to store data, which will disable updates to the |
| 64 * UI until `endBatchUpdate` is called. This is useful when a single UI |
| 65 * operation is likely to cause many sequential model updates (eg, deleting |
| 66 * 100 bookmarks). |
| 67 */ |
| 68 beginBatchUpdate: function() { |
| 69 this.batchMode_ = true; |
| 70 }, |
| 71 |
| 72 /** |
| 73 * End a batch update to the store data, notifying the UI of any changes |
| 74 * which occurred while batch mode was enabled. |
| 75 */ |
| 76 endBatchUpdate: function() { |
| 77 this.batchMode_ = false; |
| 78 this.notifyObservers_(this.data); |
| 79 }, |
| 80 |
| 81 /** |
| 61 * Handles a 'deferred' action, which can asynchronously dispatch actions | 82 * Handles a 'deferred' action, which can asynchronously dispatch actions |
| 62 * to the Store in order to reach a new UI state. DeferredActions have the | 83 * to the Store in order to reach a new UI state. DeferredActions have the |
| 63 * form `dispatchAsync(function(dispatch) { ... })`). Inside that function, | 84 * form `dispatchAsync(function(dispatch) { ... })`). Inside that function, |
| 64 * the |dispatch| callback can be called asynchronously to dispatch Actions | 85 * the |dispatch| callback can be called asynchronously to dispatch Actions |
| 65 * directly to the Store. | 86 * directly to the Store. |
| 66 * @param {DeferredAction} action | 87 * @param {DeferredAction} action |
| 67 */ | 88 */ |
| 68 dispatchAsync: function(action) { | 89 dispatchAsync: function(action) { |
| 69 if (!this.initialized_) { | 90 if (!this.initialized_) { |
| 70 this.queuedActions_.push(action); | 91 this.queuedActions_.push(action); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 97 * @param {?Action} action | 118 * @param {?Action} action |
| 98 * @private | 119 * @private |
| 99 */ | 120 */ |
| 100 reduce_: function(action) { | 121 reduce_: function(action) { |
| 101 if (!action) | 122 if (!action) |
| 102 return; | 123 return; |
| 103 | 124 |
| 104 this.data_ = bookmarks.reduceAction(this.data_, action); | 125 this.data_ = bookmarks.reduceAction(this.data_, action); |
| 105 // Batch notifications until after all initialization queuedActions are | 126 // Batch notifications until after all initialization queuedActions are |
| 106 // resolved. | 127 // resolved. |
| 107 if (this.isInitialized()) | 128 if (this.isInitialized() && !this.batchMode_) |
| 108 this.notifyObservers_(this.data_); | 129 this.notifyObservers_(this.data_); |
| 109 }, | 130 }, |
| 110 | 131 |
| 111 /** | 132 /** |
| 112 * @param {!BookmarksPageState} state | 133 * @param {!BookmarksPageState} state |
| 113 * @private | 134 * @private |
| 114 */ | 135 */ |
| 115 notifyObservers_: function(state) { | 136 notifyObservers_: function(state) { |
| 116 this.observers_.forEach(function(o) { | 137 this.observers_.forEach(function(o) { |
| 117 o.onStateChanged(state); | 138 o.onStateChanged(state); |
| 118 }); | 139 }); |
| 119 }, | 140 }, |
| 120 }; | 141 }; |
| 121 | 142 |
| 122 cr.addSingletonGetter(Store); | 143 cr.addSingletonGetter(Store); |
| 123 | 144 |
| 124 return { | 145 return { |
| 125 Store: Store, | 146 Store: Store, |
| 126 }; | 147 }; |
| 127 }); | 148 }); |
| OLD | NEW |