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

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

Issue 2722083002: [MD Bookmarks] Flatten sidebar. (Closed)
Patch Set: 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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 return selectedFolder; 214 return selectedFolder;
215 case 'finish-search': 215 case 'finish-search':
216 return null; 216 return null;
217 case 'clear-search': 217 case 'clear-search':
218 return nodes['0'].children[0]; 218 return nodes['0'].children[0];
219 default: 219 default:
220 return selectedFolder; 220 return selectedFolder;
221 } 221 }
222 }; 222 };
223 223
224 var ClosedFolderState = {}; 224 var SidebarState = {};
225 225
226 /** 226 /**
227 * @param {ClosedFolderState} state 227 * Returns the modifications for |folders| needed to show or hide all nodes
228 * @param {Action} action 228 * beneath |nodeId| that are not beneath a closed folder.
229 * @param {NodeList} nodes 229 * @param {!Array<SidebarFolder>} folders
230 * @return {ClosedFolderState} 230 * @param {number} nodeIdx
231 * @param {boolean} open
232 * @return {!Array<SidebarFolder>}
231 */ 233 */
232 ClosedFolderState.openAncestorsOf = function(state, action, nodes) { 234 SidebarState.updateVisibleFoldersBelowNode = function(
233 var id = action.id; 235 folders, nodeIdx, open) {
236 var node = Object.assign({}, folders[nodeIdx]);
237 node.open = open;
238
239 if (!node.visible)
240 return {};
241
234 var modifications = {}; 242 var modifications = {};
235 var parentId = nodes[id].parentId; 243 var stack = [{node: node, showing: node.visible}];
236 while (parentId) { 244 for (var i = nodeIdx + 1; i < folders.length; i++) {
237 if (state[parentId]) { 245 var n = folders[i];
238 modifications[parentId] = false; 246
239 } 247 // Pop off nodes deeper than the current node.
240 parentId = nodes[parentId].parentId; 248 while (stack.length && n.depth <= stack[stack.length - 1].node.depth)
249 stack.pop();
250
251 if (!stack.length)
252 break;
253
254 var parent = stack[stack.length - 1];
255 var visible = parent.node.open && parent.showing;
256
257 // Add modification if desired visibility is not the current visibility.
258 if (visible != n.visible)
259 modifications[i] = Object.assign({}, n, {visible: visible});
260
261 // Add node to stack if it's deeper than the current node.
262 if (n.depth > parent.node.depth)
263 stack.push({node: n, showing: visible});
241 } 264 }
242 265
243 return Object.assign({}, state, modifications); 266 return modifications;
244 }; 267 };
245 268
246 /** 269 /**
247 * @param {ClosedFolderState} state 270 * @param {SidebarState} state
248 * @param {Action} action 271 * @param {Action} action
249 * @return {ClosedFolderState} 272 * @return {SidebarState}
250 */ 273 */
251 ClosedFolderState.toggleFolderOpen = function(state, action) { 274 SidebarState.changeFolderOpen = function(state, action) {
252 var id = action.id; 275 var newFolders = state.folders.slice();
253 var closed = !action.open; 276 var idx = state.folderMap[action.id];
254 var modification = {}; 277 var folder = newFolders[idx];
255 modification[id] = closed; 278 if (folder.open == action.open)
279 return state;
256 280
257 return Object.assign({}, state, modification); 281 newFolders[idx] = /** @type {SidebarFolder} */ (
282 Object.assign({}, folder, {open: action.open}));
283 newFolders = /** @type {!Array<SidebarFolder>} */ (Object.assign(
284 newFolders,
285 this.updateVisibleFoldersBelowNode(state.folders, idx, action.open)));
286 return /** @type {SidebarState} */ (
287 Object.assign({}, state, {folders: newFolders}));
258 }; 288 };
259 289
260 /** 290 /**
261 * @param {ClosedFolderState} state 291 * @param {SidebarState} state
262 * @param {Action} action 292 * @param {Action} action
263 * @param {NodeList} nodes 293 * @param {NodeList} nodes
264 * @return {ClosedFolderState} 294 * @return {SidebarState}
265 */ 295 */
266 ClosedFolderState.updateClosedFolders = function(state, action, nodes) { 296 SidebarState.openAncestorsOf = function(state, action, nodes) {
297 var id = action.id;
298 var newState = state;
299 var parentId = nodes[id].parentId || '';
300 while (nodes[parentId] && nodes[parentId].parentId) {
301 newState = this.changeFolderOpen(
302 newState, bookmarks.actions.changeFolderOpen(parentId, true));
303 parentId = nodes[parentId].parentId || '';
304 }
305
306 return newState;
307 };
308
309 /**
310 * @param {SidebarState} state
311 * @param {Action} action
312 * @return {SidebarState}
313 */
314 SidebarState.removeBookmark = function(state, action) {
315 var newFolders = state.folders.slice();
316
317 for (var i = 0; i < newFolders.length; i++) {
318 if (action.id != newFolders[i].id)
319 continue;
320
321 newFolders.splice(i, 1);
322 }
323
324 return /** @type {SidebarState} */ (Object.assign({}, state, {
325 folders: newFolders,
326 folderMap: bookmarks.util.createFolderMap(newFolders),
327 }));
328 };
329
330 /**
331 * @param {SidebarState} state
332 * @param {Action} action
333 * @param {NodeList} nodes
334 * @return {SidebarState}
335 */
336 SidebarState.updateSidebar = function(state, action, nodes) {
267 switch (action.name) { 337 switch (action.name) {
338 case 'remove-bookmark':
339 return this.removeBookmark(state, action);
268 case 'change-folder-open': 340 case 'change-folder-open':
269 return ClosedFolderState.toggleFolderOpen(state, action); 341 return this.changeFolderOpen(state, action);
270 case 'select-folder': 342 case 'select-folder':
271 return ClosedFolderState.openAncestorsOf(state, action, nodes); 343 return this.openAncestorsOf(state, action, nodes);
272 default: 344 default:
273 return state; 345 return state;
274 }; 346 };
275 }; 347 };
276 348
277 /** 349 /**
278 * Root reducer for the Bookmarks page. This is called by the store in 350 * Root reducer for the Bookmarks page. This is called by the store in
279 * response to an action, and the return value is used to update the UI. 351 * response to an action, and the return value is used to update the UI.
280 * @param {BookmarksPageState} state 352 * @param {BookmarksPageState} state
281 * @param {Action} action 353 * @param {Action} action
282 * @return {BookmarksPageState} 354 * @return {BookmarksPageState}
283 */ 355 */
284 function reduceAction(state, action) { 356 function reduceAction(state, action) {
285 return { 357 return {
286 nodes: NodeState.updateNodes(state.nodes, action), 358 nodes: NodeState.updateNodes(state.nodes, action),
359 search: SearchState.updateSearch(state.search, action),
287 selectedFolder: SelectedFolderState.updateSelectedFolder( 360 selectedFolder: SelectedFolderState.updateSelectedFolder(
288 state.selectedFolder, action, state.nodes), 361 state.selectedFolder, action, state.nodes),
289 closedFolders: ClosedFolderState.updateClosedFolders(
290 state.closedFolders, action, state.nodes),
291 search: SearchState.updateSearch(state.search, action),
292 selection: SelectionState.updateSelection(state.selection, action), 362 selection: SelectionState.updateSelection(state.selection, action),
363 sidebar: SidebarState.updateSidebar(state.sidebar, action, state.nodes),
293 }; 364 };
294 } 365 }
295 366
296 return { 367 return {
297 reduceAction: reduceAction, 368 reduceAction: reduceAction,
298 ClosedFolderState: ClosedFolderState,
299 NodeState: NodeState, 369 NodeState: NodeState,
300 SearchState: SearchState, 370 SearchState: SearchState,
301 SelectedFolderState: SelectedFolderState, 371 SelectedFolderState: SelectedFolderState,
302 SelectionState: SelectionState, 372 SelectionState: SelectionState,
373 SidebarState: SidebarState,
303 }; 374 };
304 }); 375 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/md_bookmarks/folder_node.js ('k') | chrome/browser/resources/md_bookmarks/sidebar.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698