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

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

Issue 8336004: Improve web-app type safety. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 2 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 /** @suppress {duplicate} */ 5 /** @suppress {duplicate} */
6 var remoting = remoting || {}; 6 var remoting = remoting || {};
7 7
8 (function() { 8 /**
9 'use strict'; 9 * Whether or not the plugin should scale itself.
10 * @type {boolean}
11 */
12 remoting.scaleToFit = false;
10 13
11 window.addEventListener('blur', pluginLostFocus_, false); 14 /** @type {remoting.ClientSession} */
15 remoting.session = null;
12 16
13 function pluginLostFocus_() { 17 /** @type {string} */ remoting.accessCode = '';
14 // If the plug loses input focus, release all keys as a precaution against 18 /** @type {number} */ remoting.accessCodeTimerId = 0;
15 // leaving them 'stuck down' on the host. 19 /** @type {number} */ remoting.accessCodeExpiresIn = 0;
16 if (remoting.session && remoting.session.plugin) { 20 /** @type {remoting.AppMode} */ remoting.currentMode;
17 remoting.session.plugin.releaseAllKeys(); 21 /** @type {string} */ remoting.hostJid = '';
18 } 22 /** @type {string} */ remoting.hostPublicKey = '';
19 } 23 /** @type {boolean} */ remoting.lastShareWasCancelled = false;
24 /** @type {boolean} */ remoting.timerRunning = false;
25 /** @type {string} */ remoting.username = '';
Jamie 2011/10/18 00:19:27 This while file needs refactoring, but for now jus
20 26
21 /** @enum {string} */ 27 /** @enum {string} */
22 remoting.AppMode = { 28 remoting.AppMode = {
23 HOME: 'home', 29 HOME: 'home',
24 UNAUTHENTICATED: 'auth', 30 UNAUTHENTICATED: 'auth',
25 CLIENT: 'client', 31 CLIENT: 'client',
26 CLIENT_UNCONNECTED: 'client.unconnected', 32 CLIENT_UNCONNECTED: 'client.unconnected',
27 CLIENT_CONNECTING: 'client.connecting', 33 CLIENT_CONNECTING: 'client.connecting',
28 CLIENT_CONNECT_FAILED: 'client.connect-failed', 34 CLIENT_CONNECT_FAILED: 'client.connect-failed',
29 CLIENT_SESSION_FINISHED: 'client.session-finished', 35 CLIENT_SESSION_FINISHED: 'client.session-finished',
30 HOST: 'host', 36 HOST: 'host',
31 HOST_WAITING_FOR_CODE: 'host.waiting-for-code', 37 HOST_WAITING_FOR_CODE: 'host.waiting-for-code',
32 HOST_WAITING_FOR_CONNECTION: 'host.waiting-for-connection', 38 HOST_WAITING_FOR_CONNECTION: 'host.waiting-for-connection',
33 HOST_SHARED: 'host.shared', 39 HOST_SHARED: 'host.shared',
34 HOST_SHARE_FAILED: 'host.share-failed', 40 HOST_SHARE_FAILED: 'host.share-failed',
35 HOST_SHARE_FINISHED: 'host.share-finished', 41 HOST_SHARE_FINISHED: 'host.share-finished',
36 IN_SESSION: 'in-session' 42 IN_SESSION: 'in-session'
37 }; 43 };
38 44
39 remoting.EMAIL = 'email'; 45 (function() {
Jamie 2011/10/18 00:19:27 This is no longer used.
46 'use strict';
simonmorris 2011/10/18 00:55:36 Is it better to have 'use strict' at the top of th
Jamie 2011/10/18 01:42:01 It doesn't matter, but yes, probably. Done.
47
48 window.addEventListener('blur', pluginLostFocus_, false);
49
50 function pluginLostFocus_() {
51 // If the plug loses input focus, release all keys as a precaution against
52 // leaving them 'stuck down' on the host.
53 if (remoting.session && remoting.session.plugin) {
54 remoting.session.plugin.releaseAllKeys();
55 }
56 }
57
58 /** @type {string} */
40 remoting.HOST_PLUGIN_ID = 'host-plugin-id'; 59 remoting.HOST_PLUGIN_ID = 'host-plugin-id';
41 60
42 /** @enum {string} */ 61 /** @enum {string} */
43 remoting.ClientError = { 62 remoting.ClientError = {
44 NO_RESPONSE: /*i18n-content*/'ERROR_NO_RESPONSE', 63 NO_RESPONSE: /*i18n-content*/'ERROR_NO_RESPONSE',
45 INVALID_ACCESS_CODE: /*i18n-content*/'ERROR_INVALID_ACCESS_CODE', 64 INVALID_ACCESS_CODE: /*i18n-content*/'ERROR_INVALID_ACCESS_CODE',
46 MISSING_PLUGIN: /*i18n-content*/'ERROR_MISSING_PLUGIN', 65 MISSING_PLUGIN: /*i18n-content*/'ERROR_MISSING_PLUGIN',
47 OAUTH_FETCH_FAILED: /*i18n-content*/'ERROR_AUTHENTICATION_FAILED', 66 OAUTH_FETCH_FAILED: /*i18n-content*/'ERROR_AUTHENTICATION_FAILED',
48 HOST_IS_OFFLINE: /*i18n-content*/'ERROR_HOST_IS_OFFLINE', 67 HOST_IS_OFFLINE: /*i18n-content*/'ERROR_HOST_IS_OFFLINE',
49 INCOMPATIBLE_PROTOCOL: /*i18n-content*/'ERROR_INCOMPATIBLE_PROTOCOL', 68 INCOMPATIBLE_PROTOCOL: /*i18n-content*/'ERROR_INCOMPATIBLE_PROTOCOL',
50 OTHER_ERROR: /*i18n-content*/'ERROR_GENERIC' 69 OTHER_ERROR: /*i18n-content*/'ERROR_GENERIC'
51 }; 70 };
52 71
53 /**
54 * Whether or not the plugin should scale itself.
55 * @type {boolean}
56 */
57 remoting.scaleToFit = false;
58
59 // Constants representing keys used for storing persistent application state. 72 // Constants representing keys used for storing persistent application state.
60 var KEY_APP_MODE_ = 'remoting-app-mode'; 73 var KEY_APP_MODE_ = 'remoting-app-mode';
61 var KEY_EMAIL_ = 'remoting-email'; 74 var KEY_EMAIL_ = 'remoting-email';
62 var KEY_USE_P2P_API_ = 'remoting-use-p2p-api'; 75 var KEY_USE_P2P_API_ = 'remoting-use-p2p-api';
63 76
64 // Some constants for pretty-printing the access code. 77 // Some constants for pretty-printing the access code.
65 var kSupportIdLen = 7; 78 /** @type {number} */ var kSupportIdLen = 7;
66 var kHostSecretLen = 5; 79 /** @type {number} */ var kHostSecretLen = 5;
67 var kAccessCodeLen = kSupportIdLen + kHostSecretLen; 80 /** @type {number} */ var kAccessCodeLen = kSupportIdLen + kHostSecretLen;
68 var kDigitsPerGroup = 4; 81 /** @type {number} */ var kDigitsPerGroup = 4;
69 82
83 /**
84 * @param {string} classes A space-separated list of classes.
85 * @param {string} cls The class to check for.
86 * @return {boolean} True if |cls| is found within |classes|.
87 */
70 function hasClass(classes, cls) { 88 function hasClass(classes, cls) {
71 return classes.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')); 89 return classes.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) != null;
72 } 90 }
73 91
92 /**
93 * @param {Element} element The element to which to add the class.
94 * @param {string} cls The new class.
95 * @return {void} Nothing.
96 */
74 function addClass(element, cls) { 97 function addClass(element, cls) {
75 if (!hasClass(element.className, cls)) { 98 if (!hasClass(element.className, cls)) {
76 var padded = element.className == '' ? '' : element.className + ' '; 99 var padded = element.className == '' ? '' : element.className + ' ';
77 element.className = padded + cls; 100 element.className = padded + cls;
78 } 101 }
79 } 102 }
80 103
104 /**
105 * @param {Element} element The element from which to remove the class.
106 * @param {string} cls The new class.
107 * @return {void} Nothing.
108 */
81 function removeClass(element, cls) { 109 function removeClass(element, cls) {
82 element.className = 110 element.className =
83 element.className.replace(new RegExp('\\b' + cls + '\\b', 'g'), '') 111 element.className.replace(new RegExp('\\b' + cls + '\\b', 'g'), '')
84 .replace(' ', ' '); 112 .replace(' ', ' ');
85 } 113 }
86 114
87 function retrieveEmail_(access_token) { 115 function retrieveEmail_(access_token) {
88 var headers = { 116 var headers = {
89 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() 117 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken()
90 }; 118 };
91 119
120 /** @param {XMLHttpRequest} xhr The XHR response. */
92 var onResponse = function(xhr) { 121 var onResponse = function(xhr) {
93 if (xhr.status != 200) { 122 if (xhr.status != 200) {
94 // TODO(ajwong): Have a better way of showing an error. 123 // TODO(ajwong): Have a better way of showing an error.
95 remoting.debug.log('Unable to get email'); 124 remoting.debug.log('Unable to get email');
96 document.getElementById('current-email').innerText = '???'; 125 document.getElementById('current-email').innerText = '???';
97 return; 126 return;
98 } 127 }
99 128
100 // TODO(ajwong): See if we can't find a JSON endpoint. 129 // TODO(ajwong): See if we can't find a JSON endpoint.
101 setEmail(xhr.responseText.split('&')[0].split('=')[1]); 130 setEmail(xhr.responseText.split('&')[0].split('=')[1]);
102 }; 131 };
103 132
104 // TODO(ajwong): Update to new v2 API. 133 // TODO(ajwong): Update to new v2 API.
105 remoting.xhr.get('https://www.googleapis.com/userinfo/email', 134 remoting.xhr.get('https://www.googleapis.com/userinfo/email',
106 onResponse, '', headers); 135 onResponse, '', headers);
107 } 136 }
108 137
109 function refreshEmail_() { 138 function refreshEmail_() {
110 if (!getEmail() && remoting.oauth2.isAuthenticated()) { 139 if (!getEmail() && remoting.oauth2.isAuthenticated()) {
111 remoting.oauth2.callWithToken(retrieveEmail_); 140 remoting.oauth2.callWithToken(retrieveEmail_);
112 } 141 }
113 } 142 }
114 143
144 /**
145 * @param {string} value The email address to place in local storage.
146 * @return {void} Nothing.
147 */
115 function setEmail(value) { 148 function setEmail(value) {
116 window.localStorage.setItem(KEY_EMAIL_, value); 149 window.localStorage.setItem(KEY_EMAIL_, value);
117 document.getElementById('current-email').innerText = value; 150 document.getElementById('current-email').innerText = value;
118 } 151 }
119 152
120 /** 153 /**
121 * @return {?string} The email address associated with the auth credentials. 154 * @return {?string} The email address associated with the auth credentials.
122 */ 155 */
123 function getEmail() { 156 function getEmail() {
124 var result = window.localStorage.getItem(KEY_EMAIL_); 157 var result = window.localStorage.getItem(KEY_EMAIL_);
125 return typeof result == 'string' ? result : null; 158 return typeof result == 'string' ? result : null;
126 } 159 }
127 160
128 function exchangedCodeForToken_() { 161 function exchangedCodeForToken_() {
129 if (!remoting.oauth2.isAuthenticated()) { 162 if (!remoting.oauth2.isAuthenticated()) {
130 alert('Your OAuth2 token was invalid. Please try again.'); 163 alert('Your OAuth2 token was invalid. Please try again.');
131 } 164 }
132 remoting.oauth2.callWithToken(function(token) { 165 /** @param {string} token The auth token. */
133 retrieveEmail_(token); 166 var retrieveEmail = function(token) { retrieveEmail_(token); }
134 }); 167 remoting.oauth2.callWithToken(retrieveEmail);
135 } 168 }
136 169
137 remoting.clearOAuth2 = function() { 170 remoting.clearOAuth2 = function() {
138 remoting.oauth2.clear(); 171 remoting.oauth2.clear();
139 window.localStorage.removeItem(KEY_EMAIL_); 172 window.localStorage.removeItem(KEY_EMAIL_);
140 remoting.setMode(remoting.AppMode.UNAUTHENTICATED); 173 remoting.setMode(remoting.AppMode.UNAUTHENTICATED);
141 } 174 }
142 175
143 remoting.toggleDebugLog = function() { 176 remoting.toggleDebugLog = function() {
144 var debugLog = document.getElementById('debug-log'); 177 var debugLog = document.getElementById('debug-log');
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 * 219 *
187 * @param {remoting.AppMode} mode The new modal state, expressed as a dotted 220 * @param {remoting.AppMode} mode The new modal state, expressed as a dotted
188 * hiearchy. 221 * hiearchy.
189 */ 222 */
190 remoting.setMode = function(mode) { 223 remoting.setMode = function(mode) {
191 var modes = mode.split('.'); 224 var modes = mode.split('.');
192 for (var i = 1; i < modes.length; ++i) 225 for (var i = 1; i < modes.length; ++i)
193 modes[i] = modes[i - 1] + '.' + modes[i]; 226 modes[i] = modes[i - 1] + '.' + modes[i];
194 var elements = document.querySelectorAll('[data-ui-mode]'); 227 var elements = document.querySelectorAll('[data-ui-mode]');
195 for (var i = 0; i < elements.length; ++i) { 228 for (var i = 0; i < elements.length; ++i) {
196 var element = elements[i]; 229 /** @type {Element} */ var element = elements[i];
197 var hidden = true; 230 var hidden = true;
198 for (var m = 0; m < modes.length; ++m) { 231 for (var m = 0; m < modes.length; ++m) {
199 if (hasClass(element.getAttribute('data-ui-mode'), modes[m])) { 232 if (hasClass(element.getAttribute('data-ui-mode'), modes[m])) {
200 hidden = false; 233 hidden = false;
201 break; 234 break;
202 } 235 }
203 } 236 }
204 element.hidden = hidden; 237 element.hidden = hidden;
205 } 238 }
206 remoting.debug.log('App mode: ' + mode); 239 remoting.debug.log('App mode: ' + mode);
207 remoting.currentMode = mode; 240 remoting.currentMode = mode;
208 if (mode == remoting.AppMode.IN_SESSION) { 241 if (mode == remoting.AppMode.IN_SESSION) {
209 document.removeEventListener('keydown', remoting.checkHotkeys, false); 242 document.removeEventListener('keydown', remoting.checkHotkeys, false);
210 } else { 243 } else {
211 document.addEventListener('keydown', remoting.checkHotkeys, false); 244 document.addEventListener('keydown', remoting.checkHotkeys, false);
212 } 245 }
213 } 246 }
214 247
215 /** 248 /**
216 * Get the major mode that the app is running in. 249 * Get the major mode that the app is running in.
217 * @return {remoting.AppMode} The app's current major mode. 250 * @return {string} The app's current major mode.
218 */ 251 */
219 remoting.getMajorMode = function() { 252 remoting.getMajorMode = function() {
220 return remoting.currentMode.split('.')[0]; 253 return remoting.currentMode.split('.')[0];
221 } 254 }
222 255
223 remoting.tryShare = function() { 256 remoting.tryShare = function() {
224 remoting.debug.log('Attempting to share...'); 257 remoting.debug.log('Attempting to share...');
225 remoting.lastShareWasCancelled = false; 258 remoting.lastShareWasCancelled = false;
226 if (remoting.oauth2.needsNewAccessToken()) { 259 if (remoting.oauth2.needsNewAccessToken()) {
227 remoting.debug.log('Refreshing token...'); 260 remoting.debug.log('Refreshing token...');
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 334
302 remoting.updateAccessCodeTimeoutElement_ = function() { 335 remoting.updateAccessCodeTimeoutElement_ = function() {
303 var pad = (remoting.accessCodeExpiresIn < 10) ? '0:0' : '0:'; 336 var pad = (remoting.accessCodeExpiresIn < 10) ? '0:0' : '0:';
304 l10n.localizeElement(document.getElementById('seconds-remaining'), 337 l10n.localizeElement(document.getElementById('seconds-remaining'),
305 pad + remoting.accessCodeExpiresIn); 338 pad + remoting.accessCodeExpiresIn);
306 if (!updateTimeoutStyles_()) { 339 if (!updateTimeoutStyles_()) {
307 disableTimeoutCountdown_(); 340 disableTimeoutCountdown_();
308 } 341 }
309 } 342 }
310 343
344 /**
345 * Callback to show or hide the NAT traversal warning when the policy changes.
346 * @param {boolean} enabled True if NAT traversal is enabled.
347 * @return {void} Nothing.
348 */
311 function onNatTraversalPolicyChanged_(enabled) { 349 function onNatTraversalPolicyChanged_(enabled) {
312 var container = document.getElementById('nat-box-container'); 350 var container = document.getElementById('nat-box-container');
313 container.hidden = enabled; 351 container.hidden = enabled;
314 } 352 }
315 353
316 function onStateChanged_() { 354 function onStateChanged_() {
317 var plugin = /** @type {remoting.HostPlugin} */ 355 var plugin = /** @type {remoting.HostPlugin} */
318 document.getElementById(remoting.HOST_PLUGIN_ID); 356 document.getElementById(remoting.HOST_PLUGIN_ID);
319 var state = plugin.state; 357 var state = plugin.state;
320 if (state == plugin.STARTING) { 358 if (state == plugin.STARTING) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 * @return {void} Nothing. 445 * @return {void} Nothing.
408 */ 446 */
409 remoting.cancelShare = function() { 447 remoting.cancelShare = function() {
410 remoting.debug.log('Canceling share...'); 448 remoting.debug.log('Canceling share...');
411 remoting.lastShareWasCancelled = true; 449 remoting.lastShareWasCancelled = true;
412 var plugin = /** @type {remoting.HostPlugin} */ 450 var plugin = /** @type {remoting.HostPlugin} */
413 document.getElementById(remoting.HOST_PLUGIN_ID); 451 document.getElementById(remoting.HOST_PLUGIN_ID);
414 try { 452 try {
415 plugin.disconnect(); 453 plugin.disconnect();
416 } catch (error) { 454 } catch (error) {
417 remoting.debug.log('Error disconnecting: ' + error.description + 455 var tmp = /** @type {{description: string}} */ error;
Jamie 2011/10/18 00:19:27 This is horrible, but I couldn't find any other wa
simonmorris 2011/10/18 00:55:36 It's OK - maybe rename tmp to errorTyped, to make
Jamie 2011/10/18 01:42:01 Done.
456 remoting.debug.log('Error disconnecting: ' + tmp.description +
418 '. The host plugin probably crashed.'); 457 '. The host plugin probably crashed.');
419 // TODO(jamiewalch): Clean this up. We should have a class representing 458 // TODO(jamiewalch): Clean this up. We should have a class representing
420 // the host plugin, like we do for the client, which should handle crash 459 // the host plugin, like we do for the client, which should handle crash
421 // reporting and it should use a more detailed error message than the 460 // reporting and it should use a more detailed error message than the
422 // default 'generic' one. See crbug.com/94624 461 // default 'generic' one. See crbug.com/94624
423 showShareError_(/*i18n-content*/'ERROR_GENERIC'); 462 showShareError_(/*i18n-content*/'ERROR_GENERIC');
424 } 463 }
425 disableTimeoutCountdown_(); 464 disableTimeoutCountdown_();
426 } 465 }
427 466
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 // Update the stats once per second. 515 // Update the stats once per second.
477 window.setTimeout(updateStatistics, 1000); 516 window.setTimeout(updateStatistics, 1000);
478 } 517 }
479 518
480 function showToolbarPreview_() { 519 function showToolbarPreview_() {
481 var toolbar = document.getElementById('session-toolbar'); 520 var toolbar = document.getElementById('session-toolbar');
482 addClass(toolbar, 'toolbar-preview'); 521 addClass(toolbar, 'toolbar-preview');
483 window.setTimeout(removeClass, 3000, toolbar, 'toolbar-preview'); 522 window.setTimeout(removeClass, 3000, toolbar, 'toolbar-preview');
484 } 523 }
485 524
525 /** @param {number} oldState The previous state of the plugin. */
486 function onClientStateChange_(oldState) { 526 function onClientStateChange_(oldState) {
487 if (!remoting.session) { 527 if (!remoting.session) {
488 // If the connection has been cancelled, then we no longer have a reference 528 // If the connection has been cancelled, then we no longer have a reference
489 // to the session object and should ignore any state changes. 529 // to the session object and should ignore any state changes.
490 return; 530 return;
491 } 531 }
492 var state = remoting.session.state; 532 var state = remoting.session.state;
493 if (state == remoting.ClientSession.State.CREATED) { 533 if (state == remoting.ClientSession.State.CREATED) {
494 remoting.debug.log('Created plugin'); 534 remoting.debug.log('Created plugin');
495 } else if (state == remoting.ClientSession.State.BAD_PLUGIN_VERSION) { 535 } else if (state == remoting.ClientSession.State.BAD_PLUGIN_VERSION) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 function startSession_() { 585 function startSession_() {
546 remoting.debug.log('Starting session...'); 586 remoting.debug.log('Starting session...');
547 var accessCode = document.getElementById('access-code-entry'); 587 var accessCode = document.getElementById('access-code-entry');
548 accessCode.value = ''; // The code has been validated and won't work again. 588 accessCode.value = ''; // The code has been validated and won't work again.
549 remoting.username = 589 remoting.username =
550 /** @type {string} email must be non-NULL to get here */ getEmail(); 590 /** @type {string} email must be non-NULL to get here */ getEmail();
551 remoting.session = 591 remoting.session =
552 new remoting.ClientSession(remoting.hostJid, remoting.hostPublicKey, 592 new remoting.ClientSession(remoting.hostJid, remoting.hostPublicKey,
553 remoting.accessCode, remoting.username, 593 remoting.accessCode, remoting.username,
554 onClientStateChange_); 594 onClientStateChange_);
555 remoting.oauth2.callWithToken(function(token) { 595 /** @param {string} token The auth token. */
596 var createPluginAndConnect = function(token) {
556 remoting.session.createPluginAndConnect( 597 remoting.session.createPluginAndConnect(
557 document.getElementById('session-mode'), 598 document.getElementById('session-mode'),
558 token); 599 token);
559 }); 600 };
601 remoting.oauth2.callWithToken(createPluginAndConnect);
560 } 602 }
561 603
562 /** 604 /**
563 * Show a client-side error message. 605 * Show a client-side error message.
564 * 606 *
565 * @param {remoting.ClientError} errorTag The error to be localized and 607 * @param {remoting.ClientError} errorTag The error to be localized and
566 * displayed. 608 * displayed.
567 * @return {void} Nothing. 609 * @return {void} Nothing.
568 */ 610 */
569 function showConnectError_(errorTag) { 611 function showConnectError_(errorTag) {
570 remoting.debug.log('Connection failed: ' + errorTag); 612 remoting.debug.log('Connection failed: ' + errorTag);
571 var errorDiv = document.getElementById('connect-error-message'); 613 var errorDiv = document.getElementById('connect-error-message');
572 l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag)); 614 l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag));
573 remoting.accessCode = ''; 615 remoting.accessCode = '';
574 if (remoting.session) { 616 if (remoting.session) {
575 remoting.session.disconnect(); 617 remoting.session.disconnect();
576 remoting.session = null; 618 remoting.session = null;
577 } 619 }
578 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED); 620 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED);
579 } 621 }
580 622
581 /** 623 /**
582 * @param {XMLHttpRequest} xhr The XMLHttpRequest object. 624 * @param {XMLHttpRequest} xhr The XMLHttpRequest object.
583 * @return {void} Nothing. 625 * @return {void} Nothing.
584 */ 626 */
585 function parseServerResponse_(xhr) { 627 function parseServerResponse_(xhr) {
586 remoting.supportHostsXhr = null; 628 remoting.supportHostsXhr = null;
587 remoting.debug.log('parseServerResponse: status = ' + xhr.status); 629 remoting.debug.log('parseServerResponse: status = ' + xhr.status);
588 if (xhr.status == 200) { 630 if (xhr.status == 200) {
589 var host = JSON.parse(xhr.responseText); 631 var host = /** @type {{data: {jabberId: string, publicKey: string}}} */
590 if (host.data && host.data.jabberId) { 632 JSON.parse(xhr.responseText);
633 if (host.data && host.data.jabberId && host.data.publicKey) {
Jamie 2011/10/18 00:19:27 I've updated the test to match the type cast above
simonmorris 2011/10/18 00:55:36 OK.
591 remoting.hostJid = host.data.jabberId; 634 remoting.hostJid = host.data.jabberId;
592 remoting.hostPublicKey = host.data.publicKey; 635 remoting.hostPublicKey = host.data.publicKey;
593 var split = remoting.hostJid.split('/'); 636 var split = remoting.hostJid.split('/');
594 document.getElementById('connected-to').innerText = split[0]; 637 document.getElementById('connected-to').innerText = split[0];
595 startSession_(); 638 startSession_();
596 return; 639 return;
597 } 640 }
598 } 641 }
599 var errorMsg = remoting.ClientError.OTHER_ERROR; 642 var errorMsg = remoting.ClientError.OTHER_ERROR;
600 if (xhr.status == 404) { 643 if (xhr.status == 404) {
601 errorMsg = remoting.ClientError.INVALID_ACCESS_CODE; 644 errorMsg = remoting.ClientError.INVALID_ACCESS_CODE;
602 } else if (xhr.status == 0) { 645 } else if (xhr.status == 0) {
603 errorMsg = remoting.ClientError.NO_RESPONSE; 646 errorMsg = remoting.ClientError.NO_RESPONSE;
604 } else { 647 } else {
605 remoting.debug.log('The server responded: ' + xhr.responseText); 648 remoting.debug.log('The server responded: ' + xhr.responseText);
606 } 649 }
607 showConnectError_(errorMsg); 650 showConnectError_(errorMsg);
608 } 651 }
609 652
653 /** @param {string} accessCode The access code, as entered by the user.
654 * @return {string} The normalized form of the code (whitespace removed). */
610 function normalizeAccessCode_(accessCode) { 655 function normalizeAccessCode_(accessCode) {
611 // Trim whitespace. 656 // Trim whitespace.
612 // TODO(sergeyu): Do we need to do any other normalization here? 657 // TODO(sergeyu): Do we need to do any other normalization here?
613 return accessCode.replace(/\s/g, ''); 658 return accessCode.replace(/\s/g, '');
614 } 659 }
615 660
661 /** @param {string} supportId The canonicalized support ID. */
616 function resolveSupportId(supportId) { 662 function resolveSupportId(supportId) {
617 var headers = { 663 var headers = {
618 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() 664 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken()
619 }; 665 };
620 666
621 remoting.supportHostsXhr = remoting.xhr.get( 667 remoting.supportHostsXhr = remoting.xhr.get(
622 'https://www.googleapis.com/chromoting/v1/support-hosts/' + 668 'https://www.googleapis.com/chromoting/v1/support-hosts/' +
623 encodeURIComponent(supportId), 669 encodeURIComponent(supportId),
624 parseServerResponse_, 670 parseServerResponse_,
625 '', 671 '',
(...skipping 14 matching lines...) Expand all
640 }); 686 });
641 } else { 687 } else {
642 remoting.tryConnectWithAccessToken(); 688 remoting.tryConnectWithAccessToken();
643 } 689 }
644 } 690 }
645 691
646 remoting.tryConnectWithAccessToken = function() { 692 remoting.tryConnectWithAccessToken = function() {
647 if (!remoting.wcsLoader) { 693 if (!remoting.wcsLoader) {
648 remoting.wcsLoader = new remoting.WcsLoader(); 694 remoting.wcsLoader = new remoting.WcsLoader();
649 } 695 }
696 /** @param {function(string):void} setToken The callback function. */
697 var callWithToken = function(setToken) {
698 remoting.oauth2.callWithToken(setToken);
699 };
650 remoting.wcsLoader.start( 700 remoting.wcsLoader.start(
651 remoting.oauth2.getAccessToken(), 701 remoting.oauth2.getAccessToken(),
652 function(setToken) { 702 callWithToken,
653 remoting.oauth2.callWithToken(setToken);
654 },
655 remoting.tryConnectWithWcs); 703 remoting.tryConnectWithWcs);
656 } 704 }
657 705
658 remoting.tryConnectWithWcs = function() { 706 remoting.tryConnectWithWcs = function() {
659 var accessCode = document.getElementById('access-code-entry').value; 707 var accessCode = document.getElementById('access-code-entry').value;
660 remoting.accessCode = normalizeAccessCode_(accessCode); 708 remoting.accessCode = normalizeAccessCode_(accessCode);
661 // At present, only 12-digit access codes are supported, of which the first 709 // At present, only 12-digit access codes are supported, of which the first
662 // 7 characters are the supportId. 710 // 7 characters are the supportId.
663 if (remoting.accessCode.length != kAccessCodeLen) { 711 if (remoting.accessCode.length != kAccessCodeLen) {
664 remoting.debug.log('Bad access code length'); 712 remoting.debug.log('Bad access code length');
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 case remoting.AppMode.HOST_WAITING_FOR_CONNECTION: 810 case remoting.AppMode.HOST_WAITING_FOR_CONNECTION:
763 case remoting.AppMode.HOST_SHARED: 811 case remoting.AppMode.HOST_SHARED:
764 case remoting.AppMode.IN_SESSION: 812 case remoting.AppMode.IN_SESSION:
765 var result = chrome.i18n.getMessage(/*i18n-content*/'CLOSE_PROMPT'); 813 var result = chrome.i18n.getMessage(/*i18n-content*/'CLOSE_PROMPT');
766 return result; 814 return result;
767 default: 815 default:
768 return null; 816 return null;
769 } 817 }
770 } 818 }
771 819
820 /**
821 * @param {Event} event The keyboard event.
822 * @return {void} Nothing.
823 */
772 remoting.checkHotkeys = function(event) { 824 remoting.checkHotkeys = function(event) {
773 if (String.fromCharCode(event.which) == 'D') { 825 if (String.fromCharCode(event.which) == 'D') {
774 remoting.toggleDebugLog(); 826 remoting.toggleDebugLog();
775 } 827 }
776 } 828 }
777 829
778 function recenterToolbar_() { 830 function recenterToolbar_() {
779 var toolbar = document.getElementById('session-toolbar'); 831 var toolbar = document.getElementById('session-toolbar');
780 var toolbarX = (window.innerWidth - toolbar.clientWidth) / 2; 832 var toolbarX = (window.innerWidth - toolbar.clientWidth) / 2;
781 toolbar.style['left'] = toolbarX + 'px'; 833 toolbar.style['left'] = toolbarX + 'px';
782 } 834 }
783 835
784 }()); 836 }());
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698