Chromium Code Reviews| 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: {}, | 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 }); |
| OLD | NEW |