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

Side by Side Diff: components/sync_driver/resources/sync_node_browser.js

Issue 2203673002: [Sync] Move //components/sync_driver to //components/sync/driver. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@sd-a
Patch Set: Full change rebased on static lib. Created 4 years, 4 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
(Empty)
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
3 // found in the LICENSE file.
4
5 // require: cr.js
6 // require: cr/ui.js
7 // require: cr/ui/tree.js
8
9 (function() {
10 /**
11 * A helper function to determine if a node is the root of its type.
12 *
13 * @param {!Object} node The node to check.
14 */
15 var isTypeRootNode = function(node) {
16 return node.PARENT_ID == 'r' && node.UNIQUE_SERVER_TAG != '';
17 };
18
19 /**
20 * A helper function to determine if a node is a child of the given parent.
21 *
22 * @param {!Object} parent node.
23 * @param {!Object} node The node to check.
24 */
25 var isChildOf = function(parentNode, node) {
26 if (node.PARENT_ID != '') {
27 return node.PARENT_ID == parentNode.ID;
28 }
29 else {
30 return node.modelType == parentNode.modelType;
31 }
32 };
33
34 /**
35 * A helper function to sort sync nodes.
36 *
37 * Sorts by position index if possible, falls back to sorting by name, and
38 * finally sorting by METAHANDLE.
39 *
40 * If this proves to be slow and expensive, we should experiment with moving
41 * this functionality to C++ instead.
42 */
43 var nodeComparator = function(nodeA, nodeB) {
44 if (nodeA.hasOwnProperty('positionIndex') &&
45 nodeB.hasOwnProperty('positionIndex')) {
46 return nodeA.positionIndex - nodeB.positionIndex;
47 } else if (nodeA.NON_UNIQUE_NAME != nodeB.NON_UNIQUE_NAME) {
48 return nodeA.NON_UNIQUE_NAME.localeCompare(nodeB.NON_UNIQUE_NAME);
49 } else {
50 return nodeA.METAHANDLE - nodeB.METAHANDLE;
51 }
52 };
53
54 /**
55 * Updates the node detail view with the details for the given node.
56 * @param {!Object} node The struct representing the node we want to display.
57 */
58 function updateNodeDetailView(node) {
59 var nodeDetailsView = $('node-details');
60 nodeDetailsView.hidden = false;
61 jstProcess(new JsEvalContext(node.entry_), nodeDetailsView);
62 }
63
64 /**
65 * Updates the 'Last refresh time' display.
66 * @param {string} The text to display.
67 */
68 function setLastRefreshTime(str) {
69 $('node-browser-refresh-time').textContent = str;
70 }
71
72 /**
73 * Creates a new sync node tree item.
74 *
75 * @constructor
76 * @param {!Object} node The nodeDetails object for the node as returned by
77 * chrome.sync.getAllNodes().
78 * @extends {cr.ui.TreeItem}
79 */
80 var SyncNodeTreeItem = function(node) {
81 var treeItem = new cr.ui.TreeItem();
82 treeItem.__proto__ = SyncNodeTreeItem.prototype;
83
84 treeItem.entry_ = node;
85 treeItem.label = node.NON_UNIQUE_NAME;
86 if (node.IS_DIR) {
87 treeItem.mayHaveChildren_ = true;
88
89 // Load children on expand.
90 treeItem.expanded_ = false;
91 treeItem.addEventListener('expand',
92 treeItem.handleExpand_.bind(treeItem));
93 } else {
94 treeItem.classList.add('leaf');
95 }
96 return treeItem;
97 };
98
99 SyncNodeTreeItem.prototype = {
100 __proto__: cr.ui.TreeItem.prototype,
101
102 /**
103 * Finds the children of this node and appends them to the tree.
104 */
105 handleExpand_: function(event) {
106 var treeItem = this;
107
108 if (treeItem.expanded_) {
109 return;
110 }
111 treeItem.expanded_ = true;
112
113 var children = treeItem.tree.allNodes.filter(
114 isChildOf.bind(undefined, treeItem.entry_));
115 children.sort(nodeComparator);
116
117 children.forEach(function(node) {
118 treeItem.add(new SyncNodeTreeItem(node));
119 });
120 },
121 };
122
123 /**
124 * Creates a new sync node tree. Technically, it's a forest since it each
125 * type has its own root node for its own tree, but it still looks and acts
126 * mostly like a tree.
127 *
128 * @param {Object=} opt_propertyBag Optional properties.
129 * @constructor
130 * @extends {cr.ui.Tree}
131 */
132 var SyncNodeTree = cr.ui.define('tree');
133
134 SyncNodeTree.prototype = {
135 __proto__: cr.ui.Tree.prototype,
136
137 decorate: function() {
138 cr.ui.Tree.prototype.decorate.call(this);
139 this.addEventListener('change', this.handleChange_.bind(this));
140 this.allNodes = [];
141 },
142
143 populate: function(nodes) {
144 var tree = this;
145
146 // We store the full set of nodes in the SyncNodeTree object.
147 tree.allNodes = nodes;
148
149 var roots = tree.allNodes.filter(isTypeRootNode);
150 roots.sort(nodeComparator);
151
152 roots.forEach(function(typeRoot) {
153 tree.add(new SyncNodeTreeItem(typeRoot));
154 });
155 },
156
157 handleChange_: function(event) {
158 if (this.selectedItem) {
159 updateNodeDetailView(this.selectedItem);
160 }
161 }
162 };
163
164 /**
165 * Clears any existing UI state. Useful prior to a refresh.
166 */
167 function clear() {
168 var treeContainer = $('sync-node-tree-container');
169 while (treeContainer.firstChild) {
170 treeContainer.removeChild(treeContainer.firstChild);
171 }
172
173 var nodeDetailsView = $('node-details');
174 nodeDetailsView.hidden = true;
175 }
176
177 /**
178 * Fetch the latest set of nodes and refresh the UI.
179 */
180 function refresh() {
181 $('node-browser-refresh-button').disabled = true;
182
183 clear();
184 setLastRefreshTime('In progress since ' + (new Date()).toLocaleString());
185
186 chrome.sync.getAllNodes(function(nodeMap) {
187 // Put all nodes into one big list that ignores the type.
188 var nodes = nodeMap.
189 map(function(x) { return x.nodes; }).
190 reduce(function(a, b) { return a.concat(b); });
191
192 var treeContainer = $('sync-node-tree-container');
193 var tree = document.createElement('tree');
194 tree.setAttribute('id', 'sync-node-tree');
195 tree.setAttribute('icon-visibility', 'parent');
196 treeContainer.appendChild(tree);
197
198 cr.ui.decorate(tree, SyncNodeTree);
199 tree.populate(nodes);
200
201 setLastRefreshTime((new Date()).toLocaleString());
202 $('node-browser-refresh-button').disabled = false;
203 });
204 }
205
206 document.addEventListener('DOMContentLoaded', function(e) {
207 $('node-browser-refresh-button').addEventListener('click', refresh);
208 var Splitter = cr.ui.Splitter;
209 var customSplitter = cr.ui.define('div');
210
211 customSplitter.prototype = {
212 __proto__: Splitter.prototype,
213
214 handleSplitterDragEnd: function(e) {
215 Splitter.prototype.handleSplitterDragEnd.apply(this, arguments);
216 var treeElement = $("sync-node-tree-container");
217 var newWidth = parseFloat(treeElement.style.width);
218 treeElement.style.minWidth = Math.max(newWidth, 50) + "px";
219 }
220 };
221
222 customSplitter.decorate($("sync-node-splitter"));
223
224 // Automatically trigger a refresh the first time this tab is selected.
225 $('sync-browser-tab').addEventListener('selectedChange', function f(e) {
226 if (this.selected) {
227 $('sync-browser-tab').removeEventListener('selectedChange', f);
228 refresh();
229 }
230 });
231 });
232
233 })();
OLDNEW
« no previous file with comments | « components/sync_driver/resources/sync_node_browser.css ('k') | components/sync_driver/resources/sync_search.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698