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

Side by Side Diff: chrome/browser/resources/sync_internals/sync_node_browser.js

Issue 134443004: sync: Remove some WebUI debug functions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor cleanups Created 6 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // require: cr.js 5 // require: cr.js
6 // require: cr/ui.js 6 // require: cr/ui.js
7 // require: cr/ui/tree.js 7 // require: cr/ui/tree.js
8 8
9 cr.define('chrome.sync', function() { 9 (function() {
10 /** 10 /**
11 * Gets all children of the given node and passes it to the given 11 * A helper function to determine if a node is the root of its type.
12 * callback. 12 *
13 * @param {string} id The id whose children we want. 13 * @param {!Object} node The node to check.
14 * @param {function(Array.<!Object>)} callback The callback to call
15 * with the list of children summaries.
16 */ 14 */
17 function getSyncNodeChildrenSummaries(id, callback) { 15 var isTypeRootNode = function(node) {
18 var timer = chrome.sync.makeTimer(); 16 return node.PARENT_ID == 'r' && node.UNIQUE_SERVER_TAG != '';
19 chrome.sync.getChildNodeIds(id, function(childNodeIds) { 17 }
20 console.debug('getChildNodeIds took ' + 18
21 timer.elapsedSeconds + 's to retrieve ' + 19 /**
22 childNodeIds.length + ' ids'); 20 * A helper function to determine if a node is a child of the given parent.
23 timer = chrome.sync.makeTimer(); 21 *
24 chrome.sync.getNodeSummariesById( 22 * @param {string} parentId The ID of the parent.
25 childNodeIds, function(childrenSummaries) { 23 * @param {!Object} node The node to check.
26 console.debug('getNodeSummariesById took ' + 24 */
27 timer.elapsedSeconds + 's to retrieve summaries for ' + 25 var isChildOf = function(parentId, node) {
28 childrenSummaries.length + ' nodes'); 26 return node.PARENT_ID == parentId;
29 callback(childrenSummaries); 27 }
30 }); 28
31 }); 29 /**
30 * A helper function to sort sync nodes.
31 *
32 * Sorts by position index if possible, falls back to sorting by name, and
33 * finally sorting by METAHANDLE
Nicolas Zea 2014/01/13 20:10:14 Can the sorting not be done in the C++ code by hav
rlarocque 2014/01/13 21:56:17 That could work. I can see two reasons in favor o
Nicolas Zea 2014/01/14 22:14:33 Maybe just add a note that we can consider sorting
rlarocque 2014/01/14 22:20:43 Done.
34 */
35 var nodeComparator = function(nodeA, nodeB) {
36 if (nodeA.hasOwnProperty('positionIndex') &&
37 nodeB.hasOwnProperty('positionIndex')) {
38 return nodeA.positionIndex - nodeB.positionIndex;
39 } else if (nodeA.NON_UNIQUE_NAME != nodeB.NON_UNIQUE_NAME) {
40 return nodeA.NON_UNIQUE_NAME.localeCompare(nodeB.NON_UNIQUE_NAME);
41 } else {
42 return nodeA.METAHANDLE - nodeB.METAHANDLE;
43 }
44 }
45
46 /**
47 * Updates the node detail view with the details for the given node.
48 * @param {!Object} node The struct representing the node we want to display.
49 */
50 function updateNodeDetailView(node) {
51 var nodeDetailsView = $('node-details');
52 nodeDetailsView.hidden = false;
53 jstProcess(new JsEvalContext(node.entry_), nodeDetailsView);
54 }
55
56 /**
57 * Updates the 'Last refresh time' display.
58 * @param {string} The text to display.
59 */
60 function setLastRefreshTime(str) {
61 $('node-browser-refresh-time').textContent = str;
32 } 62 }
33 63
34 /** 64 /**
35 * Creates a new sync node tree item. 65 * Creates a new sync node tree item.
36 * @param {{id: string, title: string, isFolder: boolean}} 66 *
37 * nodeSummary The nodeSummary object for the node (as returned
38 * by chrome.sync.getNodeSummariesById()).
39 * @constructor 67 * @constructor
68 * @param {!Object} node The nodeDetails object for the node as returned by
69 * chrome.sync.getAllNodes().
40 * @extends {cr.ui.TreeItem} 70 * @extends {cr.ui.TreeItem}
41 */ 71 */
42 var SyncNodeTreeItem = function(nodeSummary) { 72 var SyncNodeTreeItem = function(node) {
43 var treeItem = new cr.ui.TreeItem({ 73 var treeItem = new cr.ui.TreeItem();
44 id_: nodeSummary.id
45 });
46 treeItem.__proto__ = SyncNodeTreeItem.prototype; 74 treeItem.__proto__ = SyncNodeTreeItem.prototype;
47 75
48 treeItem.label = nodeSummary.title; 76 treeItem.entry_ = node;
49 if (nodeSummary.isFolder) { 77 treeItem.label = node.NON_UNIQUE_NAME;
78 if (node.IS_DIR) {
50 treeItem.mayHaveChildren_ = true; 79 treeItem.mayHaveChildren_ = true;
51 80
52 // Load children asynchronously on expand. 81 // Load children on expand.
53 // TODO(akalin): Add a throbber while loading? 82 treeItem.expanded_ = false;
54 treeItem.triggeredLoad_ = false;
55 treeItem.addEventListener('expand', 83 treeItem.addEventListener('expand',
56 treeItem.handleExpand_.bind(treeItem)); 84 treeItem.handleExpand_.bind(treeItem));
57 } else { 85 } else {
58 treeItem.classList.add('leaf'); 86 treeItem.classList.add('leaf');
59 } 87 }
60 return treeItem; 88 return treeItem;
61 }; 89 };
62 90
63 SyncNodeTreeItem.prototype = { 91 SyncNodeTreeItem.prototype = {
64 __proto__: cr.ui.TreeItem.prototype, 92 __proto__: cr.ui.TreeItem.prototype,
65 93
66 /** 94 /**
67 * Retrieves the details for this node. 95 * Finds the children of this node and appends them to the tree.
68 * @param {function(Object)} callback The callback that will be
69 * called with the node details, or null if it could not be
70 * retrieved.
71 */ 96 */
72 getDetails: function(callback) { 97 handleExpand_: function(event) {
73 chrome.sync.getNodeDetailsById([this.id_], function(nodeDetails) { 98 var treeItem = this;
74 callback(nodeDetails[0] || null); 99
100 if (treeItem.expanded_) {
101 return;
102 }
103 treeItem.expanded_ = true;
104
105 var children = treeItem.tree.allNodes.filter(
106 isChildOf.bind(undefined, treeItem.entry_.ID));
107 children.sort(nodeComparator);
108
109 children.forEach(function(node) {
110 treeItem.add(new SyncNodeTreeItem(node));
75 }); 111 });
76 }, 112 },
77
78 handleExpand_: function(event) {
79 if (!this.triggeredLoad_) {
80 getSyncNodeChildrenSummaries(this.id_, this.addChildNodes_.bind(this));
81 this.triggeredLoad_ = true;
82 }
83 },
84
85 /**
86 * Adds children from the list of children summaries.
87 * @param {Array.<{id: string, title: string, isFolder: boolean}>}
88 * childrenSummaries The list of children summaries with which
89 * to create the child nodes.
90 */
91 addChildNodes_: function(childrenSummaries) {
92 var timer = chrome.sync.makeTimer();
93 for (var i = 0; i < childrenSummaries.length; ++i) {
94 var childTreeItem = new SyncNodeTreeItem(childrenSummaries[i]);
95 this.add(childTreeItem);
96 }
97 console.debug('adding ' + childrenSummaries.length +
98 ' children took ' + timer.elapsedSeconds + 's');
99 }
100 }; 113 };
101 114
102 /** 115 /**
103 * Updates the node detail view with the details for the given node. 116 * Creates a new sync node tree. Technically, it's a forest since it each
104 * @param {!Object} nodeDetails The details for the node we want 117 * type has its own root node for its own tree, but it still looks and acts
105 * to display. 118 * mostly like a tree.
106 */ 119 *
107 function updateNodeDetailView(nodeDetails) {
108 var nodeBrowser = document.getElementById('node-browser');
109 // TODO(akalin): Write a nicer detail viewer.
110 nodeDetails.entry = JSON.stringify(nodeDetails.entry, null, 2);
111 jstProcess(new JsEvalContext(nodeDetails), nodeBrowser);
112 }
113
114 /**
115 * Creates a new sync node tree.
116 * @param {Object=} opt_propertyBag Optional properties. 120 * @param {Object=} opt_propertyBag Optional properties.
117 * @constructor 121 * @constructor
118 * @extends {cr.ui.Tree} 122 * @extends {cr.ui.Tree}
119 */ 123 */
120 var SyncNodeTree = cr.ui.define('tree'); 124 var SyncNodeTree = cr.ui.define('tree');
121 125
122 SyncNodeTree.prototype = { 126 SyncNodeTree.prototype = {
123 __proto__: cr.ui.Tree.prototype, 127 __proto__: cr.ui.Tree.prototype,
124 128
125 decorate: function() { 129 decorate: function() {
126 cr.ui.Tree.prototype.decorate.call(this); 130 cr.ui.Tree.prototype.decorate.call(this);
127 this.addEventListener('change', this.handleChange_.bind(this)); 131 this.addEventListener('change', this.handleChange_.bind(this));
128 chrome.sync.getRootNodeDetails(this.makeRoot_.bind(this)); 132 this.allNodes = [];
129 }, 133 },
130 134
131 /** 135 populate: function(nodes) {
132 * Creates the root of the tree. 136 var tree = this;
133 * @param {{id: string, title: string, isFolder: boolean}} 137
134 * rootNodeSummary The summary info for the root node. 138 // We store the full set of nodes in the SyncNodeTree object.
135 */ 139 tree.allNodes = nodes;
136 makeRoot_: function(rootNodeSummary) { 140
137 // The root node usually doesn't have a title. 141 var roots = tree.allNodes.filter(isTypeRootNode);
138 rootNodeSummary.title = rootNodeSummary.title || 'Root'; 142 roots.sort(nodeComparator);
139 var rootTreeItem = new SyncNodeTreeItem(rootNodeSummary); 143
140 this.add(rootTreeItem); 144 roots.forEach(function(typeRoot) {
145 tree.add(new SyncNodeTreeItem(typeRoot));
146 });
141 }, 147 },
142 148
143 handleChange_: function(event) { 149 handleChange_: function(event) {
144 if (this.selectedItem) { 150 if (this.selectedItem) {
145 this.selectedItem.getDetails(updateNodeDetailView); 151 updateNodeDetailView(this.selectedItem);
146 } 152 }
147 } 153 }
148 }; 154 };
149 155
150 function decorateSyncNodeBrowser(syncNodeBrowser) { 156 /**
151 cr.ui.decorate(syncNodeBrowser, SyncNodeTree); 157 * Clears any existing UI state. Useful prior to a refresh.
158 */
159 function clear() {
160 var treeContainer = $('sync-node-tree-container');
161 while (treeContainer.firstChild) {
162 treeContainer.removeChild(treeContainer.firstChild);
163 }
164
165 var nodeDetailsView = $('node-details');
166 nodeDetailsView.hidden = true;
152 } 167 }
153 168
154 // This is needed because JsTemplate (which is needed by 169 /**
155 // updateNodeDetailView) is loaded at the end of the file after 170 * Fetch the latest set of nodes and refresh the UI.
156 // everything else. 171 */
157 // 172 function refresh() {
158 // TODO(akalin): Remove dependency on JsTemplate and get rid of 173 $('node-browser-refresh-button').disabled = true;
159 // this. 174
160 var domLoaded = false; 175 clear();
161 var pendingSyncNodeBrowsers = []; 176 setLastRefreshTime('In progress since ' + (new Date()).toLocaleString());
162 function decorateSyncNodeBrowserAfterDOMLoad(id) { 177
163 var e = document.getElementById(id); 178 chrome.sync.getAllNodes(function(nodes) {
164 if (domLoaded) { 179 var treeContainer = $('sync-node-tree-container');
165 decorateSyncNodeBrowser(e); 180 var tree = document.createElement('tree');
166 } else { 181 tree.setAttribute('id', 'sync-node-tree');
167 pendingSyncNodeBrowsers.push(e); 182 tree.setAttribute('icon-visibility', 'parent');
168 } 183 treeContainer.appendChild(tree);
184
185 cr.ui.decorate(tree, SyncNodeTree);
186 tree.populate(nodes);
187
188 setLastRefreshTime((new Date()).toLocaleString());
189 $('node-browser-refresh-button').disabled = false;
190 });
169 } 191 }
170 192
171 document.addEventListener('DOMContentLoaded', function() { 193 document.addEventListener('DOMContentLoaded', function(e) {
172 for (var i = 0; i < pendingSyncNodeBrowsers.length; ++i) { 194 $('node-browser-refresh-button').addEventListener('click', refresh);
173 decorateSyncNodeBrowser(pendingSyncNodeBrowsers[i]); 195 cr.ui.decorate('#sync-node-splitter', cr.ui.Splitter);
174 } 196
175 domLoaded = true; 197 // Automatically trigger a refresh the first time this tab is selected.
198 $('sync-browser-tab').addEventListener('selectedChange', function f(e) {
199 if (this.selected) {
200 $('sync-browser-tab').removeEventListener('selectedChange', f);
201 refresh();
202 }
203 });
176 }); 204 });
177 205
178 return { 206 })();
179 decorateSyncNodeBrowser: decorateSyncNodeBrowserAfterDOMLoad
180 };
181 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698