1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/**
* @fileoverview
* A class that loads a WCS IQ client and constructs remoting.wcs as a
* wrapper for it.
*/
'use strict';
/** @suppress {duplicate} */
var remoting = remoting || {};
/** @type {remoting.WcsLoader} */
remoting.wcsLoader = null;
/**
* @constructor
*/
remoting.WcsLoader = function() {
/**
* The WCS client that will be downloaded. This variable is initialized (via
* remoting.wcsLoader) by the downloaded Javascript.
* @type {remoting.WcsIqClient}
*/
this.wcsIqClient = null;
};
/**
* Load WCS if necessary, then invoke the callback with an access token.
*
* @param {function(string): void} onReady The callback function, called with
* an OAuth2 access token when WCS has been loaded.
* @param {function(remoting.Error):void} onError Function to invoke with an
* error code on failure.
* @return {void} Nothing.
*/
remoting.WcsLoader.load = function(onReady, onError) {
if (!remoting.wcsLoader) {
remoting.wcsLoader = new remoting.WcsLoader();
}
/** @param {string} token The OAuth2 access token. */
var start = function(token) {
remoting.wcsLoader.start_(token, onReady, onError);
};
remoting.oauth2.callWithToken(start, onError);
};
/**
* The URL of the GTalk gadget.
* @type {string}
* @private
*/
remoting.WcsLoader.prototype.TALK_GADGET_URL_ =
'https://chromoting-client.talkgadget.google.com/talkgadget/';
/**
* The id of the script node.
* @type {string}
* @private
*/
remoting.WcsLoader.prototype.SCRIPT_NODE_ID_ = 'wcs-script-node';
/**
* The attribute name indicating that the WCS has finished loading.
* @type {string}
* @private
*/
remoting.WcsLoader.prototype.SCRIPT_NODE_LOADED_FLAG_ = 'wcs-script-loaded';
/**
* Starts loading the WCS IQ client.
*
* When it's loaded, construct remoting.wcs as a wrapper for it.
* When the WCS connection is ready, or on error, call |onReady| or |onError|,
* respectively.
*
* @param {string} token An OAuth2 access token.
* @param {function(string): void} onReady The callback function, called with
* an OAuth2 access token when WCS has been loaded.
* @param {function(remoting.Error):void} onError Function to invoke with an
* error code on failure.
* @return {void} Nothing.
* @private
*/
remoting.WcsLoader.prototype.start_ = function(token, onReady, onError) {
var node = document.getElementById(this.SCRIPT_NODE_ID_);
if (!node) {
// The first time, there will be no script node, so create one.
node = document.createElement('script');
node.id = this.SCRIPT_NODE_ID_;
node.src = this.TALK_GADGET_URL_ + 'iq?access_token=' + token;
node.type = 'text/javascript';
document.body.insertBefore(node, document.body.firstChild);
} else if (node.hasAttribute(this.SCRIPT_NODE_LOADED_FLAG_)) {
// Subsequently, explicitly invoke onReady if onload has already fired.
// TODO(jamiewalch): It's possible that the WCS client has not finished
// initializing. Add support for multiple callbacks to the remoting.Wcs
// class to address this.
onReady(token);
return;
}
/** @type {remoting.WcsLoader} */
var that = this;
var onLoad = function() {
var typedNode = /** @type {Element} */ (node);
typedNode.setAttribute(that.SCRIPT_NODE_LOADED_FLAG_, true);
that.constructWcs_(token, onReady);
};
var onLoadError = function(event) {
// The DOM Event object has no detail on the nature of the error, so try to
// validate the token to get a better idea.
/** @param {remoting.Error} error Error code. */
var onValidateError = function(error) {
var typedNode = /** @type {Element} */ (node);
typedNode.parentNode.removeChild(node);
onError(error);
};
var onValidateOk = function() {
// We can reach the authentication server and validate the token. Either
// there's something wrong with the talkgadget service, or there is a
// cookie problem. Only the cookie problem can be fixed by the user, so
// suggest that fix.
onValidateError(remoting.Error.AUTHENTICATION_FAILED);
}
remoting.oauth2.validateToken(token, onValidateOk, onValidateError);
}
node.addEventListener('load', onLoad, false);
node.addEventListener('error', onLoadError, false);
};
/**
* Constructs the remoting.wcs object.
*
* @param {string} token An OAuth2 access token.
* @param {function(string): void} onReady The callback function, called with
* an OAuth2 access token when WCS has been loaded.
* @return {void} Nothing.
* @private
*/
remoting.WcsLoader.prototype.constructWcs_ = function(token, onReady) {
remoting.wcs = new remoting.Wcs(
remoting.wcsLoader.wcsIqClient,
token,
function() { onReady(token); });
};
|