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

Side by Side Diff: remoting/webapp/me2mom/host_list.js

Issue 8782001: Refactored HostList to better support bookmarking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge bug. Created 9 years 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
« no previous file with comments | « remoting/webapp/me2mom/client_screen.js ('k') | remoting/webapp/me2mom/host_table_entry.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /** 5 /**
6 * @fileoverview 6 * @fileoverview
7 * Class representing the host-list portion of the home screen UI. 7 * Class representing the host-list portion of the home screen UI.
8 */ 8 */
9 9
10 'use strict'; 10 'use strict';
11 11
12 /** @suppress {duplicate} */ 12 /** @suppress {duplicate} */
13 var remoting = remoting || {}; 13 var remoting = remoting || {};
14 14
15 /** 15 /**
16 * Create a host list consisting of the specified HTML elements, which should 16 * Create a host list consisting of the specified HTML elements, which should
17 * have a common parent that contains only host-list UI as it will be hidden 17 * have a common parent that contains only host-list UI as it will be hidden
18 * if the host-list is empty. 18 * if the host-list is empty.
19 *
19 * @constructor 20 * @constructor
20 * @param {Element} table The HTML <table> to contain host-list. 21 * @param {Element} table The HTML <table> to contain host-list.
21 * @param {Element} errorDiv The HTML <div> to display error messages. 22 * @param {Element} errorDiv The HTML <div> to display error messages.
22 */ 23 */
23 remoting.HostList = function(table, errorDiv) { 24 remoting.HostList = function(table, errorDiv) {
24 /** 25 /**
25 * @type {Element} 26 * @type {Element}
26 * @private 27 * @private
27 */ 28 */
28 this.table_ = table; 29 this.table_ = table;
29 /** 30 /**
30 * @type {Element} 31 * @type {Element}
31 * @private 32 * @private
32 */ 33 */
33 this.errorDiv_ = errorDiv; 34 this.errorDiv_ = errorDiv;
34 /** 35 /**
35 * @type {Array.<remoting.HostTableEntry>} 36 * @type {Array.<remoting.HostTableEntry>}
36 * @private 37 * @private
37 */ 38 */
38 this.hostTableEntries_ = null; 39 this.hostTableEntries_ = [];
40 /**
41 * @type {Array.<remoting.Host>}
42 * @private
43 */
44 this.hosts_ = [];
45 /**
46 * @type {string}
47 * @private
48 */
49 this.lastError_ = '';
50
51 // Load the cache of the last host-list, if present.
52 var cached = /** @type {string} */
53 (window.localStorage.getItem(remoting.HostList.HOSTS_KEY));
54 if (cached) {
55 try {
56 this.hosts_ = /** @type {Array} */ JSON.parse(cached);
57 } catch (err) {
58 console.error('Invalid host list cache:', /** @type {*} */(err));
59 }
60 }
39 }; 61 };
40 62
41 /** 63 /**
42 * Search the host list for a host with the specified id. 64 * Search the host list for a host with the specified id.
65 *
43 * @param {string} hostId The unique id of the host. 66 * @param {string} hostId The unique id of the host.
44 * @return {remoting.HostTableEntry?} The host table entry, if any. 67 * @return {remoting.Host?} The host, if any.
45 */ 68 */
46 remoting.HostList.prototype.getHostForId = function(hostId) { 69 remoting.HostList.prototype.getHostForId = function(hostId) {
47 for (var i = 0; i < this.hostTableEntries_.length; ++i) { 70 for (var i = 0; i < this.hosts_.length; ++i) {
48 if (this.hostTableEntries_[i].host.hostId == hostId) { 71 if (this.hosts_[i].hostId == hostId) {
49 return this.hostTableEntries_[i]; 72 return this.hosts_[i];
50 } 73 }
51 } 74 }
52 return null; 75 return null;
53 }; 76 };
54 77
55 /** 78 /**
56 * Query the Remoting Directory for the user's list of hosts. 79 * Query the Remoting Directory for the user's list of hosts.
57 * 80 *
81 * @param {function(boolean):void} onDone Callback invoked with true on success
82 * or false on failure.
58 * @return {void} Nothing. 83 * @return {void} Nothing.
59 */ 84 */
60 remoting.HostList.prototype.refresh = function() { 85 remoting.HostList.prototype.refresh = function(onDone) {
61 /** @type {remoting.HostList} */ 86 /** @type {remoting.HostList} */
62 var that = this; 87 var that = this;
63 /** @param {XMLHttpRequest} xhr */ 88 /** @param {XMLHttpRequest} xhr The response from the server. */
64 var parseHostListResponse = function(xhr) { 89 var parseHostListResponse = function(xhr) {
65 that.parseHostListResponse_(xhr); 90 that.parseHostListResponse_(xhr, onDone);
66 } 91 }
67 /** @param {string} token */ 92 /** @param {string} token The OAuth2 token. */
68 var getHosts = function(token) { 93 var getHosts = function(token) {
69 var headers = { 'Authorization': 'OAuth ' + token }; 94 var headers = { 'Authorization': 'OAuth ' + token };
70 remoting.xhr.get( 95 remoting.xhr.get(
71 'https://www.googleapis.com/chromoting/v1/@me/hosts', 96 'https://www.googleapis.com/chromoting/v1/@me/hosts',
72 parseHostListResponse, '', headers); 97 parseHostListResponse, '', headers);
73 }; 98 };
74 remoting.oauth2.callWithToken(getHosts); 99 remoting.oauth2.callWithToken(getHosts);
75 } 100 };
76 101
77 /** 102 /**
78 * Handle the results of the host list request. A success response will 103 * Handle the results of the host list request. A success response will
79 * include a JSON-encoded list of host descriptions, which we display if we're 104 * include a JSON-encoded list of host descriptions, which we display if we're
80 * able to successfully parse it. 105 * able to successfully parse it.
81 * 106 *
82 * @param {XMLHttpRequest} xhr The XHR object for the host list request. 107 * @param {XMLHttpRequest} xhr The XHR object for the host list request.
108 * @param {function(boolean):void} onDone The callback passed to |refresh|.
83 * @return {void} Nothing. 109 * @return {void} Nothing.
110 * @private
84 */ 111 */
85 remoting.HostList.prototype.parseHostListResponse_ = function(xhr) { 112 remoting.HostList.prototype.parseHostListResponse_ = function(xhr, onDone) {
113 this.hosts_ = [];
114 this.lastError_ = '';
86 try { 115 try {
87 if (xhr.status == 200) { 116 if (xhr.status == 200) {
88 var parsed_response = 117 var parsed_response =
89 /** @type {{data: {items: Array}}} */ JSON.parse(xhr.responseText); 118 /** @type {{data: {items: Array}}} */ JSON.parse(xhr.responseText);
90 if (parsed_response.data && parsed_response.data.items) { 119 if (parsed_response.data && parsed_response.data.items) {
91 this.setHosts_(parsed_response.data.items); 120 this.hosts_ = parsed_response.data.items;
92 } 121 }
93 } else { 122 } else {
94 // Some other error. 123 // Some other error.
95 console.error('Bad status on host list query: ', xhr); 124 console.error('Bad status on host list query: ', xhr);
96 // For most errors in the 4xx range, tell the user to re-authorize us.
97 if (xhr.status == 403) { 125 if (xhr.status == 403) {
98 // The user's account is not enabled for Me2Me, so fail silently. 126 // The user's account is not enabled for Me2Me, so fail silently.
99 } else if (xhr.status >= 400 && xhr.status <= 499) { 127 } else if (xhr.status >= 400 && xhr.status < 500) {
100 this.showError_(remoting.Error.GENERIC); 128 // For other errors, tell the user to re-authorize us.
129 this.lastError_ = remoting.Error.GENERIC;
130 } else {
131 this.lastError_ = remoting.Error.UNEXPECTED;
101 } 132 }
102 } 133 }
103 } catch (er) { 134 } catch (er) {
104 var typed_er = /** @type {Object} */ (er); 135 var typed_er = /** @type {Object} */ (er);
105 console.error('Error processing response: ', xhr, typed_er); 136 console.error('Error processing response: ', xhr, typed_er);
137 this.lastError_ = remoting.Error.UNEXPECTED;
106 } 138 }
107 } 139 window.localStorage.setItem(remoting.HostList.HOSTS_KEY,
140 JSON.stringify(this.hosts_));
141 onDone(this.lastError_ == '');
142 };
108 143
109 /** 144 /**
110 * Refresh the host list with up-to-date details. 145 * Display the list of hosts or error condition.
111 * @param {Array.<remoting.Host>} hosts The new host list. 146 *
112 * @return {void} Nothing. 147 * @return {void} Nothing.
113 * @private
114 */ 148 */
115 remoting.HostList.prototype.setHosts_ = function(hosts) { 149 remoting.HostList.prototype.display = function() {
116 this.table_.innerHTML = ''; 150 this.table_.innerHTML = '';
117 this.showError_(null); 151 this.errorDiv_.innerText = '';
118 this.hostTableEntries_ = []; 152 this.hostTableEntries_ = [];
119 153
120 /** 154 /**
121 * @type {remoting.HostList} 155 * @type {remoting.HostList}
122 */ 156 */
123 var that = this; 157 var that = this;
124 /** 158 /**
125 * @param {remoting.HostTableEntry} hostTableEntry The entry being renamed. 159 * @param {remoting.HostTableEntry} hostTableEntry The entry being renamed.
126 */ 160 */
127 var onRename = function(hostTableEntry) { that.renameHost_(hostTableEntry); } 161 var onRename = function(hostTableEntry) { that.renameHost_(hostTableEntry); }
128 /** 162 /**
129 * @param {remoting.HostTableEntry} hostTableEntry The entry beign deleted. 163 * @param {remoting.HostTableEntry} hostTableEntry The entry beign deleted.
130 */ 164 */
131 var onDelete = function(hostTableEntry) { that.deleteHost_(hostTableEntry); } 165 var onDelete = function(hostTableEntry) { that.deleteHost_(hostTableEntry); }
132 166
133 for (var i = 0; i < hosts.length; ++i) { 167 for (var i = 0; i < this.hosts_.length; ++i) {
134 /** @type {remoting.Host} */ 168 /** @type {remoting.Host} */
135 var host = hosts[i]; 169 var host = this.hosts_[i];
136 // Validate the entry to make sure it has all the fields we expect. 170 // Validate the entry to make sure it has all the fields we expect.
137 if (host.hostName && host.hostId && host.status && host.jabberId && 171 if (host.hostName && host.hostId && host.status && host.jabberId &&
138 host.publicKey) { 172 host.publicKey) {
139 var hostTableEntry = new remoting.HostTableEntry(); 173 var hostTableEntry = new remoting.HostTableEntry();
140 hostTableEntry.init(host, onRename, onDelete); 174 hostTableEntry.init(host, onRename, onDelete);
141 this.hostTableEntries_[i] = hostTableEntry; 175 this.hostTableEntries_[i] = hostTableEntry;
142 this.table_.appendChild(hostTableEntry.tableRow); 176 this.table_.appendChild(hostTableEntry.tableRow);
143 } 177 }
144 } 178 }
145 179
146 this.showOrHide_(this.hostTableEntries_.length != 0); 180 if (this.lastError_ != '') {
147 }; 181 l10n.localizeElementFromTag(this.errorDiv_, this.lastError_);
182 }
148 183
149 /** 184 this.showOrHide_(this.hosts_.length != 0 || this.lastError_ != '');
150 * Display a localized error message.
151 * @param {remoting.Error?} errorTag The error to display, or NULL to clear any
152 * previous error.
153 * @return {void} Nothing.
154 */
155 remoting.HostList.prototype.showError_ = function(errorTag) {
156 this.table_.innerHTML = '';
157 if (errorTag) {
158 l10n.localizeElementFromTag(this.errorDiv_,
159 /** @type {string} */ (errorTag));
160 this.showOrHide_(true);
161 } else {
162 this.errorDiv_.innerText = '';
163 }
164 }; 185 };
165 186
166 /** 187 /**
167 * Show or hide the host-list UI. 188 * Show or hide the host-list UI.
189 *
168 * @param {boolean} show True to show the UI, or false to hide it. 190 * @param {boolean} show True to show the UI, or false to hide it.
169 * @return {void} Nothing. 191 * @return {void} Nothing.
170 * @private 192 * @private
171 */ 193 */
172 remoting.HostList.prototype.showOrHide_ = function(show) { 194 remoting.HostList.prototype.showOrHide_ = function(show) {
173 var parent = /** @type {Element} */ (this.table_.parentNode); 195 var parent = /** @type {Element} */ (this.table_.parentNode);
174 parent.hidden = !show; 196 parent.hidden = !show;
175 if (show) { 197 if (show) {
176 parent.style.height = parent.scrollHeight + 'px'; 198 parent.style.height = parent.scrollHeight + 'px';
177 removeClass(parent, remoting.HostList.COLLAPSED_); 199 removeClass(parent, remoting.HostList.COLLAPSED_);
178 } else { 200 } else {
179 addClass(parent, remoting.HostList.COLLAPSED_); 201 addClass(parent, remoting.HostList.COLLAPSED_);
180 } 202 }
181 }; 203 };
182 204
183 /** 205 /**
184 * Remove a host from the list, and deregister it. 206 * Remove a host from the list, and deregister it.
185 * @param {remoting.HostTableEntry} hostTableEntry The host to be removed. 207 * @param {remoting.HostTableEntry} hostTableEntry The host to be removed.
186 * @return {void} Nothing. 208 * @return {void} Nothing.
187 * @private 209 * @private
188 */ 210 */
189 remoting.HostList.prototype.deleteHost_ = function(hostTableEntry) { 211 remoting.HostList.prototype.deleteHost_ = function(hostTableEntry) {
190 this.table_.removeChild(hostTableEntry.tableRow); 212 this.table_.removeChild(hostTableEntry.tableRow);
191 var index = this.hostTableEntries_.indexOf(hostTableEntry); 213 var index = this.hostTableEntries_.indexOf(hostTableEntry);
192 if (index != -1) { 214 if (index != -1) {
193 this.hostTableEntries_.splice(index, 1); 215 this.hostTableEntries_.splice(index, 1);
194 } 216 }
195 217
196 /** @param {string} token */ 218 /** @param {string} token The OAuth2 token. */
197 var deleteHost = function(token) { 219 var deleteHost = function(token) {
198 var headers = { 'Authorization': 'OAuth ' + token }; 220 var headers = { 'Authorization': 'OAuth ' + token };
199 remoting.xhr.remove( 221 remoting.xhr.remove(
200 'https://www.googleapis.com/chromoting/v1/@me/hosts/' + 222 'https://www.googleapis.com/chromoting/v1/@me/hosts/' +
201 hostTableEntry.host.hostId, 223 hostTableEntry.host.hostId,
202 function() {}, '', headers); 224 function() {}, '', headers);
203 } 225 }
204 remoting.oauth2.callWithToken(deleteHost); 226 remoting.oauth2.callWithToken(deleteHost);
205 227
206 this.showOrHide_(this.hostTableEntries_.length != 0); 228 this.showOrHide_(this.hostTableEntries_.length != 0);
(...skipping 26 matching lines...) Expand all
233 } 255 }
234 remoting.oauth2.callWithToken(renameHost); 256 remoting.oauth2.callWithToken(renameHost);
235 }; 257 };
236 258
237 /** 259 /**
238 * Class name for the host list when it is collapsed. 260 * Class name for the host list when it is collapsed.
239 * @private 261 * @private
240 */ 262 */
241 remoting.HostList.COLLAPSED_ = 'collapsed'; 263 remoting.HostList.COLLAPSED_ = 'collapsed';
242 264
265 /**
266 * Key name under which Me2Me hosts are cached.
267 */
268 remoting.HostList.HOSTS_KEY = 'me2me-cached-hosts';
269
243 /** @type {remoting.HostList} */ 270 /** @type {remoting.HostList} */
244 remoting.hostList = null; 271 remoting.hostList = null;
OLDNEW
« no previous file with comments | « remoting/webapp/me2mom/client_screen.js ('k') | remoting/webapp/me2mom/host_table_entry.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698