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

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, 8 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: new Set(), 41 items: new Set(),
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.removeIdsFromSet(selectionState.items, deleted),
54 anchor: null,
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 case 'deselect-items': 68 case 'deselect-items':
57 return SelectionState.deselectAll(selection); 69 return SelectionState.deselectAll(selection);
58 case 'select-items': 70 case 'select-items':
59 return SelectionState.selectItems(selection, action); 71 return SelectionState.selectItems(selection, action);
72 case 'remove-bookmark':
73 return SelectionState.deselectDeletedItems(
74 selection, action.descendants);
75 default:
76 return selection;
60 } 77 }
61 return selection;
62 }; 78 };
63 79
64 var SearchState = {}; 80 var SearchState = {};
65 81
66 /** 82 /**
67 * @param {SearchState} search 83 * @param {SearchState} search
68 * @param {Action} action 84 * @param {Action} action
69 * @return {SearchState} 85 * @return {SearchState}
70 */ 86 */
71 SearchState.startSearch = function(search, action) { 87 SearchState.startSearch = function(search, action) {
(...skipping 20 matching lines...) Expand all
92 SearchState.clearSearch = function() { 108 SearchState.clearSearch = function() {
93 return { 109 return {
94 term: '', 110 term: '',
95 inProgress: false, 111 inProgress: false,
96 results: [], 112 results: [],
97 }; 113 };
98 }; 114 };
99 115
100 /** 116 /**
101 * @param {SearchState} search 117 * @param {SearchState} search
118 * @param {!Set<string>} deletedIds
119 * @return {SearchState}
120 */
121 SearchState.removeDeletedResults = function(search, deletedIds) {
122 var newResults = [];
123 search.results.forEach(function(id) {
124 if (!deletedIds.has(id))
125 newResults.push(id);
126 });
127 return /** @type {SearchState} */ (Object.assign({}, search, {
128 results: newResults,
129 }));
130 };
131
132 /**
133 * @param {SearchState} search
102 * @param {Action} action 134 * @param {Action} action
103 * @return {SearchState} 135 * @return {SearchState}
104 */ 136 */
105 SearchState.updateSearch = function(search, action) { 137 SearchState.updateSearch = function(search, action) {
106 switch (action.name) { 138 switch (action.name) {
107 case 'start-search': 139 case 'start-search':
108 return SearchState.startSearch(search, action); 140 return SearchState.startSearch(search, action);
109 case 'select-folder': 141 case 'select-folder':
110 case 'clear-search': 142 case 'clear-search':
111 return SearchState.clearSearch(); 143 return SearchState.clearSearch();
112 case 'finish-search': 144 case 'finish-search':
113 return SearchState.finishSearch(search, action); 145 return SearchState.finishSearch(search, action);
146 case 'remove-bookmark':
147 return SearchState.removeDeletedResults(search, action.descendants);
114 default: 148 default:
115 return search; 149 return search;
116 } 150 }
117 }; 151 };
118 152
119 var NodeState = {}; 153 var NodeState = {};
120 154
121 /** 155 /**
122 * @param {NodeList} nodes 156 * @param {NodeList} nodes
123 * @param {string} id 157 * @param {string} id
(...skipping 21 matching lines...) Expand all
145 Object.assign({}, node, action.changeInfo)); 179 Object.assign({}, node, action.changeInfo));
146 }); 180 });
147 }; 181 };
148 182
149 /** 183 /**
150 * @param {NodeList} nodes 184 * @param {NodeList} nodes
151 * @param {Action} action 185 * @param {Action} action
152 * @return {NodeList} 186 * @return {NodeList}
153 */ 187 */
154 NodeState.removeBookmark = function(nodes, action) { 188 NodeState.removeBookmark = function(nodes, action) {
155 return NodeState.modifyNode_(nodes, action.parentId, function(node) { 189 var newState =
156 var newChildren = node.children.slice(); 190 NodeState.modifyNode_(nodes, action.parentId, function(node) {
157 newChildren.splice(action.index, 1); 191 var newChildren = node.children.slice();
158 return /** @type {BookmarkNode} */ ( 192 newChildren.splice(action.index, 1);
159 Object.assign({}, node, {children: newChildren})); 193 return /** @type {BookmarkNode} */ (
160 }); 194 Object.assign({}, node, {children: newChildren}));
195 });
196
197 return bookmarks.util.removeIdsFromMap(newState, action.descendants);
161 }; 198 };
162 199
163 /** 200 /**
164 * @param {NodeList} nodes 201 * @param {NodeList} nodes
165 * @param {Action} action 202 * @param {Action} action
166 * @return {NodeList} 203 * @return {NodeList}
167 */ 204 */
168 NodeState.moveBookmark = function(nodes, action) { 205 NodeState.moveBookmark = function(nodes, action) {
169 var nodeModifications = {}; 206 var nodeModifications = {};
170 var id = action.id; 207 var id = action.id;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 }; 269 };
233 270
234 /** 271 /**
235 * @param {?string} selectedFolder 272 * @param {?string} selectedFolder
236 * @param {Action} action 273 * @param {Action} action
237 * @param {NodeList} nodes 274 * @param {NodeList} nodes
238 * @return {?string} 275 * @return {?string}
239 */ 276 */
240 SelectedFolderState.updateSelectedFolder = function( 277 SelectedFolderState.updateSelectedFolder = function(
241 selectedFolder, action, nodes) { 278 selectedFolder, action, nodes) {
242 // TODO(tsergeant): It should not be possible to select a non-folder.
243 // TODO(tsergeant): Select parent folder when selected folder is deleted.
244 switch (action.name) { 279 switch (action.name) {
245 case 'select-folder': 280 case 'select-folder':
281 // TODO(tsergeant): It should not be possible to select a non-folder.
246 return action.id; 282 return action.id;
247 case 'change-folder-open': 283 case 'change-folder-open':
248 // When hiding the selected folder by closing its ancestor, select 284 // When hiding the selected folder by closing its ancestor, select
249 // that ancestor instead. 285 // that ancestor instead.
250 if (!action.open && selectedFolder && 286 if (!action.open && selectedFolder &&
251 SelectedFolderState.isAncestorOf( 287 SelectedFolderState.isAncestorOf(
252 nodes, action.id, selectedFolder)) { 288 nodes, action.id, selectedFolder)) {
253 return action.id; 289 return action.id;
254 } 290 }
255 return selectedFolder; 291 return selectedFolder;
256 case 'finish-search': 292 case 'finish-search':
257 return null; 293 return null;
258 case 'clear-search': 294 case 'clear-search':
259 // TODO(tsergeant): Return to the folder that was selected before the 295 // TODO(tsergeant): Return to the folder that was selected before the
260 // search. 296 // search.
261 return nodes[ROOT_NODE_ID].children[0]; 297 return nodes[ROOT_NODE_ID].children[0];
298 case 'remove-bookmark':
299 // When deleting the selected folder (or its ancestor), select the
300 // parent of the deleted node.
301 if (selectedFolder &&
302 SelectedFolderState.isAncestorOf(nodes, action.id, selectedFolder))
303 return assert(nodes[action.id].parentId);
304 return selectedFolder;
262 default: 305 default:
263 return selectedFolder; 306 return selectedFolder;
264 } 307 }
265 }; 308 };
266 309
267 var ClosedFolderState = {}; 310 var ClosedFolderState = {};
268 311
269 /** 312 /**
270 * @param {ClosedFolderState} closedFolders 313 * @param {ClosedFolderState} closedFolders
271 * @param {string|undefined} id 314 * @param {string|undefined} id
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 return ClosedFolderState.changeFolderOpen(closedFolders, action); 358 return ClosedFolderState.changeFolderOpen(closedFolders, action);
316 case 'select-folder': 359 case 'select-folder':
317 return ClosedFolderState.openFolderAndAncestors( 360 return ClosedFolderState.openFolderAndAncestors(
318 closedFolders, nodes[action.id].parentId, nodes); 361 closedFolders, nodes[action.id].parentId, nodes);
319 case 'move-bookmark': 362 case 'move-bookmark':
320 if (!nodes[action.id].children) 363 if (!nodes[action.id].children)
321 return closedFolders; 364 return closedFolders;
322 365
323 return ClosedFolderState.openFolderAndAncestors( 366 return ClosedFolderState.openFolderAndAncestors(
324 closedFolders, action.parentId, nodes); 367 closedFolders, action.parentId, nodes);
368 case 'remove-bookmark':
369 return bookmarks.util.removeIdsFromSet(
370 closedFolders, action.descendants);
325 default: 371 default:
326 return closedFolders; 372 return closedFolders;
327 }; 373 };
328 }; 374 };
329 375
330 /** 376 /**
331 * Root reducer for the Bookmarks page. This is called by the store in 377 * Root reducer for the Bookmarks page. This is called by the store in
332 * response to an action, and the return value is used to update the UI. 378 * response to an action, and the return value is used to update the UI.
333 * @param {!BookmarksPageState} state 379 * @param {!BookmarksPageState} state
334 * @param {Action} action 380 * @param {Action} action
(...skipping 13 matching lines...) Expand all
348 394
349 return { 395 return {
350 reduceAction: reduceAction, 396 reduceAction: reduceAction,
351 ClosedFolderState: ClosedFolderState, 397 ClosedFolderState: ClosedFolderState,
352 NodeState: NodeState, 398 NodeState: NodeState,
353 SearchState: SearchState, 399 SearchState: SearchState,
354 SelectedFolderState: SelectedFolderState, 400 SelectedFolderState: SelectedFolderState,
355 SelectionState: SelectionState, 401 SelectionState: SelectionState,
356 }; 402 };
357 }); 403 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/md_bookmarks/api_listener.js ('k') | chrome/browser/resources/md_bookmarks/store_client.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698