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

Side by Side Diff: chrome/browser/resources/md_bookmarks/store.js

Issue 2813503002: MD Bookmarks: Prevent navigating to invalid folders (Closed)
Patch Set: Rebase & Implement deferred actions Created 3 years, 7 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 unified diff | Download patch
OLDNEW
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
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 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698