destination_store.js revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)cr.define('print_preview', function() { 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'use strict'; 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A data store that stores destinations and dispatches events when the data 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * store changes. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!print_preview.NativeLayer} nativeLayer Used to fetch local print 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destinations. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!print_preview.AppState} appState Application state. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @constructor 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extends {cr.EventTarget} 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function DestinationStore(nativeLayer, appState) { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.EventTarget.call(this); 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Used to fetch local print destinations. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!print_preview.NativeLayer} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.nativeLayer_ = nativeLayer; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Used to load and persist the selected destination. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!print_preview.AppState} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appState_ = appState; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Internal backing store for the data store. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!Array.<!print_preview.Destination>} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.destinations_ = []; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Cache used for constant lookup of destinations by ID. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {object.<string, !print_preview.Destination>} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.destinationMap_ = {}; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Currently selected destination. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {print_preview.Destination} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectedDestination_ = null; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initial destination ID used to auto-select the first inserted destination 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that matches. If {@code null}, the first destination inserted into the 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * store will be selected. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {?string} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.initialDestinationId_ = null; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Whether the initial destination is a local one or not. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {boolean} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isInitialDestinationLocal_ = true; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Whether the destination store will auto select the destination that 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * matches the initial destination. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {boolean} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isInAutoSelectMode_ = false; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Event tracker used to track event listeners of the destination store. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {!EventTracker} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tracker_ = new EventTracker(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Used to fetch cloud-based print destinations. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {print_preview.CloudPrintInterface} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cloudPrintInterface_ = null; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Whether the destination store has already loaded or is loading all cloud 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destinations. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {boolean} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.hasLoadedAllCloudDestinations_ = false; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ID of a timeout after the initial destination ID is set. If no inserted 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination matches the initial destination ID after the specified 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * timeout, the first destination in the store will be automatically 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * selected. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {?number} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.autoSelectTimeout_ = null; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Whether a search for local destinations is in progress. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {boolean} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isLocalDestinationSearchInProgress_ = false; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.addEventListeners_(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.reset_(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Event types dispatched by the data store. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @enum {string} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore.EventType = { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DESTINATION_SEARCH_DONE: 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'print_preview.DestinationStore.DESTINATION_SEARCH_DONE', 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DESTINATION_SEARCH_STARTED: 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'print_preview.DestinationStore.DESTINATION_SEARCH_STARTED', 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DESTINATION_SELECT: 'print_preview.DestinationStore.DESTINATION_SELECT', 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DESTINATIONS_INSERTED: 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'print_preview.DestinationStore.DESTINATIONS_INSERTED', 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SELECTED_DESTINATION_CAPABILITIES_READY: 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'print_preview.DestinationStore.SELECTED_DESTINATION_CAPABILITIES_READY' 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Delay in milliseconds before the destination store ignores the initial 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination ID and just selects any printer (since the initial destination 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * was not found). 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type {number} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @const 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore.AUTO_SELECT_TIMEOUT_ = 15000; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Creates a local PDF print destination. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {!print_preview.Destination} Created print destination. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore.createLocalPdfPrintDestination_ = function() { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var dest = new print_preview.Destination( 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_preview.Destination.GooglePromotedId.SAVE_AS_PDF, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_preview.Destination.Type.LOCAL, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) print_preview.Destination.AuthType.LOCAL, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) localStrings.getString('printToPDF'), 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /*isRecent*/, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_preview.Destination.ConnectionStatus.ONLINE); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest.capabilities = new print_preview.ChromiumCapabilities( 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /*hasCopiesCapability*/, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '1' /*defaultCopiesStr*/, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /*hasCollateCapability*/, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /*defaultIsCollateEnabled*/, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /*hasDuplexCapability*/, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /*defaultIsDuplexEnabled*/, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true /*hasOrientationCapability*/, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false /*defaultIsLandscapeEnabled*/, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true /*hasColorCapability*/, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true /*defaultIsColorEnabled*/); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dest; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore.prototype = { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __proto__: cr.EventTarget.prototype, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {!Array.<!print_preview.Destination>} List of destinations in 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the store. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get destinations() { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.destinations_.slice(0); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {print_preview.Destination} The currently selected destination or 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * {@code null} if none is selected. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get selectedDestination() { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.selectedDestination_; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} Whether a search for local destinations is in progress. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get isLocalDestinationSearchInProgress() { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.isLocalDestinationSearchInProgress_; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} Whether a search for cloud destinations is in progress. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get isCloudDestinationSearchInProgress() { 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this.cloudPrintInterface_ && 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.cloudPrintInterface_.isCloudDestinationSearchInProgress; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initializes the destination store. Sets the initially selected 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination. If any inserted destinations match this ID, that destination 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will be automatically selected. This method must be called after the 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * print_preview.AppState has been initialized. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {?string} systemDefaultDestinationId ID of the system default 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init: function(systemDefaultDestinationId) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.appState_.selectedDestinationId) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.initialDestinationId_ = this.appState_.selectedDestinationId; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isInitialDestinationLocal_ = 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appState_.isSelectedDestinationLocal; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.initialDestinationId_ = systemDefaultDestinationId; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isInitialDestinationLocal_ = true; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isInAutoSelectMode_ = true; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.initialDestinationId_ == null) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(this.destinations_.length > 0, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'No destinations available to select'); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectDestination(this.destinations_[0]); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var candidate = this.destinationMap_[this.initialDestinationId_]; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (candidate != null) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectDestination(candidate); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!cr.isChromeOS && this.isInitialDestinationLocal_) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.nativeLayer_.startGetLocalDestinationCapabilities( 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.initialDestinationId_); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Sets the destination store's Google Cloud Print interface. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!print_preview.CloudPrintInterface} cloudPrintInterface Interface 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to set. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setCloudPrintInterface: function(cloudPrintInterface) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cloudPrintInterface_ = cloudPrintInterface; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tracker_.add( 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cloudPrintInterface_, 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cloudprint.CloudPrintInterface.EventType.SEARCH_DONE, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onCloudPrintSearchDone_.bind(this)); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tracker_.add( 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cloudPrintInterface_, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cloudprint.CloudPrintInterface.EventType.SEARCH_FAILED, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onCloudPrintSearchFailed_.bind(this)); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tracker_.add( 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cloudPrintInterface_, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cloudprint.CloudPrintInterface.EventType.PRINTER_DONE, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onCloudPrintPrinterDone_.bind(this)); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tracker_.add( 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cloudPrintInterface_, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cloudprint.CloudPrintInterface.EventType.PRINTER_FAILED, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onCloudPrintPrinterFailed_.bind(this)); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fetch initial destination if its a cloud destination. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.isInAutoSelectMode_ && !this.isInitialDestinationLocal_) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cloudPrintInterface_.printer(this.initialDestinationId_); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} Whether only default cloud destinations have been 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * loaded. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hasOnlyDefaultCloudDestinations: function() { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.destinations_.every(function(dest) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dest.isLocal || 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest.id == print_preview.Destination.GooglePromotedId.DOCS || 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest.id == print_preview.Destination.GooglePromotedId.FEDEX; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** @param {!print_preview.Destination} Destination to select. */ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selectDestination: function(destination) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectedDestination_ = destination; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectedDestination_.isRecent = true; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isInAutoSelectMode_ = false; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.autoSelectTimeout_ != null) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clearTimeout(this.autoSelectTimeout_); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.autoSelectTimeout_ = null; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (destination.id == print_preview.Destination.GooglePromotedId.FEDEX && 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !destination.isTosAccepted) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(this.cloudPrintInterface_ != null, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Selected FedEx Office destination, but Google Cloud Print is ' + 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'not enabled'); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destination.isTosAccepted = true; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cloudPrintInterface_.updatePrinterTosAcceptance(destination.id, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.appState_.persistSelectedDestination(this.selectedDestination_); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, DestinationStore.EventType.DESTINATION_SELECT); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (destination.capabilities == null) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (destination.isLocal) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.nativeLayer_.startGetLocalDestinationCapabilities( 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destination.id); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(this.cloudPrintInterface_ != null, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Selected destination is a cloud destination, but Google ' + 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'Cloud Print is not enabled'); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.cloudPrintInterface_.printer(destination.id); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore.EventType.SELECTED_DESTINATION_CAPABILITIES_READY); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Inserts a print destination to the data store and dispatches a 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DESTINATIONS_INSERTED event. If the destination matches the initial 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination ID, then the destination will be automatically selected. 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!print_preview.Destination} destination Print destination to 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * insert. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insertDestination: function(destination) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.insertDestination_(destination)) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, DestinationStore.EventType.DESTINATIONS_INSERTED); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.isInAutoSelectMode_ && 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this.initialDestinationId_ == null || 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destination.id == this.initialDestinationId_)) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectDestination(destination); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Inserts multiple print destinations to the data store and dispatches one 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DESTINATIONS_INSERTED event. If any of the destinations match the initial 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination ID, then that destination will be automatically selected. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!Array.<print_preview.Destination>} destinations Print 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destinations to insert. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insertDestinations: function(destinations) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var insertedDestination = false; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var destinationToAutoSelect = null; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destinations.forEach(function(dest) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.insertDestination_(dest)) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insertedDestination = true; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.isInAutoSelectMode_ && 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destinationToAutoSelect == null && 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this.initialDestinationId_ == null || 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest.id == this.initialDestinationId_)) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destinationToAutoSelect = dest; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, this); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (insertedDestination) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, DestinationStore.EventType.DESTINATIONS_INSERTED); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (destinationToAutoSelect != null) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectDestination(destinationToAutoSelect); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Updates an existing print destination with capabilities information. If 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the destination doesn't already exist, it will be added. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {!print_preview.Destination} destination Destination to update. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {!print_preview.Destination} The existing destination that was 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * updated. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updateDestination: function(destination) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var existingDestination = this.destinationMap_[destination.id]; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existingDestination != null) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existingDestination.capabilities = destination.capabilities; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return existingDestination; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.insertDestination(destination); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** Initiates loading of local print destinations. */ 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) startLoadLocalDestinations: function() { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.nativeLayer_.startGetLocalDestinations(); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isLocalDestinationSearchInProgress_ = true; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, DestinationStore.EventType.DESTINATION_SEARCH_STARTED); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Initiates loading of cloud destinations. 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {boolean} recentOnly Whether the load recet destinations only. 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) startLoadCloudDestinations: function(recentOnly) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.cloudPrintInterface_ != null && 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !this.hasLoadedAllCloudDestinations_ && 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!recentOnly || !this.isCloudDestinationSearchInProgress)) { 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.cloudPrintInterface_.search(recentOnly); 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.hasLoadedAllCloudDestinations_ = !recentOnly; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, DestinationStore.EventType.DESTINATION_SEARCH_STARTED); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Inserts a destination into the store without dispatching any events. 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} Whether the inserted destination was not already in the 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * store. 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insertDestination_: function(destination) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var existingDestination = this.destinationMap_[destination.id]; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existingDestination == null) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.destinations_.push(destination); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.destinationMap_[destination.id] = destination; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (existingDestination.connectionStatus == 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_preview.Destination.ConnectionStatus.UNKNOWN && 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destination.connectionStatus != 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_preview.Destination.ConnectionStatus.UNKNOWN) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existingDestination.connectionStatus = destination.connectionStatus; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Binds handlers to events. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addEventListeners_: function() { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tracker_.add( 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.nativeLayer_, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_preview.NativeLayer.EventType.LOCAL_DESTINATIONS_SET, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onLocalDestinationsSet_.bind(this)); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tracker_.add( 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.nativeLayer_, 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_preview.NativeLayer.EventType.CAPABILITIES_SET, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onLocalDestinationCapabilitiesSet_.bind(this)); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tracker_.add( 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.nativeLayer_, 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_preview.NativeLayer.EventType.GET_CAPABILITIES_FAIL, 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onGetCapabilitiesFail_.bind(this)); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.tracker_.add( 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.nativeLayer_, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_preview.NativeLayer.EventType.DESTINATIONS_RELOAD, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onDestinationsReload_.bind(this)); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Resets the state of the destination store to its initial state. 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reset_: function() { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.destinations_ = []; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.destinationMap_ = {}; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectedDestination_ = null; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.hasLoadedAllCloudDestinations_ = false; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.insertDestination( 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore.createLocalPdfPrintDestination_()); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.autoSelectTimeout_ = setTimeout( 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.onAutoSelectTimeoutExpired_.bind(this), 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore.AUTO_SELECT_TIMEOUT_); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called when the local destinations have been got from the native layer. 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {cr.Event} Contains the local destinations. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onLocalDestinationsSet_: function(event) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var localDestinations = event.destinationInfos.map(function(destInfo) { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return print_preview.LocalDestinationParser.parse(destInfo); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.insertDestinations(localDestinations); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isLocalDestinationSearchInProgress_ = false; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, DestinationStore.EventType.DESTINATION_SEARCH_DONE); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called when the native layer retrieves the capabilities for the selected 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * local destination. Updates the destination with new capabilities if the 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination already exists, otherwise it creates a new destination and 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then updates its capabilities. 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {cr.Event} event Contains the capabilities of the local print 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onLocalDestinationCapabilitiesSet_: function(event) { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var destinationId = event.settingsInfo['printerId']; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var destination = this.destinationMap_[destinationId]; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var capabilities = print_preview.LocalCapabilitiesParser.parse( 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.settingsInfo); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (destination) { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In case there were multiple capabilities request for this local 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destination, just ignore the later ones. 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (destination.capabilities != null) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destination.capabilities = capabilities; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rltoscano): This makes the assumption that the "deviceName" is 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same as "printerName". We should include the "printerName" in the 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // response. See http://crbug.com/132831. 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destination = print_preview.LocalDestinationParser.parse( 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {deviceName: destinationId, printerName: destinationId}); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destination.capabilities = capabilities; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.insertDestination(destination); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.selectedDestination_ && 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectedDestination_.id == destinationId) { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent(this, 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore.EventType. 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SELECTED_DESTINATION_CAPABILITIES_READY); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called when a request to get a local destination's print capabilities 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * fails. If the destination is the initial destination, auto-select another 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination instead. 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {cr.Event} event Contains the destination ID that failed. 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onGetCapabilitiesFail_: function(event) { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) console.error('Failed to get print capabilities for printer ' + 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.destinationId); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.isInAutoSelectMode_ && 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.initialDestinationId_ == event.destinationId) { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(this.destinations_.length > 0, 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'No destinations were loaded when failed to get initial ' + 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'destination'); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectDestination(this.destinations_[0]); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called when the /search call completes. Adds the fetched destinations to 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the destination store. 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {cr.Event} event Contains the fetched destinations. 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onCloudPrintSearchDone_: function(event) { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.insertDestinations(event.printers); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, DestinationStore.EventType.DESTINATION_SEARCH_DONE); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called when the /search call fails. Updates outstanding request count and 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * dispatches CLOUD_DESTINATIONS_LOADED event. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onCloudPrintSearchFailed_: function() { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, DestinationStore.EventType.DESTINATION_SEARCH_DONE); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called when /printer call completes. Updates the specified destination's 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * print capabilities. 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {cr.Event} event Contains detailed information about the 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination. 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onCloudPrintPrinterDone_: function(event) { 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var dest = this.updateDestination(event.printer); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.selectedDestination_ == dest) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cr.dispatchSimpleEvent( 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore.EventType.SELECTED_DESTINATION_CAPABILITIES_READY); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called when the Google Cloud Print interface fails to lookup a 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * destination. Selects another destination if the failed destination was 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the initial destination. 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {object} event Contains the ID of the destination that was failed 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to be looked up. 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onCloudPrintPrinterFailed_: function(event) { 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this.isInAutoSelectMode_ && 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.initialDestinationId_ == event.destinationId) { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) console.error('Could not find initial printer: ' + event.destinationId); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(this.destinations_.length > 0, 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'No destinations were loaded when failed to get initial ' + 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'destination'); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectDestination(this.destinations_[0]); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called from native layer after the user was requested to sign in, and did 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * so successfully. 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onDestinationsReload_: function() { 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.reset_(); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.isInAutoSelectMode_ = true; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.startLoadLocalDestinations(); 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.startLoadCloudDestinations(true); 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.startLoadCloudDestinations(false); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called when no destination was auto-selected after some timeout. Selects 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the first destination in store. 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @private 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) onAutoSelectTimeoutExpired_: function() { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.autoSelectTimeout_ = null; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(this.destinations_.length > 0, 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'No destinations were loaded before auto-select timeout expired'); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.selectDestination(this.destinations_[0]); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Export 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return { 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestinationStore: DestinationStore 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}); 634