| Index: ui/file_manager/gallery/js/mosaic_mode.js
|
| diff --git a/ui/file_manager/gallery/js/mosaic_mode.js b/ui/file_manager/gallery/js/mosaic_mode.js
|
| index acd553cb16f41b445b5ebd39ee388abe5297d42b..c5cec1ae61373fa78526e293836542b4eb604c31 100644
|
| --- a/ui/file_manager/gallery/js/mosaic_mode.js
|
| +++ b/ui/file_manager/gallery/js/mosaic_mode.js
|
| @@ -3,18 +3,19 @@
|
| // found in the LICENSE file.
|
|
|
| /**
|
| - * @param {Element} container Content container.
|
| - * @param {ErrorBanner} errorBanner Error banner.
|
| - * @param {cr.ui.ArrayDataModel} dataModel Data model.
|
| - * @param {cr.ui.ListSelectionModel} selectionModel Selection model.
|
| + * @param {!Element} container Content container.
|
| + * @param {!ErrorBanner} errorBanner Error banner.
|
| + * @param {!cr.ui.ArrayDataModel} dataModel Data model.
|
| + * @param {!cr.ui.ListSelectionModel} selectionModel Selection model.
|
| * @param {!VolumeManager} volumeManager Volume manager.
|
| * @param {function()} toggleMode Function to switch to the Slide mode.
|
| * @constructor
|
| + * @struct
|
| */
|
| function MosaicMode(
|
| container, errorBanner, dataModel, selectionModel, volumeManager,
|
| toggleMode) {
|
| - this.mosaic_ = new Mosaic(container.ownerDocument, errorBanner,
|
| + this.mosaic_ = new Mosaic(assert(container.ownerDocument), errorBanner,
|
| dataModel, selectionModel, volumeManager);
|
| container.appendChild(this.mosaic_);
|
|
|
| @@ -24,7 +25,7 @@ function MosaicMode(
|
| }
|
|
|
| /**
|
| - * @return {Mosaic} The mosaic control.
|
| + * @return {!Mosaic} The mosaic control.
|
| */
|
| MosaicMode.prototype.getMosaic = function() { return this.mosaic_; };
|
|
|
| @@ -52,7 +53,7 @@ MosaicMode.prototype.hasActiveTool = function() { return true; };
|
| /**
|
| * Keydown handler.
|
| *
|
| - * @param {Event} event Event.
|
| + * @param {!Event} event Event.
|
| */
|
| MosaicMode.prototype.onKeyDown = function(event) {
|
| switch (util.getKeyModifiers(event) + event.keyIdentifier) {
|
| @@ -72,17 +73,20 @@ MosaicMode.prototype.onKeyDown = function(event) {
|
| /**
|
| * Mosaic control.
|
| *
|
| - * @param {Document} document Document.
|
| - * @param {ErrorBanner} errorBanner Error banner.
|
| - * @param {cr.ui.ArrayDataModel} dataModel Data model.
|
| - * @param {cr.ui.ListSelectionModel} selectionModel Selection model.
|
| - * @param {VolumeManagerWrapper} volumeManager Volume manager.
|
| - * @return {Element} Mosaic element.
|
| + * @param {!Document} document Document.
|
| + * @param {!ErrorBanner} errorBanner Error banner.
|
| + * @param {!cr.ui.ArrayDataModel} dataModel Data model.
|
| + * @param {!cr.ui.ListSelectionModel} selectionModel Selection model.
|
| + * @param {!VolumeManager} volumeManager Volume manager.
|
| + * @return {!Element} Mosaic element.
|
| * @constructor
|
| + * @struct
|
| + * @extends {HTMLDivElement}
|
| + * @suppress {checkStructDictInheritance}
|
| */
|
| function Mosaic(document, errorBanner, dataModel, selectionModel,
|
| volumeManager) {
|
| - var self = document.createElement('div');
|
| + var self = assertInstanceof(document.createElement('div'), HTMLDivElement);
|
| Mosaic.decorate(self, errorBanner, dataModel, selectionModel, volumeManager);
|
| return self;
|
| }
|
| @@ -110,15 +114,16 @@ Mosaic.ANIMATED_SCROLL_DURATION = 500;
|
| /**
|
| * Decorates a Mosaic instance.
|
| *
|
| - * @param {Mosaic} self Self pointer.
|
| - * @param {ErrorBanner} errorBanner Error banner.
|
| - * @param {cr.ui.ArrayDataModel} dataModel Data model.
|
| - * @param {cr.ui.ListSelectionModel} selectionModel Selection model.
|
| - * @param {VolumeManagerWrapper} volumeManager Volume manager.
|
| + * @param {!HTMLDivElement} self Self pointer.
|
| + * @param {!ErrorBanner} errorBanner Error banner.
|
| + * @param {!cr.ui.ArrayDataModel} dataModel Data model.
|
| + * @param {!cr.ui.ListSelectionModel} selectionModel Selection model.
|
| + * @param {!VolumeManager} volumeManager Volume manager.
|
| */
|
| Mosaic.decorate = function(
|
| self, errorBanner, dataModel, selectionModel, volumeManager) {
|
| self.__proto__ = Mosaic.prototype;
|
| + self = /** @type {!Mosaic} */ (self);
|
| self.className = 'mosaic';
|
|
|
| self.dataModel_ = dataModel;
|
| @@ -126,6 +131,60 @@ Mosaic.decorate = function(
|
| self.volumeManager_ = volumeManager;
|
| self.errorBanner_ = errorBanner;
|
|
|
| + /**
|
| + * @type {Array.<!Mosaic.Tile>}
|
| + * @private
|
| + */
|
| + self.tiles_ = null;
|
| +
|
| + /**
|
| + * @type {boolean}
|
| + * @private
|
| + */
|
| + self.loadVisibleTilesSuppressed_ = false;
|
| +
|
| + /**
|
| + * @type {boolean}
|
| + * @private
|
| + */
|
| + self.loadVisibleTilesScheduled_ = false;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + self.showingTimeoutID_ = 0;
|
| +
|
| + /**
|
| + * @type {Mosaic.SelectionController}
|
| + * @private
|
| + */
|
| + self.selectionController_ = null;
|
| +
|
| + /**
|
| + * @type {Mosaic.Layout}
|
| + * @private
|
| + */
|
| + self.layoutModel_ = null;
|
| +
|
| + /**
|
| + * @type {boolean}
|
| + * @private
|
| + */
|
| + self.suppressHovering_ = false;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + self.layoutTimer_ = 0;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + self.scrollAnimation_ = 0;
|
| +
|
| // Initialization is completed lazily on the first call to |init|.
|
| };
|
|
|
| @@ -201,7 +260,7 @@ Mosaic.prototype.initListeners_ = function() {
|
| Mosaic.prototype.animatedScrollTo = function(targetPosition) {
|
| if (this.scrollAnimation_) {
|
| webkitCancelAnimationFrame(this.scrollAnimation_);
|
| - this.scrollAnimation_ = null;
|
| + this.scrollAnimation_ = 0;
|
| }
|
|
|
| // Mouse move events are fired without touching the mouse because of scrolling
|
| @@ -270,10 +329,10 @@ Mosaic.prototype.getTileRect = function(index) {
|
| };
|
|
|
| /**
|
| - * @param {number} index Tile index.
|
| * Scroll the given tile into the viewport.
|
| + * @param {number} index Tile index.
|
| */
|
| -Mosaic.prototype.scrollIntoView = function(index) {
|
| +Mosaic.prototype.scrollIntoViewByIndex = function(index) {
|
| var tile = this.tiles_[index];
|
| if (tile) tile.scrollIntoView();
|
| };
|
| @@ -281,7 +340,7 @@ Mosaic.prototype.scrollIntoView = function(index) {
|
| /**
|
| * Initializes multiple tiles.
|
| *
|
| - * @param {Array.<Mosaic.Tile>} tiles Array of tiles.
|
| + * @param {!Array.<!Mosaic.Tile>} tiles Array of tiles.
|
| * @private
|
| */
|
| Mosaic.prototype.initTiles_ = function(tiles) {
|
| @@ -308,7 +367,7 @@ Mosaic.prototype.reload = function() {
|
| Mosaic.prototype.layout = function() {
|
| if (this.layoutTimer_) {
|
| clearTimeout(this.layoutTimer_);
|
| - this.layoutTimer_ = null;
|
| + this.layoutTimer_ = 0;
|
| }
|
| while (true) {
|
| var index = this.layoutModel_.getTileCount();
|
| @@ -330,7 +389,7 @@ Mosaic.prototype.layout = function() {
|
| Mosaic.prototype.scheduleLayout = function(opt_delay) {
|
| if (!this.layoutTimer_) {
|
| this.layoutTimer_ = setTimeout(function() {
|
| - this.layoutTimer_ = null;
|
| + this.layoutTimer_ = 0;
|
| this.layout();
|
| }.bind(this), opt_delay || 0);
|
| }
|
| @@ -350,7 +409,7 @@ Mosaic.prototype.onResize_ = function() {
|
| /**
|
| * Mouse event handler.
|
| *
|
| - * @param {Event} event Event.
|
| + * @param {!Event} event Event.
|
| * @private
|
| */
|
| Mosaic.prototype.onMouseEvent_ = function(event) {
|
| @@ -386,7 +445,7 @@ Mosaic.prototype.onScroll_ = function() {
|
| /**
|
| * Selection change handler.
|
| *
|
| - * @param {Event} event Event.
|
| + * @param {!Event} event Event.
|
| * @private
|
| */
|
| Mosaic.prototype.onSelection_ = function(event) {
|
| @@ -400,7 +459,7 @@ Mosaic.prototype.onSelection_ = function(event) {
|
| /**
|
| * Leads item change handler.
|
| *
|
| - * @param {Event} event Event.
|
| + * @param {!Event} event Event.
|
| * @private
|
| */
|
| Mosaic.prototype.onLeadChange_ = function(event) {
|
| @@ -414,7 +473,7 @@ Mosaic.prototype.onLeadChange_ = function(event) {
|
| /**
|
| * Splice event handler.
|
| *
|
| - * @param {Event} event Event.
|
| + * @param {!Event} event Event.
|
| * @private
|
| */
|
| Mosaic.prototype.onSplice_ = function(event) {
|
| @@ -456,7 +515,7 @@ Mosaic.prototype.onSplice_ = function(event) {
|
| /**
|
| * Content change handler.
|
| *
|
| - * @param {Event} event Event.
|
| + * @param {!Event} event Event.
|
| * @private
|
| */
|
| Mosaic.prototype.onContentChange_ = function(event) {
|
| @@ -481,7 +540,7 @@ Mosaic.prototype.onContentChange_ = function(event) {
|
| /**
|
| * Keydown event handler.
|
| *
|
| - * @param {Event} event Event.
|
| + * @param {!Event} event Event.
|
| * @return {boolean} True if the event has been consumed.
|
| */
|
| Mosaic.prototype.onKeyDown = function(event) {
|
| @@ -518,7 +577,7 @@ Mosaic.prototype.show = function() {
|
| duration -= 100;
|
| }
|
| this.showingTimeoutID_ = setTimeout(function() {
|
| - this.showingTimeoutID_ = null;
|
| + this.showingTimeoutID_ = 0;
|
| // Make the selection visible.
|
| // If the mosaic is not animated it will start fading in now.
|
| this.setAttribute('visible', 'normal');
|
| @@ -532,9 +591,9 @@ Mosaic.prototype.show = function() {
|
| Mosaic.prototype.hide = function() {
|
| this.errorBanner_.clear();
|
|
|
| - if (this.showingTimeoutID_ !== null) {
|
| + if (this.showingTimeoutID_ !== 0) {
|
| clearTimeout(this.showingTimeoutID_);
|
| - this.showingTimeoutID_ = null;
|
| + this.showingTimeoutID_ = 0;
|
| }
|
| this.removeAttribute('visible');
|
| };
|
| @@ -660,11 +719,13 @@ Mosaic.prototype.getItemCount_ = function() {
|
|
|
| /**
|
| * Creates a selection controller that is to be used with grid.
|
| - * @param {cr.ui.ListSelectionModel} selectionModel The selection model to
|
| + * @param {!cr.ui.ListSelectionModel} selectionModel The selection model to
|
| * interact with.
|
| - * @param {Mosaic.Layout} layoutModel The layout model to use.
|
| + * @param {!Mosaic.Layout} layoutModel The layout model to use.
|
| * @constructor
|
| - * @extends {!cr.ui.ListSelectionController}
|
| + * @struct
|
| + * @extends {cr.ui.ListSelectionController}
|
| + * @suppress {checkStructDictInheritance}
|
| */
|
| Mosaic.SelectionController = function(selectionModel, layoutModel) {
|
| cr.ui.ListSelectionController.call(this, selectionModel);
|
| @@ -710,51 +771,89 @@ Mosaic.SelectionController.prototype.getIndexBelow = function(index) {
|
| * @param {string=} opt_mode Layout mode.
|
| * @param {Mosaic.Density=} opt_maxDensity Layout density.
|
| * @constructor
|
| + * @struct
|
| */
|
| Mosaic.Layout = function(opt_mode, opt_maxDensity) {
|
| - this.mode_ = opt_mode || Mosaic.Layout.MODE_TENTATIVE;
|
| + this.mode_ = opt_mode || Mosaic.Layout.Mode.TENTATIVE;
|
| this.maxDensity_ = opt_maxDensity || Mosaic.Density.createHighest();
|
| +
|
| + /**
|
| + * @type {!Array.<!Mosaic.Column>}
|
| + * @private
|
| + */
|
| + this.columns_ = [];
|
| +
|
| + /**
|
| + * @type {Mosaic.Column}
|
| + * @private
|
| + */
|
| + this.newColumn_ = null;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + this.viewportWidth_ = 0;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + this.viewportHeight_ = 0;
|
| +
|
| + /**
|
| + * @type {Mosaic.Density}
|
| + * @private
|
| + */
|
| + this.density_ = null;
|
| +
|
| this.reset_();
|
| };
|
|
|
| /**
|
| * Blank space at the top of the mosaic element. We do not do that in CSS
|
| * to make transition effects easier.
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Layout.PADDING_TOP = 50;
|
|
|
| /**
|
| * Blank space at the bottom of the mosaic element.
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Layout.PADDING_BOTTOM = 50;
|
|
|
| /**
|
| * Horizontal and vertical spacing between images. Should be kept in sync
|
| * with the style of .mosaic-item in gallery.css (= 2 * ( 4 + 1))
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Layout.SPACING = 10;
|
|
|
| /**
|
| * Margin for scrolling using keyboard. Distance between a selected tile
|
| * and window border.
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Layout.SCROLL_MARGIN = 30;
|
|
|
| /**
|
| - * Layout mode: commit to DOM immediately.
|
| + * Layout mode.
|
| + * @enum {string}
|
| */
|
| -Mosaic.Layout.MODE_FINAL = 'final';
|
| -
|
| -/**
|
| - * Layout mode: do not commit layout to DOM until it is complete or the viewport
|
| - * overflows.
|
| - */
|
| -Mosaic.Layout.MODE_TENTATIVE = 'tentative';
|
| -
|
| -/**
|
| - * Layout mode: never commit layout to DOM.
|
| - */
|
| -Mosaic.Layout.MODE_DRY_RUN = 'dry_run';
|
| +Mosaic.Layout.Mode = {
|
| + // Commit to DOM immediately.
|
| + FINAL: 'final',
|
| + // Do not commit layout to DOM until it is complete or the viewport
|
| + // overflows.
|
| + TENTATIVE: 'tentative',
|
| + // Never commit layout to DOM.
|
| + DRY_RUN: 'dry_run',
|
| +};
|
|
|
| /**
|
| * Resets the layout.
|
| @@ -765,8 +864,8 @@ Mosaic.Layout.prototype.reset_ = function() {
|
| this.columns_ = [];
|
| this.newColumn_ = null;
|
| this.density_ = Mosaic.Density.createLowest();
|
| - if (this.mode_ !== Mosaic.Layout.MODE_DRY_RUN) // DRY_RUN is sticky.
|
| - this.mode_ = Mosaic.Layout.MODE_TENTATIVE;
|
| + if (this.mode_ !== Mosaic.Layout.Mode.DRY_RUN) // DRY_RUN is sticky.
|
| + this.mode_ = Mosaic.Layout.Mode.TENTATIVE;
|
| };
|
|
|
| /**
|
| @@ -796,7 +895,7 @@ Mosaic.Layout.prototype.getHeight = function() {
|
| };
|
|
|
| /**
|
| - * @return {Array.<Mosaic.Tile>} All tiles in the layout.
|
| + * @return {!Array.<!Mosaic.Tile>} All tiles in the layout.
|
| */
|
| Mosaic.Layout.prototype.getTiles = function() {
|
| return Array.prototype.concat.apply([],
|
| @@ -830,7 +929,7 @@ Mosaic.Layout.prototype.getLaidOutTileCount = function() {
|
| /**
|
| * Adds a tile to the layout.
|
| *
|
| - * @param {Mosaic.Tile} tile The tile to be added.
|
| + * @param {!Mosaic.Tile} tile The tile to be added.
|
| * @param {boolean} isLast True if this tile is the last.
|
| */
|
| Mosaic.Layout.prototype.add = function(tile, isLast) {
|
| @@ -876,7 +975,7 @@ Mosaic.Layout.prototype.add = function(tile, isLast) {
|
| this.columns_.push(this.newColumn_);
|
| this.newColumn_ = null;
|
|
|
| - if (this.mode_ === Mosaic.Layout.MODE_FINAL && isFinalColumn) {
|
| + if (this.mode_ === Mosaic.Layout.Mode.FINAL && isFinalColumn) {
|
| this.commit_();
|
| continue;
|
| }
|
| @@ -885,7 +984,7 @@ Mosaic.Layout.prototype.add = function(tile, isLast) {
|
| // Viewport completely filled.
|
| if (this.density_.equals(this.maxDensity_)) {
|
| // Max density reached, commit if tentative, just continue if dry run.
|
| - if (this.mode_ === Mosaic.Layout.MODE_TENTATIVE)
|
| + if (this.mode_ === Mosaic.Layout.Mode.TENTATIVE)
|
| this.commit_();
|
| continue;
|
| }
|
| @@ -897,7 +996,7 @@ Mosaic.Layout.prototype.add = function(tile, isLast) {
|
| continue;
|
| }
|
|
|
| - if (isFinalColumn && this.mode_ === Mosaic.Layout.MODE_TENTATIVE) {
|
| + if (isFinalColumn && this.mode_ === Mosaic.Layout.Mode.TENTATIVE) {
|
| // The complete tentative layout fits into the viewport.
|
| var stretched = this.findHorizontalLayout_();
|
| if (stretched)
|
| @@ -920,7 +1019,7 @@ Mosaic.Layout.prototype.commit_ = function(opt_offsetX, opt_offsetY) {
|
| for (var i = 0; i !== this.columns_.length; i++) {
|
| this.columns_[i].layout(opt_offsetX, opt_offsetY);
|
| }
|
| - this.mode_ = Mosaic.Layout.MODE_FINAL;
|
| + this.mode_ = Mosaic.Layout.Mode.FINAL;
|
| };
|
|
|
| /**
|
| @@ -952,7 +1051,7 @@ Mosaic.Layout.prototype.findHorizontalLayout_ = function() {
|
|
|
| for (var h = minTileHeight; h < this.viewportHeight_; h += minTileHeight) {
|
| var layout = new Mosaic.Layout(
|
| - Mosaic.Layout.MODE_DRY_RUN, this.density_.clone());
|
| + Mosaic.Layout.Mode.DRY_RUN, this.density_.clone());
|
| layout.setViewportSize(this.viewportWidth_, h);
|
| for (var t = 0; t !== tiles.length; t++)
|
| layout.add(tiles[t], t + 1 === tiles.length);
|
| @@ -980,14 +1079,14 @@ Mosaic.Layout.prototype.invalidateFromTile_ = function(index) {
|
| // The columns to the right cover the entire viewport width, so there is no
|
| // chance that the modified layout would fit into the viewport.
|
| // No point in restarting the entire layout, keep the columns to the right.
|
| - console.assert(this.mode_ === Mosaic.Layout.MODE_FINAL,
|
| + console.assert(this.mode_ === Mosaic.Layout.Mode.FINAL,
|
| 'Expected FINAL layout mode');
|
| this.columns_ = this.columns_.slice(0, columnIndex);
|
| this.newColumn_ = null;
|
| } else {
|
| // There is a chance that the modified layout would fit into the viewport.
|
| this.reset_();
|
| - this.mode_ = Mosaic.Layout.MODE_TENTATIVE;
|
| + this.mode_ = Mosaic.Layout.Mode.TENTATIVE;
|
| }
|
| };
|
|
|
| @@ -1099,7 +1198,7 @@ Mosaic.Layout.prototype.getColumnIndexByTile_ = function(index) {
|
| * 3. The relative proportions of the sizes should be as close to the original
|
| * as possible.
|
| *
|
| - * @param {Array.<number>} sizes Array of sizes.
|
| + * @param {!Array.<number>} sizes Array of sizes.
|
| * @param {number} newTotal New total size.
|
| */
|
| Mosaic.Layout.rescaleSizesToNewTotal = function(sizes, newTotal) {
|
| @@ -1128,6 +1227,7 @@ Mosaic.Layout.rescaleSizesToNewTotal = function(sizes, newTotal) {
|
| * @param {number} vertical Vertical density, frequency of rows forced to
|
| * contain a single tile.
|
| * @constructor
|
| + * @struct
|
| */
|
| Mosaic.Density = function(horizontal, vertical) {
|
| this.horizontal = horizontal;
|
| @@ -1136,26 +1236,34 @@ Mosaic.Density = function(horizontal, vertical) {
|
|
|
| /**
|
| * Minimal horizontal density (tiles per row).
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Density.MIN_HORIZONTAL = 1;
|
|
|
| /**
|
| * Minimal horizontal density (tiles per row).
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Density.MAX_HORIZONTAL = 3;
|
|
|
| /**
|
| * Minimal vertical density: force 1 out of 2 rows to containt a single tile.
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Density.MIN_VERTICAL = 2;
|
|
|
| /**
|
| * Maximal vertical density: force 1 out of 3 rows to containt a single tile.
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Density.MAX_VERTICAL = 3;
|
|
|
| /**
|
| - * @return {Mosaic.Density} Lowest density.
|
| + * @return {!Mosaic.Density} Lowest density.
|
| */
|
| Mosaic.Density.createLowest = function() {
|
| return new Mosaic.Density(
|
| @@ -1164,7 +1272,7 @@ Mosaic.Density.createLowest = function() {
|
| };
|
|
|
| /**
|
| - * @return {Mosaic.Density} Highest density.
|
| + * @return {!Mosaic.Density} Highest density.
|
| */
|
| Mosaic.Density.createHighest = function() {
|
| return new Mosaic.Density(
|
| @@ -1173,14 +1281,14 @@ Mosaic.Density.createHighest = function() {
|
| };
|
|
|
| /**
|
| - * @return {Mosaic.Density} A clone of this density object.
|
| + * @return {!Mosaic.Density} A clone of this density object.
|
| */
|
| Mosaic.Density.prototype.clone = function() {
|
| return new Mosaic.Density(this.horizontal, this.vertical);
|
| };
|
|
|
| /**
|
| - * @param {Mosaic.Density} that The other object.
|
| + * @param {!Mosaic.Density} that The other object.
|
| * @return {boolean} True if equal.
|
| */
|
| Mosaic.Density.prototype.equals = function(that) {
|
| @@ -1229,8 +1337,9 @@ Mosaic.Density.prototype.isRowComplete = function(tileCount, rowIndex) {
|
| * @param {number} firstTileIndex Index of the first tile in the column.
|
| * @param {number} left Left edge coordinate.
|
| * @param {number} maxHeight Maximum height.
|
| - * @param {Mosaic.Density} density Layout density.
|
| + * @param {!Mosaic.Density} density Layout density.
|
| * @constructor
|
| + * @struct
|
| */
|
| Mosaic.Column = function(index, firstRowIndex, firstTileIndex, left, maxHeight,
|
| density) {
|
| @@ -1241,6 +1350,42 @@ Mosaic.Column = function(index, firstRowIndex, firstTileIndex, left, maxHeight,
|
| this.maxHeight_ = maxHeight;
|
| this.density_ = density;
|
|
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + this.width_ = 0;
|
| +
|
| + /**
|
| + * @type {!Array.<!Mosaic.Tile>}
|
| + * @private
|
| + */
|
| + this.tiles_ = [];
|
| +
|
| + /**
|
| + * @type {!Array.<!Mosaic.Row>}
|
| + * @private
|
| + */
|
| + this.rows_ = [];
|
| +
|
| + /**
|
| + * @type {Mosaic.Row}
|
| + * @private
|
| + */
|
| + this.newRow_ = null;
|
| +
|
| + /**
|
| + * @type {!Array.<number>}
|
| + * @private
|
| + */
|
| + this.rowHeights_ = [];
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + this.height_ = 0;
|
| +
|
| this.reset_();
|
| };
|
|
|
| @@ -1274,7 +1419,7 @@ Mosaic.Column.prototype.getNextRowIndex = function() {
|
| };
|
|
|
| /**
|
| - * @return {Array.<Mosaic.Tile>} Array of tiles in the column.
|
| + * @return {!Array.<!Mosaic.Tile>} Array of tiles in the column.
|
| */
|
| Mosaic.Column.prototype.getTiles = function() { return this.tiles_ };
|
|
|
| @@ -1317,7 +1462,7 @@ Mosaic.Column.prototype.getRowByTileIndex = function(index) {
|
| /**
|
| * Adds a tile to the column.
|
| *
|
| - * @param {Mosaic.Tile} tile The tile to add.
|
| + * @param {!Mosaic.Tile} tile The tile to add.
|
| */
|
| Mosaic.Column.prototype.add = function(tile) {
|
| var rowIndex = this.getNextRowIndex();
|
| @@ -1461,14 +1606,27 @@ Mosaic.Column.prototype.isSuboptimal = function() {
|
| *
|
| * @param {number} firstTileIndex Index of the first tile in the row.
|
| * @constructor
|
| + * @struct
|
| */
|
| Mosaic.Row = function(firstTileIndex) {
|
| this.firstTileIndex_ = firstTileIndex;
|
| this.tiles_ = [];
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + this.top_ = 0;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + this.height_ = 0;
|
| };
|
|
|
| /**
|
| - * @param {Mosaic.Tile} tile The tile to add.
|
| + * @param {!Mosaic.Tile} tile The tile to add.
|
| */
|
| Mosaic.Row.prototype.add = function(tile) {
|
| console.assert(this.getTileCount() < Mosaic.Density.MAX_HORIZONTAL);
|
| @@ -1476,7 +1634,7 @@ Mosaic.Row.prototype.add = function(tile) {
|
| };
|
|
|
| /**
|
| - * @return {Array.<Mosaic.Tile>} Array of tiles in the row.
|
| + * @return {!Array.<!Mosaic.Tile>} Array of tiles in the row.
|
| */
|
| Mosaic.Row.prototype.getTiles = function() { return this.tiles_ };
|
|
|
| @@ -1616,32 +1774,113 @@ Mosaic.Row.prototype.layout = function(left, top, width, height) {
|
| /**
|
| * A single tile of the image mosaic.
|
| *
|
| - * @param {Element} container Container element.
|
| - * @param {Gallery.Item} item Gallery item associated with this tile.
|
| - * @param {EntryLocation} locationInfo Location information for the tile.
|
| - * @return {Element} The new tile element.
|
| + * @param {!Element} container Container element.
|
| + * @param {!Gallery.Item} item Gallery item associated with this tile.
|
| + * @param {EntryLocation=} opt_locationInfo Location information for the tile.
|
| + * @return {!Element} The new tile element.
|
| * @constructor
|
| + * @extends {HTMLDivElement}
|
| + * @struct
|
| + * @suppress {checkStructDictInheritance}
|
| */
|
| -Mosaic.Tile = function(container, item, locationInfo) {
|
| +Mosaic.Tile = function(container, item, opt_locationInfo) {
|
| var self = container.ownerDocument.createElement('div');
|
| - Mosaic.Tile.decorate(self, container, item, locationInfo);
|
| + Mosaic.Tile.decorate(self, container, item, opt_locationInfo);
|
| return self;
|
| };
|
|
|
| /**
|
| - * @param {Element} self Self pointer.
|
| - * @param {Element} container Container element.
|
| - * @param {Gallery.Item} item Gallery item associated with this tile.
|
| - * @param {EntryLocation} locationInfo Location info for the tile image.
|
| + * @param {!Element} self Self pointer.
|
| + * @param {!Element} container Container element.
|
| + * @param {!Gallery.Item} item Gallery item associated with this tile.
|
| + * @param {EntryLocation=} opt_locationInfo Location info for the tile image.
|
| */
|
| -Mosaic.Tile.decorate = function(self, container, item, locationInfo) {
|
| +Mosaic.Tile.decorate = function(self, container, item, opt_locationInfo) {
|
| self.__proto__ = Mosaic.Tile.prototype;
|
| + self = /** @type {!Mosaic.Tile} */ (self);
|
| self.className = 'mosaic-tile';
|
|
|
| self.container_ = container;
|
| self.item_ = item;
|
| + self.hidpiEmbedded_ = opt_locationInfo && opt_locationInfo.isDriveBased;
|
| +
|
| + /**
|
| + * @type {?number}
|
| + * @private
|
| + */
|
| self.left_ = null; // Mark as not laid out.
|
| - self.hidpiEmbedded_ = locationInfo && locationInfo.isDriveBased;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + self.top_ = 0;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + self.width_ = 0;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + self.height_ = 0;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + self.maxContentHeight_ = 0;
|
| +
|
| + /**
|
| + * @type {number}
|
| + * @private
|
| + */
|
| + self.aspectRatio_ = 0;
|
| +
|
| + /**
|
| + * @type {ThumbnailLoader}
|
| + * @private
|
| + */
|
| + self.thumbnailPreloader_ = null;
|
| +
|
| + /**
|
| + * @type {ThumbnailLoader}
|
| + * @private
|
| + */
|
| + self.thumbnailLoader_ = null;
|
| +
|
| + /**
|
| + * @type {boolean}
|
| + * @private
|
| + */
|
| + self.imagePreloaded_ = false;
|
| +
|
| + /**
|
| + * @type {boolean}
|
| + * @private
|
| + */
|
| + self.imageLoaded_ = false;
|
| +
|
| + /**
|
| + * @type {boolean}
|
| + * @private
|
| + */
|
| + self.imagePreloading_ = false;
|
| +
|
| + /**
|
| + * @type {boolean}
|
| + * @private
|
| + */
|
| + self.imageLoading_ = false;
|
| +
|
| + /**
|
| + * @type {HTMLDivElement}
|
| + * @private
|
| + */
|
| + self.wrapper_ = null;
|
| };
|
|
|
| /**
|
| @@ -1660,27 +1899,35 @@ Mosaic.Tile.prototype.__proto__ = HTMLDivElement.prototype;
|
|
|
| /**
|
| * Minimum tile content size.
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Tile.MIN_CONTENT_SIZE = 64;
|
|
|
| /**
|
| * Maximum tile content size.
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Tile.MAX_CONTENT_SIZE = 512;
|
|
|
| /**
|
| * Default size for a tile with no thumbnail image.
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Tile.GENERIC_ICON_SIZE = 128;
|
|
|
| /**
|
| * Max size of an image considered to be 'small'.
|
| * Small images are laid out slightly differently.
|
| + * @type {number}
|
| + * @const
|
| */
|
| Mosaic.Tile.SMALL_IMAGE_SIZE = 160;
|
|
|
| /**
|
| - * @return {Gallery.Item} The Gallery item.
|
| + * @return {!Gallery.Item} The Gallery item.
|
| */
|
| Mosaic.Tile.prototype.getItem = function() { return this.item_; };
|
|
|
| @@ -1843,7 +2090,7 @@ Mosaic.Tile.prototype.init = function() {
|
| * For the low-dpi mode, only low-dpi image is loaded. If not available, then
|
| * the high-dpi image is loaded as a fallback.
|
| *
|
| - * @param {Mosaic.Tile.LoadMode} loadMode Loading mode.
|
| + * @param {!Mosaic.Tile.LoadMode} loadMode Loading mode.
|
| * @param {function(boolean)} onImageLoaded Callback when image is loaded.
|
| * The argument is true for success, false for failure.
|
| */
|
| @@ -1951,7 +2198,8 @@ Mosaic.Tile.prototype.layout = function(left, top, width, height) {
|
| if (!this.wrapper_) { // First time, create DOM.
|
| this.container_.appendChild(this);
|
| var border = util.createChild(this, 'img-border');
|
| - this.wrapper_ = util.createChild(border, 'img-wrapper');
|
| + this.wrapper_ = assertInstanceof(util.createChild(border, 'img-wrapper'),
|
| + HTMLDivElement);
|
| }
|
| if (this.hasAttribute('selected'))
|
| this.scrollIntoView(false);
|
|
|