Roll src/third_party/WebKit 3529d49:06e8485 (svn 202554:202555)
[chromium-blink-merge.git] / remoting / webapp / crd / js / wcs_loader.js
blobc3436d5f36092b21efe7195119611a418fcfccf7
1 /* Copyright (c) 2012 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  */
6 /**
7  * @fileoverview
8  * A class that loads a WCS IQ client and constructs remoting.wcs as a
9  * wrapper for it.
10  */
12 'use strict';
14 /** @suppress {duplicate} */
15 var remoting = remoting || {};
17 /** @type {remoting.WcsLoader} */
18 remoting.wcsLoader = null;
20 /**
21  * @constructor
22  */
23 remoting.WcsLoader = function() {
24   /**
25    * The WCS client that will be downloaded. This variable is initialized (via
26    * remoting.wcsLoader) by the downloaded Javascript.
27    * @type {remoting.WcsIqClient}
28    */
29   this.wcsIqClient = null;
32 /**
33  * The id of the script node.
34  * @private {string}
35  */
36 remoting.WcsLoader.prototype.SCRIPT_NODE_ID_ = 'wcs-script-node';
38 /**
39  * Starts loading the WCS IQ client.
40  *
41  * When it's loaded, construct remoting.wcs as a wrapper for it.
42  * When the WCS connection is ready, or on error, call |onReady| or |onError|,
43  * respectively.
44  *
45  * @param {string} token An OAuth2 access token.
46  * @param {function(string): void} onReady The callback function, called with
47  *     a client JID when WCS has been loaded.
48  * @param {function(!remoting.Error):void} onError Function to invoke with an
49  *     error code on failure.
50  * @return {void} Nothing.
51  */
52 remoting.WcsLoader.prototype.start = function(token, onReady, onError) {
53   var node = document.getElementById(this.SCRIPT_NODE_ID_);
54   if (node) {
55     console.error('Multiple calls to WcsLoader.start are not allowed.');
56     onError(remoting.Error.unexpected());
57     return;
58   }
60   // Create a script node to load the WCS driver.
61   node = document.createElement('script');
62   node.id = this.SCRIPT_NODE_ID_;
63   node.src = remoting.settings.TALK_GADGET_URL + '/iq?access_token=' + token;
64   node.type = 'text/javascript';
65   document.body.insertBefore(node, document.body.firstChild);
67   /** @type {remoting.WcsLoader} */
68   var that = this;
69   var onLoad = function() {
70     that.constructWcs_(token, onReady);
71   };
72   var onLoadError = function(event) {
73     // The DOM Event object has no detail on the nature of the error, so try to
74     // validate the token to get a better idea.
75     /** @param {!remoting.Error} error Error code. */
76     var onValidateError = function(error) {
77       var typedNode = /** @type {Element} */ (node);
78       typedNode.parentNode.removeChild(node);
79       onError(error);
80     };
81     var onValidateOk = function() {
82       // We can reach the authentication server and validate the token. Either
83       // there's something wrong with the talkgadget service, or there is a
84       // cookie problem. Only the cookie problem can be fixed by the user, so
85       // suggest that fix.
86       onValidateError(new remoting.Error(
87           remoting.Error.Tag.AUTHENTICATION_FAILED));
88     };
89     that.validateToken(token, onValidateOk, onValidateError);
90   };
91   node.addEventListener('load', onLoad, false);
92   node.addEventListener('error', onLoadError, false);
95 /**
96  * Constructs the remoting.wcs object.
97  *
98  * @param {string} token An OAuth2 access token.
99  * @param {function(string): void} onReady The callback function, called with
100  *     an OAuth2 access token when WCS has been loaded.
101  * @return {void} Nothing.
102  * @private
103  */
104 remoting.WcsLoader.prototype.constructWcs_ = function(token, onReady) {
105   remoting.wcs = new remoting.Wcs(
106       remoting.wcsLoader.wcsIqClient, token, onReady);
110  * Validates an OAuth2 access token.
112  * @param {string} token The access token.
113  * @param {function():void} onOk Callback to invoke if the token is valid.
114  * @param {function(!remoting.Error):void} onError Function to invoke with an
115  *     error code on failure.
116  * @return {void} Nothing.
117  */
118 remoting.WcsLoader.prototype.validateToken = function(token, onOk, onError) {
119   /** @type {XMLHttpRequest} */
120   var xhr = new XMLHttpRequest();
121   xhr.onreadystatechange = function() {
122     if (xhr.readyState != 4) {
123       return;
124     }
125     if (xhr.status == 200) {
126       onOk();
127     } else {
128       var error = new remoting.Error(remoting.Error.Tag.AUTHENTICATION_FAILED);
129       switch (xhr.status) {
130         case 0:
131           error = new remoting.Error(remoting.Error.Tag.NETWORK_FAILURE);
132           break;
133         case 502: // No break
134         case 503:
135           error = new remoting.Error(remoting.Error.Tag.SERVICE_UNAVAILABLE);
136           break;
137       }
138       onError(error);
139     }
140   };
141   var parameters = '?access_token=' + encodeURIComponent(token);
142   xhr.open('GET',
143            remoting.settings.OAUTH2_API_BASE_URL + '/v1/tokeninfo' + parameters,
144            true);
145   xhr.send(null);