| 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 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 }); |
| OLD | NEW |