OLD | NEW |
---|---|
(Empty) | |
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 | |
5 cr.define('cloudprint', function() { | |
6 'use strict'; | |
7 | |
8 /** | |
9 * API to the Google Cloud Print service. | |
10 * | |
11 * @param {string} baseUrl Base part of the Google Cloud Print service URL | |
12 * with no trailing slash. For example, | |
13 * 'https://www.google.com/cloudprint'. | |
14 * @constructor | |
15 * @extends {cr.EventTarget} | |
16 */ | |
17 function CloudPrintInterface(baseUrl) { | |
18 /** | |
19 * The base URL of the Google Cloud Print API. | |
20 * @type {string} | |
21 * @private | |
22 */ | |
23 this.baseURL_ = baseUrl; | |
24 | |
25 /** | |
26 * Last received XSRF token. Sent as a parameter in every request. | |
27 * @type {string} | |
28 * @private | |
29 */ | |
30 this.xsrfToken_ = ''; | |
31 }; | |
32 | |
33 /** | |
34 * Enumeration of events dispatched. | |
35 * @enum {string} | |
36 */ | |
37 CloudPrintInterface.Event = { | |
38 ERROR: 'cloudprint.CloudPrintInterface.ERROR', | |
39 PRINTER_DONE: 'cloudprint.CloudPrintInterface.PRINTER_DONE', | |
40 SEARCH_DONE: 'cloudprint.CloudPrintInterface.SEARCH_DONE', | |
41 SUBMIT_DONE: 'cloudprint.CloudPrintInterface.SUBMIT_DONE' | |
42 }; | |
43 | |
44 /** | |
45 * Content type header value for a URL encoded HTTP request. | |
46 * @type {string} | |
47 * @private | |
48 */ | |
49 CloudPrintInterface.URL_ENCODED_CONTENT_TYPE_ = | |
50 'application/x-www-form-urlencoded'; | |
51 | |
52 /** | |
53 * Content type header value for a multipart HTTP request. | |
54 * @type {string} | |
55 * @private | |
56 */ | |
57 CloudPrintInterface.MULTIPART_CONTENT_TYPE_ = | |
58 'multipart/form-data; boundary=----CloudPrintFormBoundaryjc9wuprokl8i'; | |
59 | |
60 CloudPrintInterface.prototype = { | |
61 __proto__: cr.EventTarget.prototype, | |
62 | |
63 /** | |
64 * Sends a Google Cloud Print search API request. | |
65 * @param {boolean} isRecent Whether to search for only recently used | |
66 * printers. | |
67 */ | |
68 search: function(isRecent) { | |
69 var params = {}; | |
70 if (isRecent) { | |
71 params['q'] = '^recent'; | |
72 } | |
73 this.sendRequest_('GET', 'search', params, null, this.onSearchDone_); | |
74 }, | |
75 | |
76 /** | |
77 * Sends a Google Cloud Print submit API request. | |
78 * @param {string} body Body of the HTTP post request to send. | |
79 */ | |
80 submit: function(body) { | |
81 this.sendRequest_('POST', 'submit', null, body, this.onSubmitDone_); | |
82 }, | |
83 | |
84 /** | |
85 * Sends a Google Cloud Print printer API request. | |
86 * @param {string} printerId ID of the printer to lookup. | |
87 */ | |
88 printer: function(printerId) { | |
89 var params = {'printerid': printerId}; | |
90 this.sendRequest_('GET', 'printer', params, null, this.onPrinterDone_); | |
91 }, | |
92 | |
93 /** | |
94 * Creates an object that represents a Google Cloud Print print ticket. | |
95 * @param {!print_preview.Destination} destination Destination to print to. | |
96 * @param {!print_preview.PrintTicketStore} printTicketStore Used to create | |
97 * the state of the print ticket. | |
98 * @return {object} Google Cloud Print print ticket. | |
99 */ | |
100 createPrintTicket: function(destination, printTicketStore) { | |
101 if (destination.isLocal) { | |
102 throw Error( | |
103 'Trying to create a Google Cloud Print print ticket for a local ' + | |
104 'destination'); | |
105 } | |
106 if (!destination.capabilities) { | |
107 throw Error( | |
108 'Trying to create a Google Cloud Print print ticket for a ' + | |
109 'destination with no print capabilities'); | |
110 } | |
111 | |
112 var ticketItems = []; | |
113 | |
114 if (destination.capabilities.collateCapability) { | |
115 var collateCap = destination.capabilities.collateCapability; | |
116 var ticketItem = { | |
117 'name': collateCap.id, | |
118 'type': collateCap.type, | |
119 'options': [{'name': printTicketStore.isCollateEnabled() ? | |
120 collateCap.collateOption : collateCap.noCollateOption}] | |
121 }; | |
122 ticketItems.push(ticketItem); | |
123 } | |
124 | |
125 if (destination.capabilities.colorCapability) { | |
126 var colorCap = destination.capabilities.colorCapability; | |
127 var ticketItem = { | |
128 'name': colorCap.id, | |
129 'type': colorCap.type, | |
130 'options': [{'name': printTicketStore.isColorEnabled() ? | |
131 colorCap.colorOption : colorCap.bwOption}] | |
132 }; | |
133 ticketItems.push(ticketItem); | |
134 } | |
135 | |
136 if (destination.capabilities.copiesCapability) { | |
137 var copiesCap = destination.capabilities.copiesCapability; | |
138 var ticketItem = { | |
139 'name': copiesCap.id, | |
140 'type': copiesCap.type, | |
141 'value': printTicketStore.getCopies() | |
142 }; | |
143 ticketItems.push(ticketItem); | |
144 } | |
145 | |
146 if (destination.capabilities.duplexCapability) { | |
147 var duplexCap = destination.capabilities.duplexCapability; | |
148 var ticketItem = { | |
149 'name': duplexCap.id, | |
150 'type': duplexCap.type, | |
151 'options': [{'name': printTicketStore.isDuplexEnabled() ? | |
152 duplexCap.longEdgeOption : duplexCap.simplexOption}] | |
153 }; | |
154 ticketItems.push(ticketItem); | |
155 } | |
156 | |
157 return { | |
158 'capabilities': ticketItems | |
159 }; | |
160 }, | |
161 | |
162 /** | |
163 * Sends a request to the Google Cloud Print API. | |
164 * @param {string} method HTTP method of the request. | |
165 * @param {string} action Google Cloud Print action to perform. | |
166 * @param {object} params HTTP parameters to include in the request. | |
dpapad
2012/04/24 01:24:56
Why change this? I believe Object is correct (http
Robert Toscano
2012/04/24 22:29:56
Done.
| |
167 * @param {string} body HTTP multi-part encoded body. | |
168 * @param {function(Object)} successCallback Callback to invoke when request | |
169 * completes successfully. | |
170 */ | |
171 sendRequest_: function(method, action, params, body, successCallback) { | |
172 if (!this.xsrfToken_) { | |
173 // TODO Should throw an error if not a read-only action or issue an | |
174 // xsrf token request. | |
175 } | |
176 var url = this.baseURL_ + '/' + action + '?xsrf=' + this.xsrfToken_; | |
177 | |
178 if (params) { | |
179 for (var paramName in params) { | |
180 url += '&' + paramName + '=' + encodeURIComponent(params[paramName]); | |
181 } | |
182 } | |
183 | |
184 var headers = {}; | |
185 headers['X-CloudPrint-Proxy'] = 'ChromePrintPreview'; | |
186 if (method == 'GET') { | |
187 headers['Content-Type'] = CloudPrintInterface.URL_ENCODED_CONTENT_TYPE_; | |
188 } else if (method == 'POST') { | |
189 headers['Content-Type'] = CloudPrintInterface.MULTIPART_CONTENT_TYPE_; | |
190 } | |
191 | |
192 var xhr = new XMLHttpRequest(); | |
193 xhr.onreadystatechange = this.onReadyStateChange_.bind( | |
194 this, xhr, successCallback.bind(this)); | |
195 xhr.open(method, url, true); | |
196 xhr.withCredentials = true; | |
197 for (var header in headers) { | |
198 xhr.setRequestHeader(header, headers[header]); | |
199 } | |
200 xhr.send(body); | |
201 }, | |
202 | |
203 /** | |
204 * Dispatches an ERROR event with the given error message. | |
205 * @param {string} message Error message to include in the ERROR event. | |
206 * @private | |
207 */ | |
208 dispatchErrorEvent_: function(message) { | |
209 var errorEvt = new cr.Event(CloudPrintInterface.Event.ERROR); | |
210 errorEvt.message = message; | |
211 this.dispatchEvent(errorEvt); | |
212 }, | |
213 | |
214 /** | |
215 * Called when the ready-state of a XML http request changes. | |
216 * Calls the successCallback with the result or dispatches an ERROR event. | |
217 * @param {XMLHttpRequest} xhr XML http request that changed. | |
218 * @param {function(Object)} successCallback Callback to call if the request | |
219 * was successful. | |
220 * @private | |
221 */ | |
222 onReadyStateChange_: function(xhr, successCallback) { | |
223 if (xhr.readyState == 4) { | |
224 if (xhr.status == 200) { | |
225 var result = JSON.parse(xhr.responseText); | |
226 if (result['success']) { | |
227 this.xsrfToken_ = result['xsrf_token']; | |
228 successCallback(result); | |
229 } else { | |
230 this.dispatchErrorEvent_(result['message']); | |
231 } | |
232 } else { | |
233 this.dispatchErrorEvent_(xhr.status + ''); | |
234 } | |
235 } | |
236 }, | |
237 | |
238 /** | |
239 * Called when the search request completes successfully. | |
240 * @param {Object} result JSON response. | |
241 * @private | |
242 */ | |
243 onSearchDone_: function(result) { | |
244 var printerListJson = result['printers'] || []; | |
245 var printerList = []; | |
246 for (var printerJson, i = 0; printerJson = printerListJson[i]; i++) { | |
247 try { | |
248 printerList.push(cloudprint.CloudDestinationParser.parse( | |
249 printerJson)); | |
250 } catch (err) { | |
251 // TODO | |
252 } | |
253 } | |
254 var isRecent = result['request']['params']['q'] == '^recent'; | |
255 var searchDoneEvt = new cr.Event(CloudPrintInterface.Event.SEARCH_DONE); | |
256 searchDoneEvt.printers = printerList; | |
257 searchDoneEvt.isRecent = isRecent; | |
258 searchDoneEvt.email = result['request']['user']; | |
259 this.dispatchEvent(searchDoneEvt); | |
260 }, | |
261 | |
262 /** | |
263 * Called when the submit request completes successfully. | |
264 * @param {Object} result JSON response. | |
265 * @private | |
266 */ | |
267 onSubmitDone_: function(result) { | |
268 this.dispatchEvent(new cr.Event(CloudPrintInterface.Event.SUBMIT_DONE)); | |
269 }, | |
270 | |
271 /** | |
272 * Called when the printer request completes successfully. | |
273 * @param {Object} result JSON response. | |
274 * @private | |
275 */ | |
276 onPrinterDone_: function(result) { | |
277 // TODO Better error handling here. | |
278 var printerJson = result['printers'][0]; | |
279 var printer; | |
280 try { | |
281 printer = cloudprint.CloudDestinationParser.parse(printerJson); | |
282 } catch (err) { | |
283 // TODO | |
284 return; | |
285 } | |
286 var printerDoneEvt = new cr.Event(CloudPrintInterface.Event.PRINTER_DONE); | |
287 printerDoneEvt.printer = printer; | |
288 this.dispatchEvent(printerDoneEvt); | |
289 } | |
290 }; | |
291 | |
292 // Export | |
293 return { | |
294 CloudPrintInterface: CloudPrintInterface | |
295 }; | |
296 }); | |
OLD | NEW |