| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 cr.define('print_preview', function() { | 5 cr.define('print_preview', function() { |
| 6 'use strict'; | 6 'use strict'; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * A data store that stores destinations and dispatches events when the data | 9 * A data store that stores destinations and dispatches events when the data |
| 10 * store changes. | 10 * store changes. |
| 11 * @param {!print_preview.NativeLayer} nativeLayer Used to fetch local print |
| 12 * destinations. |
| 11 * @constructor | 13 * @constructor |
| 12 * @extends {cr.EventTarget} | 14 * @extends {cr.EventTarget} |
| 13 */ | 15 */ |
| 14 function DestinationStore() { | 16 function DestinationStore(nativeLayer) { |
| 15 cr.EventTarget.call(this); | 17 cr.EventTarget.call(this); |
| 16 | 18 |
| 17 /** | 19 /** |
| 20 * Used to fetch local print destinations. |
| 21 * @type {!print_preview.NativeLayer} |
| 22 * @private |
| 23 */ |
| 24 this.nativeLayer_ = nativeLayer; |
| 25 |
| 26 /** |
| 18 * Internal backing store for the data store. | 27 * Internal backing store for the data store. |
| 19 * @type {!Array.<print_preview.Destination>} | 28 * @type {!Array.<!print_preview.Destination>} |
| 20 * @private | 29 * @private |
| 21 */ | 30 */ |
| 22 this.destinations_ = []; | 31 this.destinations_ = []; |
| 23 | 32 |
| 24 /** | 33 /** |
| 34 * Cache used for constant lookup of printers. |
| 35 * @type {object.<string, !print_preview.Destination>} |
| 36 * @private |
| 37 */ |
| 38 this.destinationMap_ = {}; |
| 39 |
| 40 /** |
| 25 * Currently selected destination. | 41 * Currently selected destination. |
| 26 * @type {print_preview.Destination} | 42 * @type {print_preview.Destination} |
| 27 * @private | 43 * @private |
| 28 */ | 44 */ |
| 29 this.selectedDestination_ = null; | 45 this.selectedDestination_ = null; |
| 30 | 46 |
| 31 /** | 47 /** |
| 32 * Initial destination ID used to auto-select the first inserted destination | 48 * Initial destination ID used to auto-select the first inserted destination |
| 33 * that matches. If {@code null}, the first destination inserted into the | 49 * that matches. If {@code null}, the first destination inserted into the |
| 34 * store will be selected. | 50 * store will be selected. |
| 35 * @type {?string} | 51 * @type {?string} |
| 36 * @private | 52 * @private |
| 37 */ | 53 */ |
| 38 this.initialDestinationId_ = null; | 54 this.initialDestinationId_ = null; |
| 39 | 55 |
| 40 /** | 56 /** |
| 41 * Whether the destination store will auto select the destination that | 57 * Whether the destination store will auto select the destination that |
| 42 * matches the initial destination. | 58 * matches the initial destination. |
| 43 * @type {boolean} | 59 * @type {boolean} |
| 44 * @private | 60 * @private |
| 45 */ | 61 */ |
| 46 this.isInAutoSelectMode_ = false; | 62 this.isInAutoSelectMode_ = false; |
| 63 |
| 64 /** |
| 65 * Event tracker used to track event listeners of the destination store. |
| 66 * @type {!EventTracker} |
| 67 * @private |
| 68 */ |
| 69 this.tracker_ = new EventTracker(); |
| 70 |
| 71 /** |
| 72 * Used to fetch cloud-based print destinations. |
| 73 * @type {print_preview.CloudPrintInterface} |
| 74 * @private |
| 75 */ |
| 76 this.cloudPrintInterface_ = null; |
| 77 |
| 78 /** |
| 79 * Whether the destination store has already loaded or is loading all cloud |
| 80 * destinations. |
| 81 * @type {boolean} |
| 82 * @private |
| 83 */ |
| 84 this.hasLoadedAllCloudDestinations_ = false; |
| 85 |
| 86 /** |
| 87 * ID of a timeout after the initial destination ID is set. If no inserted |
| 88 * destination matches the initial destination ID after the specified |
| 89 * timeout, the first destination in the store will be automatically |
| 90 * selected. |
| 91 * @type {?number} |
| 92 * @private |
| 93 */ |
| 94 this.autoSelectTimeout_ = null; |
| 95 |
| 96 this.addEventListeners_(); |
| 97 this.reset_(); |
| 47 }; | 98 }; |
| 48 | 99 |
| 49 /** | 100 /** |
| 50 * Event types dispatched by the data store. | 101 * Event types dispatched by the data store. |
| 51 * @enum {string} | 102 * @enum {string} |
| 52 */ | 103 */ |
| 53 DestinationStore.EventType = { | 104 DestinationStore.EventType = { |
| 54 DESTINATIONS_INSERTED: | 105 DESTINATIONS_INSERTED: |
| 55 'print_preview.DestinationStore.DESTINATIONS_INSERTED', | 106 'print_preview.DestinationStore.DESTINATIONS_INSERTED', |
| 56 DESTINATION_SELECT: 'print_preview.DestinationStore.DESTINATION_SELECT' | 107 DESTINATION_SELECT: 'print_preview.DestinationStore.DESTINATION_SELECT', |
| 108 SELECTED_DESTINATION_CAPABILITIES_READY: |
| 109 'print_preview.DestinationStore.SELECTED_DESTINATION_CAPABILITIES_READY' |
| 110 }; |
| 111 |
| 112 /** |
| 113 * Delay in milliseconds before the destination store ignores the initial |
| 114 * destination ID and just selects any printer (since the initial destination |
| 115 * was not found). |
| 116 * @type {number} |
| 117 * @const |
| 118 * @private |
| 119 */ |
| 120 DestinationStore.AUTO_SELECT_TIMEOUT_ = 2000; |
| 121 |
| 122 /** |
| 123 * Creates a local PDF print destination. |
| 124 * @return {!print_preview.Destination} Created print destination. |
| 125 * @private |
| 126 */ |
| 127 DestinationStore.createLocalPdfPrintDestination_ = function() { |
| 128 var dest = new print_preview.Destination( |
| 129 print_preview.Destination.GooglePromotedId.SAVE_AS_PDF, |
| 130 print_preview.Destination.Type.LOCAL, |
| 131 localStrings.getString('printToPDF'), |
| 132 false /*isRecent*/); |
| 133 dest.capabilities = new print_preview.ChromiumCapabilities( |
| 134 false /*hasCopiesCapability*/, |
| 135 '1' /*defaultCopiesStr*/, |
| 136 false /*hasCollateCapability*/, |
| 137 false /*defaultIsCollateEnabled*/, |
| 138 false /*hasDuplexCapability*/, |
| 139 false /*defaultIsDuplexEnabled*/, |
| 140 true /*hasOrientationCapability*/, |
| 141 false /*defaultIsLandscapeEnabled*/, |
| 142 true /*hasColorCapability*/, |
| 143 true /*defaultIsColorEnabled*/); |
| 144 return dest; |
| 57 }; | 145 }; |
| 58 | 146 |
| 59 DestinationStore.prototype = { | 147 DestinationStore.prototype = { |
| 60 __proto__: cr.EventTarget.prototype, | 148 __proto__: cr.EventTarget.prototype, |
| 61 | 149 |
| 62 /** | 150 /** |
| 63 * @return {!Array.<!print_preview.Destination>} List of destinations in | 151 * @return {!Array.<!print_preview.Destination>} List of destinations in |
| 64 * the store. | 152 * the store. |
| 65 */ | 153 */ |
| 66 get destinations() { | 154 get destinations() { |
| 67 return this.destinations_.slice(0); | 155 return this.destinations_.slice(0); |
| 68 }, | 156 }, |
| 69 | 157 |
| 70 /** | 158 /** |
| 71 * @return {print_preview.Destination} The currently selected destination or | 159 * @return {print_preview.Destination} The currently selected destination or |
| 72 * {@code null} if none is selected. | 160 * {@code null} if none is selected. |
| 73 */ | 161 */ |
| 74 get selectedDestination() { | 162 get selectedDestination() { |
| 75 return this.selectedDestination_; | 163 return this.selectedDestination_; |
| 76 }, | 164 }, |
| 77 | 165 |
| 78 /** | 166 /** |
| 79 * Sets the initially selected destination. If any inserted destinations | 167 * Sets the initially selected destination. If any inserted destinations |
| 80 * match this ID, that destination will be automatically selected. This | 168 * match this ID, that destination will be automatically selected. This |
| 81 * occurs only once for every time this setter is called or if the store is | 169 * occurs only once for every time this setter is called or if the store is |
| 82 * cleared. | 170 * cleared. |
| 83 * @param {string} ID of the destination that should be selected | 171 * @param {?string} ID of the destination that should be selected |
| 84 * automatically when added to the store. | 172 * automatically when added to the store or {@code null} if the first |
| 173 * destination that is inserted should be selected. |
| 85 */ | 174 */ |
| 86 setInitialDestinationId: function(initialDestinationId) { | 175 setInitialDestinationId: function(initialDestinationId) { |
| 87 this.initialDestinationId_ = initialDestinationId; | 176 this.initialDestinationId_ = initialDestinationId; |
| 88 this.isInAutoSelectMode_ = true; | 177 this.isInAutoSelectMode_ = true; |
| 89 if (this.initialDestinationId_ == null && this.destinations_.length > 0) { | 178 if (this.initialDestinationId_ == null) { |
| 179 assert(this.destinations_.length > 0, |
| 180 'No destinations available to select'); |
| 90 this.selectDestination(this.destinations_[0]); | 181 this.selectDestination(this.destinations_[0]); |
| 91 } else if (this.initialDestinationId_ != null) { | 182 } else { |
| 92 for (var dest, i = 0; dest = this.destinations_[i]; i++) { | 183 var candidate = this.destinationMap_[this.initialDestinationId_]; |
| 93 if (dest.id == initialDestinationId) { | 184 if (candidate != null) { |
| 94 this.selectDestination(dest); | 185 this.selectDestination(candidate); |
| 95 break; | |
| 96 } | |
| 97 } | 186 } |
| 98 } | 187 } |
| 99 }, | 188 }, |
| 100 | 189 |
| 190 /** |
| 191 * Sets the destination store's Google Cloud Print interface. |
| 192 * @param {!print_preview.CloudPrintInterface} cloudPrintInterface Interface |
| 193 * to set. |
| 194 */ |
| 195 setCloudPrintInterface: function(cloudPrintInterface) { |
| 196 this.cloudPrintInterface_ = cloudPrintInterface; |
| 197 this.tracker_.add( |
| 198 this.cloudPrintInterface_, |
| 199 cloudprint.CloudPrintInterface.EventType.SEARCH_DONE, |
| 200 this.onCloudPrintSearchDone_.bind(this)); |
| 201 this.tracker_.add( |
| 202 this.cloudPrintInterface_, |
| 203 cloudprint.CloudPrintInterface.EventType.PRINTER_DONE, |
| 204 this.onCloudPrintPrinterDone_.bind(this)); |
| 205 }, |
| 206 |
| 101 /** @param {!print_preview.Destination} Destination to select. */ | 207 /** @param {!print_preview.Destination} Destination to select. */ |
| 102 selectDestination: function(destination) { | 208 selectDestination: function(destination) { |
| 103 this.selectedDestination_ = destination; | 209 this.selectedDestination_ = destination; |
| 104 this.selectedDestination_.isRecent = true; | 210 this.selectedDestination_.isRecent = true; |
| 105 this.isInAutoSelectMode_ = false; | 211 this.isInAutoSelectMode_ = false; |
| 212 if (this.autoSelectTimeout_ != null) { |
| 213 clearTimeout(this.autoSelectTimeout_); |
| 214 this.autoSelectTimeout_ = null; |
| 215 } |
| 106 cr.dispatchSimpleEvent( | 216 cr.dispatchSimpleEvent( |
| 107 this, DestinationStore.EventType.DESTINATION_SELECT); | 217 this, DestinationStore.EventType.DESTINATION_SELECT); |
| 218 if (destination.capabilities == null) { |
| 219 if (destination.isLocal) { |
| 220 this.nativeLayer_.startGetLocalDestinationCapabilities( |
| 221 destination.id); |
| 222 } else { |
| 223 assert(this.cloudPrintInterface_ != null, |
| 224 'Selected destination is a cloud destination, but Google ' + |
| 225 'Cloud Print is not enabled'); |
| 226 this.cloudPrintInterface_.printer(destination.id); |
| 227 } |
| 228 } else { |
| 229 cr.dispatchSimpleEvent( |
| 230 this, |
| 231 DestinationStore.EventType.SELECTED_DESTINATION_CAPABILITIES_READY); |
| 232 } |
| 108 }, | 233 }, |
| 109 | 234 |
| 110 /** | 235 /** |
| 111 * Inserts a print destination to the data store and dispatches a | 236 * Inserts a print destination to the data store and dispatches a |
| 112 * DESTINATIONS_INSERTED event. If the destination matches the initial | 237 * DESTINATIONS_INSERTED event. If the destination matches the initial |
| 113 * destination ID, then the destination will be automatically selected. | 238 * destination ID, then the destination will be automatically selected. |
| 114 * @param {!print_preview.Destination} destination Print destination to | 239 * @param {!print_preview.Destination} destination Print destination to |
| 115 * insert. | 240 * insert. |
| 116 */ | 241 */ |
| 117 insertDestination: function(destination) { | 242 insertDestination: function(destination) { |
| 118 this.destinations_.push(destination); | 243 if (this.insertDestination_(destination)) { |
| 119 cr.dispatchSimpleEvent( | 244 cr.dispatchSimpleEvent( |
| 120 this, DestinationStore.EventType.DESTINATIONS_INSERTED); | 245 this, DestinationStore.EventType.DESTINATIONS_INSERTED); |
| 121 if (this.isInAutoSelectMode_) { | 246 if (this.isInAutoSelectMode_ && |
| 122 if (this.initialDestinationId_ == null) { | 247 (this.initialDestinationId_ == null || |
| 248 destination.id == this.initialDestinationId_)) { |
| 123 this.selectDestination(destination); | 249 this.selectDestination(destination); |
| 124 } else { | |
| 125 if (destination.id == this.initialDestinationId_) { | |
| 126 this.selectDestination(destination); | |
| 127 } | |
| 128 } | 250 } |
| 129 } | 251 } |
| 130 }, | 252 }, |
| 131 | 253 |
| 132 /** | 254 /** |
| 133 * Inserts multiple print destinations to the data store and dispatches one | 255 * Inserts multiple print destinations to the data store and dispatches one |
| 134 * DESTINATIONS_INSERTED event. If any of the destinations match the initial | 256 * DESTINATIONS_INSERTED event. If any of the destinations match the initial |
| 135 * destination ID, then that destination will be automatically selected. | 257 * destination ID, then that destination will be automatically selected. |
| 136 * @param {!Array.<print_preview.Destination>} destinations Print | 258 * @param {!Array.<print_preview.Destination>} destinations Print |
| 137 * destinations to insert. | 259 * destinations to insert. |
| 138 */ | 260 */ |
| 139 insertDestinations: function(destinations) { | 261 insertDestinations: function(destinations) { |
| 140 this.destinations_ = this.destinations_.concat(destinations); | 262 var insertedDestination = false; |
| 141 cr.dispatchSimpleEvent( | 263 var destinationToAutoSelect = null; |
| 142 this, DestinationStore.EventType.DESTINATIONS_INSERTED); | 264 destinations.forEach(function(dest) { |
| 143 if (this.isInAutoSelectMode_) { | 265 if (this.insertDestination_(dest)) { |
| 144 if (this.initialDestinationId_ == null && destinations.length > 0) { | 266 insertedDestination = true; |
| 145 this.selectDestination(destinations[0]); | 267 if (this.isInAutoSelectMode_ && |
| 146 } else if (this.initialDestinationId_ != null) { | 268 destinationToAutoSelect == null && |
| 147 for (var dest, i = 0; dest = destinations[i]; i++) { | 269 (this.initialDestinationId_ == null || |
| 148 if (dest.id == this.initialDestinationId_) { | 270 dest.id == this.initialDestinationId_)) { |
| 149 this.selectDestination(dest); | 271 destinationToAutoSelect = dest; |
| 150 break; | |
| 151 } | |
| 152 } | 272 } |
| 153 } | 273 } |
| 274 }, this); |
| 275 if (insertedDestination) { |
| 276 cr.dispatchSimpleEvent( |
| 277 this, DestinationStore.EventType.DESTINATIONS_INSERTED); |
| 278 } |
| 279 if (destinationToAutoSelect != null) { |
| 280 this.selectDestination(destinationToAutoSelect); |
| 154 } | 281 } |
| 155 }, | 282 }, |
| 156 | 283 |
| 157 /** | 284 /** |
| 158 * Updates an existing print destination with capabilities information. If | 285 * Updates an existing print destination with capabilities information. If |
| 159 * the destination doesn't already exist, it will be added. | 286 * the destination doesn't already exist, it will be added. |
| 160 * @param {!print_preview.Destination} destination Destination to update. | 287 * @param {!print_preview.Destination} destination Destination to update. |
| 161 * @return {!print_preview.Destination} The existing destination that was | 288 * @return {!print_preview.Destination} The existing destination that was |
| 162 * updated. | 289 * updated. |
| 163 */ | 290 */ |
| 164 updateDestination: function(destination) { | 291 updateDestination: function(destination) { |
| 165 var existingDestination = null; | 292 var existingDestination = this.destinationMap_[destination.id]; |
| 166 for (var d, i = 0; d = this.destinations_[i]; i++) { | 293 if (existingDestination != null) { |
| 167 if (destination.id == d.id) { | |
| 168 existingDestination = d; | |
| 169 break; | |
| 170 } | |
| 171 } | |
| 172 if (existingDestination) { | |
| 173 existingDestination.capabilities = destination.capabilities; | 294 existingDestination.capabilities = destination.capabilities; |
| 174 return existingDestination; | 295 return existingDestination; |
| 175 } else { | 296 } else { |
| 176 this.insertDestination(destination); | 297 this.insertDestination(destination); |
| 177 } | 298 } |
| 178 }, | 299 }, |
| 179 | 300 |
| 180 /** Clears all print destinations. */ | 301 /** Initiates loading of local print destinations. */ |
| 181 clear: function() { | 302 startLoadLocalDestinations: function() { |
| 303 this.nativeLayer_.startGetLocalDestinations(); |
| 304 }, |
| 305 |
| 306 /** Initiates loading of recent cloud destinations. */ |
| 307 startLoadRecentCloudDestinations: function() { |
| 308 if (this.cloudPrintInterface_ != null) { |
| 309 this.cloudPrintInterface_.search(true /*isRecent*/); |
| 310 } |
| 311 }, |
| 312 |
| 313 /** Initiates loading of all cloud destinations. */ |
| 314 startLoadAllCloudDestinations: function() { |
| 315 if (this.cloudPrintInterface_ != null && |
| 316 !this.hasLoadedAllCloudDestinations_) { |
| 317 this.cloudPrintInterface_.search(false /*isRecent*/); |
| 318 this.hasLoadedAllCloudDestinations_ = true; |
| 319 } |
| 320 }, |
| 321 |
| 322 /** |
| 323 * Inserts a destination into the store without dispatching any events. |
| 324 * @return {boolean} Whether the inserted destination was not already in the |
| 325 * store. |
| 326 * @private |
| 327 */ |
| 328 insertDestination_: function(destination) { |
| 329 if (this.destinationMap_[destination.id] == null) { |
| 330 this.destinations_.push(destination); |
| 331 this.destinationMap_[destination.id] = destination; |
| 332 return true; |
| 333 } else { |
| 334 return false; |
| 335 } |
| 336 }, |
| 337 |
| 338 /** |
| 339 * Binds handlers to events. |
| 340 * @private |
| 341 */ |
| 342 addEventListeners_: function() { |
| 343 this.tracker_.add( |
| 344 this.nativeLayer_, |
| 345 print_preview.NativeLayer.EventType.LOCAL_DESTINATIONS_SET, |
| 346 this.onLocalDestinationsSet_.bind(this)); |
| 347 this.tracker_.add( |
| 348 this.nativeLayer_, |
| 349 print_preview.NativeLayer.EventType.CAPABILITIES_SET, |
| 350 this.onLocalDestinationCapabilitiesSet_.bind(this)); |
| 351 this.tracker_.add( |
| 352 this.nativeLayer_, |
| 353 print_preview.NativeLayer.EventType.DESTINATIONS_RELOAD, |
| 354 this.onDestinationsReload_.bind(this)); |
| 355 }, |
| 356 |
| 357 /** |
| 358 * Resets the state of the destination store to its initial state. |
| 359 * @private |
| 360 */ |
| 361 reset_: function() { |
| 182 this.destinations_ = []; | 362 this.destinations_ = []; |
| 363 this.destinationMap_ = {}; |
| 183 this.selectedDestination_ = null; | 364 this.selectedDestination_ = null; |
| 365 this.hasLoadedAllCloudDestinations_ = false; |
| 366 this.insertDestination( |
| 367 DestinationStore.createLocalPdfPrintDestination_()); |
| 368 this.autoSelectTimeout_ = setTimeout( |
| 369 this.onAutoSelectTimeoutExpired_.bind(this), |
| 370 DestinationStore.AUTO_SELECT_TIMEOUT_); |
| 371 }, |
| 372 |
| 373 /** |
| 374 * Called when the local destinations have been got from the native layer. |
| 375 * @param {cr.Event} Contains the local destinations. |
| 376 * @private |
| 377 */ |
| 378 onLocalDestinationsSet_: function(event) { |
| 379 var localDestinations = event.destinationInfos.map(function(destInfo) { |
| 380 return print_preview.LocalDestinationParser.parse(destInfo); |
| 381 }); |
| 382 this.insertDestinations(localDestinations); |
| 383 }, |
| 384 |
| 385 /** |
| 386 * Called when the native layer retrieves the capabilities for the selected |
| 387 * local destination. |
| 388 * @param {cr.Event} event Contains the capabilities of the local print |
| 389 * destination. |
| 390 * @private |
| 391 */ |
| 392 onLocalDestinationCapabilitiesSet_: function(event) { |
| 393 // TODO(rltoscano): There may be a race condition here. This method is |
| 394 // assumed to return capabilities for the currently selected printer. But |
| 395 // between the time the local printer was selected and the capabilities |
| 396 // were retrieved, the selected printer can change. One way to address |
| 397 // this is to include the destination ID in the event.settingsInfo |
| 398 // parameter. |
| 399 if (this.selectedDestination_ && this.selectedDestination_.isLocal) { |
| 400 var capabilities = print_preview.LocalCapabilitiesParser.parse( |
| 401 event.settingsInfo); |
| 402 this.selectedDestination_.capabilities = capabilities; |
| 403 cr.dispatchSimpleEvent( |
| 404 this, |
| 405 DestinationStore.EventType.SELECTED_DESTINATION_CAPABILITIES_READY); |
| 406 } |
| 407 }, |
| 408 |
| 409 /** |
| 410 * Called when the /search call completes. Adds the fetched printers to the |
| 411 * destination store. |
| 412 * @param {cr.Event} event Contains the fetched printers. |
| 413 * @private |
| 414 */ |
| 415 onCloudPrintSearchDone_: function(event) { |
| 416 this.insertDestinations(event.printers); |
| 417 }, |
| 418 |
| 419 /** |
| 420 * Called when /printer call completes. Updates the specified destination's |
| 421 * print capabilities. |
| 422 * @param {cr.Event} event Contains detailed information about the |
| 423 * destination. |
| 424 * @private |
| 425 */ |
| 426 onCloudPrintPrinterDone_: function(event) { |
| 427 var dest = this.updateDestination(event.printer); |
| 428 if (this.selectedDestination_ == dest) { |
| 429 cr.dispatchSimpleEvent( |
| 430 this, |
| 431 DestinationStore.EventType.SELECTED_DESTINATION_CAPABILITIES_READY); |
| 432 } |
| 433 }, |
| 434 |
| 435 /** |
| 436 * Called from native layer after the user was requested to sign in, and did |
| 437 * so successfully. |
| 438 * @private |
| 439 */ |
| 440 onDestinationsReload_: function() { |
| 441 this.reset_(); |
| 184 this.isInAutoSelectMode_ = true; | 442 this.isInAutoSelectMode_ = true; |
| 443 this.startLoadLocalDestinations(); |
| 444 this.startLoadRecentCloudDestinations(); |
| 445 this.startLoadAllCloudDestinations(); |
| 446 }, |
| 447 |
| 448 /** |
| 449 * Called when no destination was auto-selected after some timeout. Selects |
| 450 * the first destination in store. |
| 451 * @private |
| 452 */ |
| 453 onAutoSelectTimeoutExpired_: function() { |
| 454 this.autoSelectTimeout_ = null; |
| 455 assert(this.destinations_.length > 0, |
| 456 'No destinations were loaded before auto-select timeout expired'); |
| 457 this.selectDestination(this.destinations_[0]); |
| 185 } | 458 } |
| 186 }; | 459 }; |
| 187 | 460 |
| 188 // Export | 461 // Export |
| 189 return { | 462 return { |
| 190 DestinationStore: DestinationStore | 463 DestinationStore: DestinationStore |
| 191 }; | 464 }; |
| 192 }); | 465 }); |
| OLD | NEW |