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>} */ |
| 19 this.queuedActions_ = []; |
18 /** @type {!Array<!StoreObserver>} */ | 20 /** @type {!Array<!StoreObserver>} */ |
19 this.observers_ = []; | 21 this.observers_ = []; |
20 } | 22 } |
21 | 23 |
22 Store.prototype = { | 24 Store.prototype = { |
23 /** | 25 /** |
24 * @param {!BookmarksPageState} initialState | 26 * @param {!BookmarksPageState} initialState |
25 */ | 27 */ |
26 init: function(initialState) { | 28 init: function(initialState) { |
27 this.data_ = initialState; | 29 this.data_ = initialState; |
| 30 |
| 31 this.queuedActions_.forEach(function(action) { |
| 32 this.reduce_(action); |
| 33 }.bind(this)); |
| 34 |
28 this.initialized_ = true; | 35 this.initialized_ = true; |
29 this.notifyObservers_(this.data_); | 36 this.notifyObservers_(this.data_); |
30 }, | 37 }, |
31 | 38 |
32 /** @type {!BookmarksPageState} */ | 39 /** @type {!BookmarksPageState} */ |
33 get data() { | 40 get data() { |
34 return this.data_; | 41 return this.data_; |
35 }, | 42 }, |
36 | 43 |
37 /** @return {boolean} */ | 44 /** @return {boolean} */ |
38 isInitialized: function() { | 45 isInitialized: function() { |
39 return this.initialized_; | 46 return this.initialized_; |
40 }, | 47 }, |
41 | 48 |
42 /** @param {!StoreObserver} observer */ | 49 /** @param {!StoreObserver} observer */ |
43 addObserver: function(observer) { | 50 addObserver: function(observer) { |
44 this.observers_.push(observer); | 51 this.observers_.push(observer); |
45 }, | 52 }, |
46 | 53 |
47 /** @param {!StoreObserver} observer */ | 54 /** @param {!StoreObserver} observer */ |
48 removeObserver: function(observer) { | 55 removeObserver: function(observer) { |
49 var index = this.observers_.indexOf(observer); | 56 var index = this.observers_.indexOf(observer); |
50 this.observers_.splice(index, 1); | 57 this.observers_.splice(index, 1); |
51 }, | 58 }, |
52 | 59 |
53 /** | 60 /** |
54 * 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 |
55 * observers of the change. | 62 * observers of the change. If the Store has not yet been initialized, the |
| 63 * action will be queued and performed upon initialization. |
56 * @param {Action} action | 64 * @param {Action} action |
57 */ | 65 */ |
58 handleAction: function(action) { | 66 handleAction: function(action) { |
59 if (!this.initialized_) | 67 if (!this.initialized_) { |
| 68 this.queuedActions_.push(action); |
60 return; | 69 return; |
| 70 } |
61 | 71 |
| 72 this.reduce_(action); |
| 73 this.notifyObservers_(this.data_); |
| 74 }, |
| 75 |
| 76 /** |
| 77 * @param {Action} action |
| 78 * @private |
| 79 */ |
| 80 reduce_: function(action) { |
62 this.data_ = bookmarks.reduceAction(this.data_, action); | 81 this.data_ = bookmarks.reduceAction(this.data_, action); |
63 this.notifyObservers_(this.data_); | |
64 }, | 82 }, |
65 | 83 |
66 /** | 84 /** |
67 * @param {!BookmarksPageState} state | 85 * @param {!BookmarksPageState} state |
68 * @private | 86 * @private |
69 */ | 87 */ |
70 notifyObservers_: function(state) { | 88 notifyObservers_: function(state) { |
71 this.observers_.forEach(function(o) { | 89 this.observers_.forEach(function(o) { |
72 o.onStateChanged(state); | 90 o.onStateChanged(state); |
73 }); | 91 }); |
74 }, | 92 }, |
75 }; | 93 }; |
76 | 94 |
77 cr.addSingletonGetter(Store); | 95 cr.addSingletonGetter(Store); |
78 | 96 |
79 return { | 97 return { |
80 Store: Store, | 98 Store: Store, |
81 }; | 99 }; |
82 }); | 100 }); |
OLD | NEW |