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 */ |
| 11 | 11 |
| 12 cr.define('bookmarks', function() { | 12 cr.define('bookmarks', function() { |
| 13 var NodeState = {}; | |
| 14 | |
| 15 /** | |
| 16 * @param {NodeList} nodes | |
| 17 * @param {string} id | |
| 18 * @param {function(BookmarkNode):BookmarkNode} callback | |
| 19 * @return {NodeList} | |
| 20 */ | |
| 21 NodeState.modifyNode_ = function(nodes, id, callback) { | |
| 22 var nodeModification = {}; | |
| 23 nodeModification[id] = callback(nodes[id]); | |
| 24 return Object.assign({}, nodes, nodeModification); | |
|
calamity
2017/03/07 07:27:35
How does closure understand this?
tsergeant
2017/03/08 02:47:10
I would guess that here Closure sees that Object.a
| |
| 25 }; | |
| 26 | |
| 27 /** | |
| 28 * @param {NodeList} nodes | |
| 29 * @param {Action} action | |
| 30 * @return {NodeList} | |
| 31 */ | |
| 32 NodeState.editBookmark = function(nodes, action) { | |
| 33 return NodeState.modifyNode_(nodes, action.id, function(node) { | |
| 34 return /** @type {BookmarkNode} */ ( | |
| 35 Object.assign({}, node, action.changeInfo)); | |
|
calamity
2017/03/07 07:27:35
While it doesn't understand this.
tsergeant
2017/03/08 02:47:10
But here, it isn't able to convert Object to the s
calamity
2017/03/08 06:57:19
Ech.
| |
| 36 }); | |
| 37 }; | |
| 38 | |
| 39 /** | |
| 40 * @param {NodeList} nodes | |
| 41 * @param {Action} action | |
| 42 * @return {NodeList} | |
| 43 */ | |
| 44 NodeState.removeBookmark = function(nodes, action) { | |
| 45 return NodeState.modifyNode_(nodes, action.parentId, function(node) { | |
| 46 var newChildren = node.children.slice(); | |
| 47 newChildren.splice(action.index, 1); | |
| 48 return /** @type {BookmarkNode} */ ( | |
| 49 Object.assign({}, node, {children: newChildren})); | |
| 50 }); | |
| 51 }; | |
| 52 | |
| 53 /** | |
| 54 * @param {NodeList} nodes | |
| 55 * @param {Action} action | |
| 56 * @return {NodeList} | |
| 57 */ | |
| 58 NodeState.updateNodes = function(nodes, action) { | |
| 59 switch (action.name) { | |
| 60 case 'edit-bookmark': | |
| 61 return NodeState.editBookmark(nodes, action); | |
| 62 case 'remove-bookmark': | |
| 63 return NodeState.removeBookmark(nodes, action); | |
| 64 case 'refresh-nodes': | |
| 65 return action.nodes; | |
| 66 default: | |
| 67 return nodes; | |
| 68 } | |
| 69 }; | |
| 70 | |
| 71 var SelectedFolderState = {}; | |
| 72 | |
| 73 /** | |
| 74 * @param {NodeList} nodes | |
| 75 * @param {string} ancestorId | |
| 76 * @param {string} childId | |
| 77 * @return {boolean} | |
| 78 */ | |
| 79 SelectedFolderState.isAncestorOf = function(nodes, ancestorId, childId) { | |
| 80 var currentId = childId; | |
| 81 // Work upwards through the tree from child. | |
| 82 while (currentId) { | |
| 83 if (currentId == ancestorId) | |
| 84 return true; | |
| 85 currentId = nodes[currentId].parentId; | |
| 86 } | |
| 87 return false; | |
| 88 }; | |
| 89 | |
| 90 /** | |
| 91 * @param {?string} selectedFolder | |
| 92 * @param {Action} action | |
| 93 * @param {NodeList} nodes | |
| 94 * @return {?string} | |
| 95 */ | |
| 96 SelectedFolderState.updateSelectedFolder = function( | |
| 97 selectedFolder, action, nodes) { | |
| 98 // TODO(tsergeant): It should not be possible to select a non-folder. | |
|
calamity
2017/03/07 07:27:35
What's the plan for this TODO? Are you just going
tsergeant
2017/03/08 02:47:10
I think that if you try to select a folder that ei
calamity
2017/03/08 06:57:19
I'd prefer throwing an exception over failing sile
tsergeant
2017/03/08 23:17:53
Yeah, maybe. I have a feeling we want to avoid ass
| |
| 99 switch (action.name) { | |
| 100 case 'select-folder': | |
| 101 return action.id; | |
| 102 case 'change-folder-open': | |
| 103 // When hiding the selected folder by closing its ancestor, select | |
| 104 // that ancestor instead. | |
| 105 if (!action.open && selectedFolder && | |
| 106 SelectedFolderState.isAncestorOf( | |
| 107 nodes, action.id, selectedFolder)) { | |
| 108 return action.id; | |
| 109 } | |
| 110 return selectedFolder; | |
| 111 default: | |
| 112 return selectedFolder; | |
| 113 } | |
| 114 }; | |
| 115 | |
| 116 var ClosedFolderState = {}; | |
| 117 | |
| 118 /** | |
| 119 * @param {ClosedFolderState} state | |
| 120 * @param {Action} action | |
| 121 * @param {NodeList} nodes | |
| 122 * @return {ClosedFolderState} | |
| 123 */ | |
| 124 ClosedFolderState.openAncestorsOf = function(state, action, nodes) { | |
| 125 var id = action.id; | |
| 126 var modifications = {}; | |
| 127 var parentId = nodes[id].parentId; | |
| 128 while (parentId) { | |
| 129 if (state[parentId]) { | |
| 130 modifications[parentId] = false; | |
| 131 } | |
| 132 parentId = nodes[parentId].parentId; | |
| 133 } | |
| 134 | |
| 135 return Object.assign({}, state, modifications); | |
| 136 }; | |
| 137 | |
| 138 /** | |
| 139 * @param {ClosedFolderState} state | |
| 140 * @param {Action} action | |
| 141 * @return {ClosedFolderState} | |
| 142 */ | |
| 143 ClosedFolderState.toggleFolderOpen = function(state, action) { | |
| 144 var id = action.id; | |
|
calamity
2017/03/07 07:27:35
nit: This var seems superfluous.
tsergeant
2017/03/08 02:47:10
Done.
| |
| 145 var closed = !action.open; | |
| 146 var modification = {}; | |
| 147 modification[id] = closed; | |
| 148 | |
| 149 return Object.assign({}, state, modification); | |
| 150 }; | |
| 151 | |
| 152 /** | |
| 153 * @param {ClosedFolderState} state | |
| 154 * @param {Action} action | |
| 155 * @param {NodeList} nodes | |
| 156 * @return {ClosedFolderState} | |
| 157 */ | |
| 158 ClosedFolderState.updateClosedFolders = function(state, action, nodes) { | |
| 159 switch (action.name) { | |
| 160 case 'change-folder-open': | |
| 161 return ClosedFolderState.toggleFolderOpen(state, action); | |
| 162 case 'select-folder': | |
| 163 return ClosedFolderState.openAncestorsOf(state, action, nodes); | |
| 164 default: | |
| 165 return state; | |
| 166 }; | |
| 167 }; | |
| 168 | |
| 13 /** | 169 /** |
| 14 * Root reducer for the Bookmarks page. This is called by the store in | 170 * Root reducer for the Bookmarks page. This is called by the store in |
| 15 * response to an action, and the return value is used to update the UI. | 171 * response to an action, and the return value is used to update the UI. |
| 16 * @param {!BookmarksPageState} state | 172 * @param {!BookmarksPageState} state |
| 17 * @param {Action} action | 173 * @param {Action} action |
| 18 * @return {!BookmarksPageState} | 174 * @return {!BookmarksPageState} |
| 19 */ | 175 */ |
| 20 function reduceAction(state, action) { | 176 function reduceAction(state, action) { |
| 21 return {}; | 177 return { |
| 178 nodes: NodeState.updateNodes(state.nodes, action), | |
| 179 selectedFolder: SelectedFolderState.updateSelectedFolder( | |
| 180 state.selectedFolder, action, state.nodes), | |
| 181 closedFolders: ClosedFolderState.updateClosedFolders( | |
| 182 state.closedFolders, action, state.nodes), | |
| 183 }; | |
| 22 } | 184 } |
| 23 | 185 |
| 24 return { | 186 return { |
| 25 reduceAction: reduceAction, | 187 reduceAction: reduceAction, |
| 188 ClosedFolderState: ClosedFolderState, | |
| 189 NodeState: NodeState, | |
| 190 SelectedFolderState: SelectedFolderState, | |
| 26 }; | 191 }; |
| 27 }); | 192 }); |
| OLD | NEW |