Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / remoting / webapp / wcs_sandbox_content.js
blobb97f6a4c6dc8eee2c2d72cd0d40a6e0c6c1227b1
1 /* Copyright 2013 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 * The sandbox side of the application/sandbox WCS interface, used by the
9 * sandbox to exchange messages with the application.
12 'use strict';
14 /** @suppress {duplicate} */
15 var remoting = remoting || {};
17 /** @constructor */
18 remoting.WcsSandboxContent = function() {
19 /**
20 * @type {Window}
21 * @private
23 this.parentWindow_ = null;
24 /**
25 * @type {number}
26 * @private
28 this.nextXhrId_ = 0;
29 /**
30 * @type {Object.<number, XMLHttpRequest>}
31 * @private
33 this.pendingXhrs_ = {};
35 window.addEventListener('message', this.onMessage_.bind(this), false);
38 /**
39 * Event handler to process messages from the application.
41 * @param {Event} event
43 remoting.WcsSandboxContent.prototype.onMessage_ = function(event) {
44 this.parentWindow_ = event.source;
46 switch (event.data['command']) {
48 case 'sendIq':
49 /** @type {string} */
50 var stanza = event.data['stanza'];
51 if (stanza === undefined) {
52 console.error('sendIq: missing IQ stanza.');
53 break;
55 if (remoting.wcs) {
56 remoting.wcs.sendIq(stanza);
57 } else {
58 console.error('Dropping IQ stanza:', stanza);
60 break;
62 case 'setAccessToken':
63 /** @type {string} */
64 var token = event.data['token'];
65 if (token === undefined) {
66 console.error('setAccessToken: missing access token.');
67 break;
69 // The WCS driver JS requires that remoting.wcsLoader be a global
70 // variable, so it can't be a member of this class.
71 // TODO(jamiewalch): remoting.wcs doesn't need to be global and should
72 // be made a member (http://crbug.com/172348).
73 if (remoting.wcs) {
74 remoting.wcs.updateAccessToken(token);
75 } else if (!remoting.wcsLoader) {
76 remoting.wcsLoader = new remoting.WcsLoader();
77 remoting.wcsLoader.start(token,
78 this.onReady_.bind(this),
79 this.onError_.bind(this));
81 break;
83 case 'xhrStateChange':
84 /** @type {number} */
85 var id = event.data['id'];
86 if (id === undefined) {
87 console.error('xhrStateChange: missing id.');
88 break;
90 var pendingXhr = this.pendingXhrs_[id];
91 if (!pendingXhr) {
92 console.error('xhrStateChange: unrecognized id:', id);
93 break;
95 /** @type {XMLHttpRequest} */
96 var xhr = event.data['xhr'];
97 if (xhr === undefined) {
98 console.error('xhrStateChange: missing xhr');
99 break;
101 for (var member in xhr) {
102 pendingXhr[member] = xhr[member];
104 if (xhr.readyState == 4) {
105 delete this.pendingXhrs_[id];
107 if (pendingXhr.onreadystatechange) {
108 pendingXhr.onreadystatechange();
110 break;
112 default:
113 console.error('Unexpected message:', event.data['command'], event.data);
118 * Callback method to indicate that the WCS driver has loaded and provide the
119 * full JID of the client.
121 * @param {string} clientJid The full JID of the WCS client.
122 * @private
124 remoting.WcsSandboxContent.prototype.onReady_ = function(clientJid) {
125 remoting.wcs.setOnIq(this.onIq_.bind(this));
126 var message = {
127 'command': 'onReady',
128 'clientJid': clientJid
130 this.parentWindow_.postMessage(message, '*');
134 * Callback method to indicate that something went wrong loading the WCS driver.
136 * @param {remoting.Error} error Details of the error.
137 * @private
139 remoting.WcsSandboxContent.prototype.onError_ = function(error) {
140 var message = {
141 'command': 'onError',
142 'error': error
144 this.parentWindow_.postMessage(message, '*');
148 * Forward an XHR to the container process to send. This is analogous to XHR's
149 * send method.
151 * @param {remoting.XMLHttpRequestProxy} xhr The XHR to send.
152 * @return {number} The unique ID allocated to the XHR. Used to abort it.
154 remoting.WcsSandboxContent.prototype.sendXhr = function(xhr) {
155 var id = this.nextXhrId_++;
156 this.pendingXhrs_[id] = xhr;
157 var message = {
158 'command': 'sendXhr',
159 'id': id,
160 'parameters': xhr.sandbox_ipc
162 this.parentWindow_.postMessage(message, '*');
163 delete xhr.sandbox_ipc;
164 return id;
168 * Abort a forwarded XHR. This is analogous to XHR's abort method.
170 * @param {number} id The unique ID of the XHR to abort, as returned by sendXhr.
172 remoting.WcsSandboxContent.prototype.abortXhr = function(id) {
173 if (!this.pendingXhrs_[id]) {
174 // The XHR is removed when it reaches the "ready" state. Calling abort
175 // subsequently is unusual, but legal, so just silently ignore the request
176 // in this case.
177 return;
179 var message = {
180 'command': 'abortXhr',
181 'id': id
183 this.parentWindow_.postMessage(message, '*');
187 * Callback to indicate than an IQ stanza has been received from the WCS
188 * driver, and should be forwarded to the main process.
190 * @param {string} stanza
191 * @private
193 remoting.WcsSandboxContent.prototype.onIq_ = function(stanza) {
194 remoting.wcs.setOnIq(this.onIq_.bind(this));
195 var message = {
196 'command': 'onIq',
197 'stanza': stanza
199 this.parentWindow_.postMessage(message, '*');
203 * Entry point for the WCS sandbox process.
205 function onSandboxInit() {
206 // The WCS code registers for a couple of events that aren't supported in
207 // Apps V2, so ignore those for now.
208 var oldAEL = window.addEventListener;
209 window.addEventListener = function(type, listener, useCapture) {
210 if (type == 'beforeunload' || type == 'unload') {
211 return;
213 oldAEL(type, listener, useCapture);
216 remoting.settings = new remoting.Settings();
217 remoting.sandboxContent = new remoting.WcsSandboxContent();
220 window.addEventListener('load', onSandboxInit, false);
222 /** @type {remoting.WcsSandboxContent} */
223 remoting.sandboxContent = null;