Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 'use strict'; | 5 'use strict'; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Called from the main frame when unloading. | 8 * Called from the main frame when unloading. |
| 9 * @param {boolean=} opt_exiting True if the app is exiting. | 9 * @param {boolean=} opt_exiting True if the app is exiting. |
| 10 */ | 10 */ |
| 11 function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting); } | 11 function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting); } |
| 12 | 12 |
| 13 /** | 13 /** |
| 14 * Overrided metadata worker's path. | 14 * Overrided metadata worker's path. |
| 15 * @type {string} | 15 * @type {string} |
| 16 * @const | 16 * @const |
| 17 */ | 17 */ |
| 18 ContentProvider.WORKER_SCRIPT = '/js/metadata_worker.js'; | 18 ContentProvider.WORKER_SCRIPT = '/js/metadata_worker.js'; |
| 19 | 19 |
| 20 /** | 20 /** |
| 21 * Data model for gallery. | 21 * Data model for gallery. |
| 22 * | 22 * |
| 23 * @param {MetadataCache} metadataCache Metadata cache. | |
| 23 * @constructor | 24 * @constructor |
| 24 * @extends {cr.ui.ArrayDataModel} | 25 * @extends {cr.ui.ArrayDataModel} |
| 25 */ | 26 */ |
| 26 function GalleryDataModel() { | 27 function GalleryDataModel(metadataCache) { |
| 27 cr.ui.ArrayDataModel.call(this, []); | 28 cr.ui.ArrayDataModel.call(this, []); |
| 28 this.metadataCache_ = null; | 29 this.metadataCache_ = metadataCache; |
| 29 } | 30 } |
| 30 | 31 |
| 31 /** | 32 /** |
| 32 * Maximum number of full size image cache. | 33 * Maximum number of full size image cache. |
| 33 * @type {number} | 34 * @type {number} |
| 34 * @const | 35 * @const |
| 35 * @private | 36 * @private |
| 36 */ | 37 */ |
| 37 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3; | 38 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3; |
| 38 | 39 |
| 39 /** | 40 /** |
| 40 * Maximum number of screen size image cache. | 41 * Maximum number of screen size image cache. |
| 41 * @type {number} | 42 * @type {number} |
| 42 * @const | 43 * @const |
| 43 * @private | 44 * @private |
| 44 */ | 45 */ |
| 45 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5; | 46 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5; |
| 46 | 47 |
| 47 GalleryDataModel.prototype = { | 48 GalleryDataModel.prototype = { |
| 48 __proto__: cr.ui.ArrayDataModel.prototype | 49 __proto__: cr.ui.ArrayDataModel.prototype |
| 49 }; | 50 }; |
| 50 | 51 |
| 51 /** | 52 /** |
| 52 * Initializes the data model. | |
| 53 * | |
| 54 * @param {MetadataCache} metadataCache Metadata cache. | |
| 55 * @param {Array.<FileEntry>} entries Image entries. | |
| 56 * @return {Promise} Promise to be fulfilled with after initialization. | |
| 57 */ | |
| 58 GalleryDataModel.prototype.initialize = function(metadataCache, entries) { | |
| 59 // Store metadata cache. | |
| 60 this.metadataCache_ = metadataCache; | |
| 61 | |
| 62 // Obtain metadata. | |
| 63 var metadataPromise = new Promise(function(fulfill) { | |
| 64 this.metadataCache_.get(entries, Gallery.METADATA_TYPE, fulfill); | |
| 65 }.bind(this)); | |
| 66 | |
| 67 // Initialize the gallery by using the metadata. | |
| 68 return metadataPromise.then(function(metadata) { | |
| 69 // Check the length of metadata. | |
| 70 if (entries.length !== metadata.length) | |
| 71 return Promise.reject('Failed to obtain metadata for the entries.'); | |
| 72 | |
| 73 // Obtains items. | |
| 74 var items = entries.map(function(entry, i) { | |
| 75 var clonedMetadata = MetadataCache.cloneMetadata(metadata[i]); | |
| 76 return new Gallery.Item( | |
| 77 entry, clonedMetadata, metadataCache, /* original */ true); | |
| 78 }); | |
| 79 | |
| 80 // Update the models. | |
| 81 this.push.apply(this, items); | |
| 82 }.bind(this)); | |
| 83 }; | |
| 84 | |
| 85 /** | |
| 86 * Saves new image. | 53 * Saves new image. |
| 87 * | 54 * |
| 88 * @param {Gallery.Item} item Original gallery item. | 55 * @param {Gallery.Item} item Original gallery item. |
| 89 * @param {Canvas} canvas Canvas containing new image. | 56 * @param {Canvas} canvas Canvas containing new image. |
| 90 * @param {boolean} overwrite Whether to overwrite the image to the item or not. | 57 * @param {boolean} overwrite Whether to overwrite the image to the item or not. |
| 91 * @return {Promise} Promise to be fulfilled with when the operation completes. | 58 * @return {Promise} Promise to be fulfilled with when the operation completes. |
| 92 */ | 59 */ |
| 93 GalleryDataModel.prototype.saveItem = function(item, canvas, overwrite) { | 60 GalleryDataModel.prototype.saveItem = function(item, canvas, overwrite) { |
| 94 var oldEntry = item.getEntry(); | 61 var oldEntry = item.getEntry(); |
| 95 var oldMetadata = item.getMetadata(); | 62 var oldMetadata = item.getMetadata(); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 loadTimeData: {} | 183 loadTimeData: {} |
| 217 }; | 184 }; |
| 218 this.container_ = document.querySelector('.gallery'); | 185 this.container_ = document.querySelector('.gallery'); |
| 219 this.document_ = document; | 186 this.document_ = document; |
| 220 this.metadataCache_ = this.context_.metadataCache; | 187 this.metadataCache_ = this.context_.metadataCache; |
| 221 this.volumeManager_ = volumeManager; | 188 this.volumeManager_ = volumeManager; |
| 222 this.selectedEntry_ = null; | 189 this.selectedEntry_ = null; |
| 223 this.metadataCacheObserverId_ = null; | 190 this.metadataCacheObserverId_ = null; |
| 224 this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this); | 191 this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this); |
| 225 | 192 |
| 226 this.dataModel_ = new GalleryDataModel(); | 193 this.dataModel_ = new GalleryDataModel(this.context_.metadataCache); |
| 227 this.selectionModel_ = new cr.ui.ListSelectionModel(); | 194 this.selectionModel_ = new cr.ui.ListSelectionModel(); |
| 228 | 195 |
| 229 this.initDom_(); | 196 this.initDom_(); |
| 230 this.initListeners_(); | 197 this.initListeners_(); |
| 231 } | 198 } |
| 232 | 199 |
| 233 /** | 200 /** |
| 234 * Gallery extends cr.EventTarget. | 201 * Gallery extends cr.EventTarget. |
| 235 */ | 202 */ |
| 236 Gallery.prototype.__proto__ = cr.EventTarget.prototype; | 203 Gallery.prototype.__proto__ = cr.EventTarget.prototype; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 return button; | 396 return button; |
| 430 }; | 397 }; |
| 431 | 398 |
| 432 /** | 399 /** |
| 433 * Loads the content. | 400 * Loads the content. |
| 434 * | 401 * |
| 435 * @param {!Array.<Entry>} entries Array of entries. | 402 * @param {!Array.<Entry>} entries Array of entries. |
| 436 * @param {!Array.<Entry>} selectedEntries Array of selected entries. | 403 * @param {!Array.<Entry>} selectedEntries Array of selected entries. |
| 437 */ | 404 */ |
| 438 Gallery.prototype.load = function(entries, selectedEntries) { | 405 Gallery.prototype.load = function(entries, selectedEntries) { |
| 439 this.dataModel_.initialize(this.metadataCache_, entries).then(function() { | 406 // Obtains max chank size. |
| 440 // Apply selection. | 407 var maxChunkSize = 20; |
| 441 this.selectionModel_.adjustLength(this.dataModel_.length); | 408 var volumeInfo = this.volumeManager_.getVolumeInfo(entries[0]); |
| 442 var entryIndexesByURLs = {}; | 409 if (volumeInfo && |
| 443 for (var index = 0; index < entries.length; index++) { | 410 volumeInfo.volumeType === VolumeManagerCommon.VolumeType.MTP) { |
| 444 entryIndexesByURLs[entries[index].toURL()] = index; | 411 maxChunkSize = 1; |
| 445 } | 412 } |
| 446 for (var i = 0; i !== selectedEntries.length; i++) { | |
| 447 var selectedIndex = entryIndexesByURLs[selectedEntries[i].toURL()]; | |
| 448 if (selectedIndex !== undefined) | |
| 449 this.selectionModel_.setIndexSelected(selectedIndex, true); | |
| 450 else | |
| 451 console.error('Cannot select ' + selectedEntries[i]); | |
| 452 } | |
| 453 if (this.selectionModel_.selectedIndexes.length === 0) | |
| 454 this.onSelection_(); | |
| 455 | 413 |
| 456 // Determine the initial mode. | 414 // Make loading list. |
| 457 var shouldShowMosaic = selectedEntries.length > 1 || | 415 var entrySet = {}; |
| 458 (this.context_.pageState && | 416 for (var i = 0; i < entries.length; i++) { |
| 459 this.context_.pageState.gallery === 'mosaic'); | 417 var entry = entries[i]; |
| 460 this.setCurrentMode_(shouldShowMosaic ? this.mosaicMode_ : this.slideMode_); | 418 entrySet[entry.toURL()] = { |
| 419 entry: entry, | |
| 420 selected: false, | |
| 421 index: i | |
| 422 }; | |
| 423 } | |
| 424 for (var i = 0; i < selectedEntries.length; i++) { | |
| 425 var entry = selectedEntries[i]; | |
| 426 entrySet[entry.toURL()] = { | |
| 427 entry: entry, | |
| 428 selected: true, | |
| 429 index: i | |
| 430 }; | |
| 431 } | |
| 432 var loadingList = []; | |
| 433 for (var url in entrySet) { | |
| 434 loadingList.push(entrySet[url]); | |
| 435 } | |
| 436 loadingList = loadingList.sort(function(a, b) { | |
| 437 if (a.selected && !b.selected) | |
| 438 return -1; | |
| 439 else if (!a.selected && b.selected) | |
| 440 return 1; | |
| 441 else | |
| 442 return a.index - b.index; | |
| 443 }); | |
| 461 | 444 |
| 462 // Init mosaic mode. | 445 // Load entries. |
| 463 var mosaic = this.mosaicMode_.getMosaic(); | 446 var loadChunk = function(firstChunk) { |
|
yoshiki
2014/08/15 05:47:39
loadChunk is called many times. Function.bind() is
hirono
2014/08/15 07:05:25
Done.
| |
| 464 mosaic.init(); | 447 // Extract chunk. |
| 448 var chunk = loadingList.splice(0, maxChunkSize); | |
| 449 if (!chunk.length) | |
| 450 return; | |
| 465 | 451 |
| 466 // Do the initialization for each mode. | 452 return new Promise(function(fulfill) { |
| 467 if (shouldShowMosaic) { | 453 // Obtains metadata for chunk. |
| 468 mosaic.show(); | 454 var entries = chunk.map(function(chunkItem) { |
| 469 this.inactivityWatcher_.check(); // Show the toolbar. | 455 return chunkItem.entry; |
| 470 cr.dispatchSimpleEvent(this, 'loaded'); | 456 }); |
| 471 } else { | 457 this.metadataCache_.get(entries, Gallery.METADATA_TYPE, fulfill); |
| 472 this.slideMode_.enter( | 458 }.bind(this)).then(function(metadataList) { |
| 473 null, | 459 if (chunk.length !== metadataList.length) |
| 474 function() { | 460 return Promise.reject('Failed to load metadata.'); |
| 475 // Flash the toolbar briefly to show it is there. | 461 |
| 476 this.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT); | 462 // Add items to the model. |
| 477 }.bind(this), | 463 var items = chunk.map(function(chunkItem, index) { |
| 478 function() { | 464 var clonedMetadata = MetadataCache.cloneMetadata(metadataList[index]); |
| 479 cr.dispatchSimpleEvent(this, 'loaded'); | 465 return new Gallery.Item( |
| 480 }.bind(this)); | 466 chunkItem.entry, |
| 481 } | 467 clonedMetadata, |
| 482 }.bind(this)).catch(function(error) { | 468 this.metadataCache_, |
| 469 /* original */ true); | |
| 470 }.bind(this)); | |
| 471 this.dataModel_.push.apply(this.dataModel_, items); | |
| 472 | |
| 473 // Apply the selection. | |
| 474 var selectionUpdated = false; | |
| 475 for (var i = 0; i < chunk.length; i++) { | |
| 476 if (!chunk[i].selected) | |
| 477 continue; | |
| 478 var index = this.dataModel_.indexOf(items[i]); | |
| 479 if (index < 0) | |
| 480 continue; | |
| 481 this.selectionModel_.setIndexSelected(index); | |
| 482 selectionUpdated = true; | |
| 483 } | |
| 484 if (selectionUpdated) | |
| 485 this.onSelection_(); | |
| 486 | |
| 487 // Init modes after the first chunk is loaded. | |
| 488 if (firstChunk) { | |
| 489 // Determine the initial mode. | |
| 490 var shouldShowMosaic = selectedEntries.length > 1 || | |
| 491 (this.context_.pageState && | |
| 492 this.context_.pageState.gallery === 'mosaic'); | |
| 493 this.setCurrentMode_( | |
| 494 shouldShowMosaic ? this.mosaicMode_ : this.slideMode_); | |
| 495 | |
| 496 // Init mosaic mode. | |
| 497 var mosaic = this.mosaicMode_.getMosaic(); | |
| 498 mosaic.init(); | |
| 499 | |
| 500 // Do the initialization for each mode. | |
| 501 if (shouldShowMosaic) { | |
| 502 mosaic.show(); | |
| 503 this.inactivityWatcher_.check(); // Show the toolbar. | |
| 504 cr.dispatchSimpleEvent(this, 'loaded'); | |
| 505 } else { | |
| 506 this.slideMode_.enter( | |
| 507 null, | |
| 508 function() { | |
| 509 // Flash the toolbar briefly to show it is there. | |
| 510 this.inactivityWatcher_.kick(Gallery.FIRST_FADE_TIMEOUT); | |
| 511 }.bind(this), | |
| 512 function() { | |
| 513 cr.dispatchSimpleEvent(this, 'loaded'); | |
| 514 }.bind(this)); | |
| 515 } | |
| 516 } | |
| 517 | |
| 518 // Continue to load chunks. | |
| 519 return loadChunk(/* firstChunk */ false); | |
| 520 }.bind(this)); | |
| 521 }.bind(this); | |
| 522 loadChunk(/* firstChunk */ true).catch(function(error) { | |
| 483 console.error(error.stack || error); | 523 console.error(error.stack || error); |
| 484 }); | 524 }); |
| 485 }; | 525 }; |
| 486 | 526 |
| 487 /** | 527 /** |
| 488 * Handles user's 'Close' action. | 528 * Handles user's 'Close' action. |
| 489 * @private | 529 * @private |
| 490 */ | 530 */ |
| 491 Gallery.prototype.onClose_ = function() { | 531 Gallery.prototype.onClose_ = function() { |
| 492 this.executeWhenReady(this.context_.onClose); | 532 this.executeWhenReady(this.context_.onClose); |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 941 window.loadTimeData.data = backgroundComponents.stringData; | 981 window.loadTimeData.data = backgroundComponents.stringData; |
| 942 gallery = new Gallery(backgroundComponents.volumeManager); | 982 gallery = new Gallery(backgroundComponents.volumeManager); |
| 943 }; | 983 }; |
| 944 | 984 |
| 945 /** | 985 /** |
| 946 * Loads entries. | 986 * Loads entries. |
| 947 */ | 987 */ |
| 948 window.loadEntries = function(entries, selectedEntries) { | 988 window.loadEntries = function(entries, selectedEntries) { |
| 949 gallery.load(entries, selectedEntries); | 989 gallery.load(entries, selectedEntries); |
| 950 }; | 990 }; |
| OLD | NEW |