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

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

Issue 2752223004: MD Bookmarks: Remove deleted nodes from state tree (Closed)
Patch Set: Rebase Created 3 years, 9 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 Module of functions which produce a new page state in response 6 * @fileoverview Module of functions which produce a new page state in response
7 * to an action. Reducers (in the same sense as Array.prototype.reduce) must be 7 * to an action. Reducers (in the same sense as Array.prototype.reduce) must be
8 * pure functions: they must not modify existing state objects, or make any API 8 * pure functions: they must not modify existing state objects, or make any API
9 * calls. 9 * calls.
10 */ 10 */
(...skipping 26 matching lines...) Expand all
37 * @return {SelectionState} 37 * @return {SelectionState}
38 */ 38 */
39 SelectionState.deselectAll = function(selectionState) { 39 SelectionState.deselectAll = function(selectionState) {
40 return { 40 return {
41 items: {}, 41 items: {},
42 anchor: null, 42 anchor: null,
43 }; 43 };
44 }; 44 };
45 45
46 /** 46 /**
47 * @param {SelectionState} selectionState
48 * @param {!Set<string>} deleted
49 * @return SelectionState
50 */
51 SelectionState.deselectDeletedItems = function(selectionState, deleted) {
52 return /** @type {SelectionState} */ Object.assign({}, selectionState, {
53 items: bookmarks.util.removeNodesFromMap(selectionState.items, deleted),
calamity 2017/04/03 06:54:24 When this turns into a Set, this won't work anymor
tsergeant 2017/04/04 04:42:27 I've rebased onto your Map->Set CL, and added a ne
54 anchor: null,
calamity 2017/04/03 06:54:24 nit: Ideally the anchor remains on the same item i
tsergeant 2017/04/04 04:42:27 My general feeling is that it's not really worth t
55 });
56 };
57
58 /**
47 * @param {SelectionState} selection 59 * @param {SelectionState} selection
48 * @param {Action} action 60 * @param {Action} action
49 * @return {SelectionState} 61 * @return {SelectionState}
50 */ 62 */
51 SelectionState.updateSelection = function(selection, action) { 63 SelectionState.updateSelection = function(selection, action) {
52 switch (action.name) { 64 switch (action.name) {
53 case 'clear-search': 65 case 'clear-search':
54 case 'finish-search': 66 case 'finish-search':
55 case 'select-folder': 67 case 'select-folder':
56 return SelectionState.deselectAll(selection); 68 return SelectionState.deselectAll(selection);
57 case 'select-items': 69 case 'select-items':
58 return SelectionState.selectItems(selection, action); 70 return SelectionState.selectItems(selection, action);
71 case 'remove-bookmark':
72 return SelectionState.deselectDeletedItems(
73 selection, action.descendants);
74 default:
75 return selection;
59 } 76 }
60 return selection;
61 }; 77 };
62 78
63 var SearchState = {}; 79 var SearchState = {};
64 80
65 /** 81 /**
66 * @param {SearchState} search 82 * @param {SearchState} search
67 * @param {Action} action 83 * @param {Action} action
68 * @return {SearchState} 84 * @return {SearchState}
69 */ 85 */
70 SearchState.startSearch = function(search, action) { 86 SearchState.startSearch = function(search, action) {
(...skipping 20 matching lines...) Expand all
91 SearchState.clearSearch = function() { 107 SearchState.clearSearch = function() {
92 return { 108 return {
93 term: '', 109 term: '',
94 inProgress: false, 110 inProgress: false,
95 results: [], 111 results: [],
96 }; 112 };
97 }; 113 };
98 114
99 /** 115 /**
100 * @param {SearchState} search 116 * @param {SearchState} search
117 * @param {!Set<string>} deletedIds
118 * @return {SearchState}
119 */
120 SearchState.removeDeletedResults = function(search, deletedIds) {
121 var newResults = [];
122 search.results.forEach(function(id) {
123 if (!deletedIds.has(id))
124 newResults.push(id);
125 });
126 return /** @type {SearchState} */ (Object.assign({}, search, {
127 results: newResults,
128 }));
129 };
130
131 /**
132 * @param {SearchState} search
101 * @param {Action} action 133 * @param {Action} action
102 * @return {SearchState} 134 * @return {SearchState}
103 */ 135 */
104 SearchState.updateSearch = function(search, action) { 136 SearchState.updateSearch = function(search, action) {
105 switch (action.name) { 137 switch (action.name) {
106 case 'start-search': 138 case 'start-search':
107 return SearchState.startSearch(search, action); 139 return SearchState.startSearch(search, action);
108 case 'select-folder': 140 case 'select-folder':
109 case 'clear-search': 141 case 'clear-search':
110 return SearchState.clearSearch(); 142 return SearchState.clearSearch();
111 case 'finish-search': 143 case 'finish-search':
112 return SearchState.finishSearch(search, action); 144 return SearchState.finishSearch(search, action);
145 case 'remove-bookmark':
146 return SearchState.removeDeletedResults(search, action.descendants);
113 default: 147 default:
114 return search; 148 return search;
115 } 149 }
116 }; 150 };
117 151
118 var NodeState = {}; 152 var NodeState = {};
119 153
120 /** 154 /**
121 * @param {NodeList} nodes 155 * @param {NodeList} nodes
122 * @param {string} id 156 * @param {string} id
(...skipping 21 matching lines...) Expand all
144 Object.assign({}, node, action.changeInfo)); 178 Object.assign({}, node, action.changeInfo));
145 }); 179 });
146 }; 180 };
147 181
148 /** 182 /**
149 * @param {NodeList} nodes 183 * @param {NodeList} nodes
150 * @param {Action} action 184 * @param {Action} action
151 * @return {NodeList} 185 * @return {NodeList}
152 */ 186 */
153 NodeState.removeBookmark = function(nodes, action) { 187 NodeState.removeBookmark = function(nodes, action) {
154 return NodeState.modifyNode_(nodes, action.parentId, function(node) { 188 var newState =
155 var newChildren = node.children.slice(); 189 NodeState.modifyNode_(nodes, action.parentId, function(node) {
156 newChildren.splice(action.index, 1); 190 var newChildren = node.children.slice();
157 return /** @type {BookmarkNode} */ ( 191 newChildren.splice(action.index, 1);
158 Object.assign({}, node, {children: newChildren})); 192 return /** @type {BookmarkNode} */ (
159 }); 193 Object.assign({}, node, {children: newChildren}));
194 });
195
196 return bookmarks.util.removeNodesFromMap(newState, action.descendants);
160 }; 197 };
161 198
162 /** 199 /**
163 * @param {NodeList} nodes 200 * @param {NodeList} nodes
164 * @param {Action} action 201 * @param {Action} action
165 * @return {NodeList} 202 * @return {NodeList}
166 */ 203 */
167 NodeState.moveBookmark = function(nodes, action) { 204 NodeState.moveBookmark = function(nodes, action) {
168 var nodeModifications = {}; 205 var nodeModifications = {};
169 var id = action.id; 206 var id = action.id;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 }; 268 };
232 269
233 /** 270 /**
234 * @param {?string} selectedFolder 271 * @param {?string} selectedFolder
235 * @param {Action} action 272 * @param {Action} action
236 * @param {NodeList} nodes 273 * @param {NodeList} nodes
237 * @return {?string} 274 * @return {?string}
238 */ 275 */
239 SelectedFolderState.updateSelectedFolder = function( 276 SelectedFolderState.updateSelectedFolder = function(
240 selectedFolder, action, nodes) { 277 selectedFolder, action, nodes) {
241 // TODO(tsergeant): It should not be possible to select a non-folder.
242 // TODO(tsergeant): Select parent folder when selected folder is deleted.
243 switch (action.name) { 278 switch (action.name) {
244 case 'select-folder': 279 case 'select-folder':
280 // TODO(tsergeant): It should not be possible to select a non-folder.
245 return action.id; 281 return action.id;
246 case 'change-folder-open': 282 case 'change-folder-open':
247 // When hiding the selected folder by closing its ancestor, select 283 // When hiding the selected folder by closing its ancestor, select
248 // that ancestor instead. 284 // that ancestor instead.
249 if (!action.open && selectedFolder && 285 if (!action.open && selectedFolder &&
250 SelectedFolderState.isAncestorOf( 286 SelectedFolderState.isAncestorOf(
251 nodes, action.id, selectedFolder)) { 287 nodes, action.id, selectedFolder)) {
252 return action.id; 288 return action.id;
253 } 289 }
254 return selectedFolder; 290 return selectedFolder;
255 case 'finish-search': 291 case 'finish-search':
256 return null; 292 return null;
257 case 'clear-search': 293 case 'clear-search':
258 // TODO(tsergeant): Return to the folder that was selected before the 294 // TODO(tsergeant): Return to the folder that was selected before the
259 // search. 295 // search.
260 return nodes['0'].children[0]; 296 return nodes['0'].children[0];
297 case 'remove-bookmark':
298 // When deleting the selected folder (or its ancestor), select the
299 // parent of the deleted node.
300 if (selectedFolder &&
301 SelectedFolderState.isAncestorOf(nodes, action.id, selectedFolder))
302 return assert(nodes[action.id].parentId);
303 return selectedFolder;
261 default: 304 default:
262 return selectedFolder; 305 return selectedFolder;
263 } 306 }
264 }; 307 };
265 308
266 var ClosedFolderState = {}; 309 var ClosedFolderState = {};
267 310
268 /** 311 /**
269 * @param {ClosedFolderState} closedFolders 312 * @param {ClosedFolderState} closedFolders
270 * @param {string|undefined} id 313 * @param {string|undefined} id
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 return ClosedFolderState.changeFolderOpen(closedFolders, action); 354 return ClosedFolderState.changeFolderOpen(closedFolders, action);
312 case 'select-folder': 355 case 'select-folder':
313 return ClosedFolderState.openFolderAndAncestors( 356 return ClosedFolderState.openFolderAndAncestors(
314 closedFolders, nodes[action.id].parentId, nodes); 357 closedFolders, nodes[action.id].parentId, nodes);
315 case 'move-bookmark': 358 case 'move-bookmark':
316 if (!nodes[action.id].children) 359 if (!nodes[action.id].children)
317 return closedFolders; 360 return closedFolders;
318 361
319 return ClosedFolderState.openFolderAndAncestors( 362 return ClosedFolderState.openFolderAndAncestors(
320 closedFolders, action.parentId, nodes); 363 closedFolders, action.parentId, nodes);
364 case 'remove-bookmark':
365 return bookmarks.util.removeNodesFromMap(
366 closedFolders, action.descendants);
321 default: 367 default:
322 return closedFolders; 368 return closedFolders;
323 }; 369 };
324 }; 370 };
325 371
326 /** 372 /**
327 * Root reducer for the Bookmarks page. This is called by the store in 373 * Root reducer for the Bookmarks page. This is called by the store in
328 * response to an action, and the return value is used to update the UI. 374 * response to an action, and the return value is used to update the UI.
329 * @param {!BookmarksPageState} state 375 * @param {!BookmarksPageState} state
330 * @param {Action} action 376 * @param {Action} action
(...skipping 13 matching lines...) Expand all
344 390
345 return { 391 return {
346 reduceAction: reduceAction, 392 reduceAction: reduceAction,
347 ClosedFolderState: ClosedFolderState, 393 ClosedFolderState: ClosedFolderState,
348 NodeState: NodeState, 394 NodeState: NodeState,
349 SearchState: SearchState, 395 SearchState: SearchState,
350 SelectedFolderState: SelectedFolderState, 396 SelectedFolderState: SelectedFolderState,
351 SelectionState: SelectionState, 397 SelectionState: SelectionState,
352 }; 398 };
353 }); 399 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698