Index: chrome/browser/resources/print_preview/print_preview_cloud.js |
diff --git a/chrome/browser/resources/print_preview/print_preview_cloud.js b/chrome/browser/resources/print_preview/print_preview_cloud.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c1908f8ec979a39142875234e06ad9758f30c8a6 |
--- /dev/null |
+++ b/chrome/browser/resources/print_preview/print_preview_cloud.js |
@@ -0,0 +1,364 @@ |
+// Copyright (c) 2011 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. |
+ |
+cr.define('cloudprint', function() { |
+ |
+ // The URL to use to access the cloud print servers. |
+ // Set by a call to setBaseURL. |
+ var cloudPrintBaseURL = ''; |
+ |
+ // Headers to set for most cloud print API calls. |
+ var xCloudPrintURLHeader = {'Content-Type': |
+ 'application/x-www-form-urlencoded', |
+ 'X-CloudPrint-Proxy': 'ChromePrintPreview'}; |
+ |
+ // Headers to set when sending multipart data to cloud print APIs. |
+ // Currently only used when submitting a job. |
+ var xCloudPrintFormHeader = {'Content-Type': |
+ 'multipart/form-data; boundary=----CloudPrintFormBoundaryjc9wuprokl8i', |
+ 'X-CloudPrint-Proxy': 'ChromePrintPreview'}; |
+ |
+ // The last received XSRF token. This should be sent with each request |
+ // to prevent XSRF. |
+ var lastXSRFToken = ''; |
+ |
+ /** |
+ * Sets the base URL to be used for communicating with cloud print |
+ * servers. |
+ * @param {string} cloudPrintURL The URL to use. |
+ */ |
+ function setBaseURL(cloudPrintURL) { |
+ cloudPrintBaseURL = cloudPrintURL; |
+ } |
+ |
+ /** |
+ * Gets the base URL to be used for communicating with cloud print |
+ * servers. |
+ * @return {string} The URL. |
+ */ |
+ function getBaseURL() { |
+ return cloudPrintBaseURL; |
+ } |
+ |
+ /** |
+ * Extracts the XSRF token from each response to be used in the next |
+ * request. |
+ * @param {XMLHttpRequest} xhr The object used to make the request. |
+ * @return {string} The extracted XSRF token. |
+ */ |
+ function extractXSRFtoken(xhr) { |
+ if (xhr.status == 200) { |
+ var result = JSON.parse(xhr.responseText); |
+ return result['xsrf_token']; |
+ } else { |
+ return null; |
+ } |
+ } |
+ |
+ /** |
+ * Makes a request to cloud print servers. |
+ * @param {string} method The HTTP method to be used. |
+ * @param {string} action The cloud print API to call. |
+ * @param {Array} headers Headers to send with the request. |
+ * @param {string} body Body to be sent with POST requests. |
+ * @param {function} callback Function to be called to process response. |
+ * @param {boolean} async True if we want the request made asyncronously. |
+ */ |
+ function sendCloudPrintRequest(method, |
+ action, |
+ headers, |
+ params, |
+ body, |
+ callback) { |
+ var xhr = new XMLHttpRequest(); |
+ if (callback != null) { |
+ xhr.onreadystatechange = function() { |
+ if (xhr.readyState == 4) { |
+ var updatedXSRFToken = extractXSRFtoken(xhr); |
+ if (updatedXSRFToken != null) { |
+ lastXSRFToken = updatedXSRFToken; |
+ } |
+ callback.call(this, xhr); |
+ } |
+ }; |
+ } |
+ var url = cloudPrintBaseURL + '/' + action; |
+ if (params == null) { |
+ params = new Array; |
+ } |
+ if (lastXSRFToken.length != 0) { |
+ params.push("xsrf=" + lastXSRFToken); |
+ } |
+ if (params.length != 0) { |
+ url = url + "?"; |
+ for (param in params) { |
+ url = url + params[param] + "&"; |
+ } |
+ } |
+ xhr.open(method, url, true); |
+ xhr.withCredentials = true; |
+ if (headers) { |
+ for (var header in headers) { |
+ if (headers.hasOwnProperty(header)) { |
+ xhr.setRequestHeader(header, headers[header]); |
+ } |
+ } |
+ } |
+ xhr.send(body); |
+ return xhr; |
+ } |
+ |
+ /** |
+ * Parse the response from the fetchPrinters call. |
+ * @param {function} callback Function to be called to process response. |
+ * @param {XMLHttpRequest} xhr The object used to make the request. |
+ */ |
+ function fetchPrintersResponse(callback, xhr) { |
+ if (xhr.status == 200) { |
+ var searchResult = JSON.parse(xhr.responseText); |
+ if (searchResult['success']) { |
+ var printerList = searchResult['printers']; |
+ callback.call(this, printerList, false); |
+ } else { |
+ callback.call(this, null, false); |
+ } |
+ } else { |
+ callback.call(this, null, false); |
+ } |
+ } |
+ |
+ /** |
+ * Retrieve the list of printers available via cloud print. |
+ * @param {function} callback Function to be called to process response. |
+ */ |
+ function fetchPrinters(callback, all) { |
+ var query = 'q=^recent'; |
+ if (all) { |
+ query = ''; |
+ } |
+ sendCloudPrintRequest('GET', |
+ 'search', |
+ xCloudPrintURLHeader, |
+ [query], |
+ null, |
+ fetchPrintersResponse.bind(this, callback)); |
+ } |
+ |
+ /** |
+ * Handle the response from printing to cloud print. |
+ * @param {function} callback Function to be called to process response. |
+ * @param {XMLHttpRequest} xhr The object used to make the request. |
+ */ |
+ function printToCloudResponse(callback, xhr) { |
+ if (xhr.status == 200) { |
+ var printResult = JSON.parse(xhr.responseText); |
+ if (printResult['success']) { |
+ callback.call(); |
+ } |
+ } |
+ // TODO(abodenha@chromium.org) Catch and handle failures. |
+ } |
+ |
+ /** |
+ * Send the current document to cloud print. |
+ * @param {string} data The document to be printed. |
+ * @param {function} callback Function to be called to process response. |
+ */ |
+ function printToCloud(data, callback) { |
+ // TODO(abodenha@chromium.org) Make sure we have an XSRF token before |
+ // sending a submit. Right now if the user clicks print before we |
+ // complete any request we wont have an XSRF and the submit will fail. |
+ sendCloudPrintRequest('POST', |
+ 'submit', |
+ xCloudPrintFormHeader, |
+ null, |
+ data, |
+ printToCloudResponse.bind(this, callback)); |
+ } |
+ |
+ /** |
+ * Gets the JSON string used to control the behavior of the current |
+ * print job. |
+ * @param {Object} printer The printer object to get the ticket for. |
+ * @return {string} The print ticket or null if not a cloud printer. |
+ */ |
+ function getPrintTicketJSON(printer) { |
+ if (isCloudPrint(printer)) { |
+ return JSON.stringify({'capabilities': |
+ [printer.cloudPrintOptions.colorOption]}); |
+ } else { |
+ return null; |
+ } |
+ } |
+ |
+ /** |
+ * Process the response from cloud print containing the capabilities |
+ * for the printer. |
+ * @param {function} callback Function to be called to process response. |
+ * @param {Object} printer The printer object to get the capabilites for. |
+ * @param {XMLHttpRequest} xhr The object used to make the request. |
+ */ |
+ function updatePrinterCapsResponse(callback, printer, xhr) { |
+ if (xhr.status == 200) { |
+ var printResult = JSON.parse(xhr.responseText); |
+ if (printResult['success']) { |
+ if (!printer.cloudPrintOptions) |
+ printer.cloudPrintOptions = new Object; |
+ printer.cloudPrintOptions.capsDownloaded = true; |
+ printer.cloudPrintOptions.colorOption = null; |
+ printer.cloudPrintOptions.colorIsDefault = false; |
+ var detailedCapabilities = printResult.printers[0].capabilities; |
+ for (var capability in detailedCapabilities) { |
+ var cap = detailedCapabilities[capability]; |
+ if (cap.name == 'ns1:Colors') { |
+ printer.cloudPrintOptions.colorOption = new Object; |
+ printer.cloudPrintOptions.colorOption.name = cap.name; |
+ printer.cloudPrintOptions.colorOption.type = cap.type; |
+ for (var option in cap.options) { |
+ var opt = cap.options[option]; |
+ if (opt.name == "Color") { |
+ printer.cloudPrintOptions.colorOnOption = opt; |
+ } |
+ if (opt.name == "Grey_K") { |
+ printer.cloudPrintOptions.colorOffOption = opt; |
+ } |
+ if (opt.default) { |
+ printer.cloudPrintOptions.colorOption.options = [opt]; |
+ printer.cloudPrintOptions.colorIsDefault = |
+ opt.name == printer.cloudPrintOptions.colorOnOption.name; |
+ } |
+ } |
+ } |
+ } |
+ callback.call(this, printer); |
+ } |
+ } |
+ } |
+ |
+ /** |
+ * Retrieve capabilities for a printer. |
+ * @param {Object} printer The printer object to get the capabilities for. |
+ * @param {function} callback Function to be called to process response. |
+ */ |
+ function updatePrinterCaps(printer, callback) { |
+ if (isCloudPrint(printer) && !printer.cloudPrintOptions.capsDownloaded) { |
+ sendCloudPrintRequest('GET', |
+ 'printer?printerid=' + |
+ printer.value + |
+ '&output=json', |
+ xCloudPrintURLHeader, |
+ null, |
+ null, |
+ updatePrinterCapsResponse.bind(this, |
+ callback, |
+ printer)); |
+ } else { |
+ callback.call(this, printer); |
+ } |
+ } |
+ |
+ /** |
+ * @param {Object} printer The printer object to get the data for. |
+ * @return {boolean} true if the printer supports color. |
+ */ |
+ function supportsColor(printer) { |
+ return isCloudPrint(printer) && |
+ printer.cloudPrintOptions.colorOption != null; |
+ } |
+ |
+ /** |
+ * @param {Object} printer The printer object to get the data for. |
+ * @return {boolean} true if the printer defaults to color. |
+ */ |
+ function colorIsDefault(printer) { |
+ return isCloudPrint(printer) && |
+ printer.cloudPrintOptions.colorIsDefault; |
+ } |
+ |
+ /** |
+ * Turn color on or off for the specified printer. |
+ * @param {Object} printer The printer object to turn color on/off for. |
+ * @param {boolean} color True to turn color on. |
+ */ |
+ function setColor(printer, color) { |
+ if (isCloudPrint(printer) && supportsColor(printer)) { |
+ if (color) { |
+ printer.cloudPrintOptions.colorOption.options = |
+ [printer.cloudPrintOptions.colorOnOption]; |
+ } else { |
+ printer.cloudPrintOptions.colorOption.options = |
+ [printer.cloudPrintOptions.colorOffOption]; |
+ } |
+ } |
+ } |
+ |
+ /** Creates a cloud print printer and sets it as the default printer. |
+ * @param {string} printer_name The name of the printer to create. |
+ * @param {Object} cloud_print_data Data to be stored in cloudPrintOptions. |
+ * @param {function} add_callback The callback to be called to add the new |
+ * printer to the print preview UI. |
+ * @param {function} update_caps_callback The callback to be called to update |
+ * capabilities on the new printer. |
+ */ |
+ function setDefaultPrinter(printer_name, |
+ cloud_print_data, |
+ add_callback, |
+ update_caps_callback) { |
+ var printer = add_callback([JSON.parse(cloud_print_data)], false); |
+ if (printer) |
+ update_caps_callback(printer); |
+ } |
+ |
+ /** Returns the data necessary to serialize a cloud print printer. |
+ * @param {Object} printer The printer object to get data for. |
+ * @return {string} A JSON string that can be used to recreate the |
+ * cloud print portion of the printer object, or |
+ * an empty string if there is no data to save. |
+ */ |
+ function getData(printer) { |
+ if (isCloudPrint(printer)) { |
+ return JSON.stringify(printer.cloudPrintOptions); |
+ } else { |
+ return ""; |
+ } |
+ } |
+ |
+ /** Test if a printer is a cloud print printer. |
+ * @param {Object} printer The printer to test. |
+ * @return {boolean} true iff the printer is a cloud print printer. |
+ */ |
+ function isCloudPrint(printer) { |
+ return printer && printer.cloudPrintOptions != null; |
+ } |
+ |
+ /** Mark a printer as a cloud print printer and record its name and id. |
+ * @param {Object} printer The printer to mark. |
+ * @param {string} name The user visible name of the printer. |
+ * @param {string} id The id of the printer used by cloud print to |
+ * identify it. |
+ */ |
+ function setCloudPrint(printer, name, id) { |
+ if (!printer.cloudPrintOptions) { |
+ printer.cloudPrintOptions = new Object; |
+ } |
+ printer.cloudPrintOptions.name = name; |
+ printer.cloudPrintOptions.id = id; |
+ } |
+ |
+ return { |
+ colorIsDefault: colorIsDefault, |
+ fetchPrinters: fetchPrinters, |
+ getBaseURL: getBaseURL, |
+ getData: getData, |
+ getPrintTicketJSON: getPrintTicketJSON, |
+ isCloudPrint: isCloudPrint, |
+ printToCloud: printToCloud, |
+ setBaseURL: setBaseURL, |
+ setCloudPrint: setCloudPrint, |
+ setColor: setColor, |
+ setDefaultPrinter: setDefaultPrinter, |
+ supportsColor: supportsColor, |
+ updatePrinterCaps: updatePrinterCaps |
+ }; |
+}); |