Index: chrome/browser/resources/file_manager/js/photo/ribbon.js |
diff --git a/chrome/browser/resources/file_manager/js/photo/ribbon.js b/chrome/browser/resources/file_manager/js/photo/ribbon.js |
deleted file mode 100644 |
index 04ec68e020cc6bc88204d1aaea8df8480fc8ea80..0000000000000000000000000000000000000000 |
--- a/chrome/browser/resources/file_manager/js/photo/ribbon.js |
+++ /dev/null |
@@ -1,366 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-'use strict'; |
- |
-/** |
- * Scrollable thumbnail ribbon at the bottom of the Gallery in the Slide mode. |
- * |
- * @param {Document} document Document. |
- * @param {MetadataCache} metadataCache MetadataCache instance. |
- * @param {cr.ui.ArrayDataModel} dataModel Data model. |
- * @param {cr.ui.ListSelectionModel} selectionModel Selection model. |
- * @return {Element} Ribbon element. |
- * @constructor |
- */ |
-function Ribbon(document, metadataCache, dataModel, selectionModel) { |
- var self = document.createElement('div'); |
- Ribbon.decorate(self, metadataCache, dataModel, selectionModel); |
- return self; |
-} |
- |
-/** |
- * Inherit from HTMLDivElement. |
- */ |
-Ribbon.prototype.__proto__ = HTMLDivElement.prototype; |
- |
-/** |
- * Decorate a Ribbon instance. |
- * |
- * @param {Ribbon} self Self pointer. |
- * @param {MetadataCache} metadataCache MetadataCache instance. |
- * @param {cr.ui.ArrayDataModel} dataModel Data model. |
- * @param {cr.ui.ListSelectionModel} selectionModel Selection model. |
- */ |
-Ribbon.decorate = function(self, metadataCache, dataModel, selectionModel) { |
- self.__proto__ = Ribbon.prototype; |
- self.metadataCache_ = metadataCache; |
- self.dataModel_ = dataModel; |
- self.selectionModel_ = selectionModel; |
- |
- self.className = 'ribbon'; |
-}; |
- |
-/** |
- * Max number of thumbnails in the ribbon. |
- * @type {number} |
- */ |
-Ribbon.ITEMS_COUNT = 5; |
- |
-/** |
- * Force redraw the ribbon. |
- */ |
-Ribbon.prototype.redraw = function() { |
- this.onSelection_(); |
-}; |
- |
-/** |
- * Clear all cached data to force full redraw on the next selection change. |
- */ |
-Ribbon.prototype.reset = function() { |
- this.renderCache_ = {}; |
- this.firstVisibleIndex_ = 0; |
- this.lastVisibleIndex_ = -1; // Zero thumbnails |
-}; |
- |
-/** |
- * Enable the ribbon. |
- */ |
-Ribbon.prototype.enable = function() { |
- this.onContentBound_ = this.onContentChange_.bind(this); |
- this.dataModel_.addEventListener('content', this.onContentBound_); |
- |
- this.onSpliceBound_ = this.onSplice_.bind(this); |
- this.dataModel_.addEventListener('splice', this.onSpliceBound_); |
- |
- this.onSelectionBound_ = this.onSelection_.bind(this); |
- this.selectionModel_.addEventListener('change', this.onSelectionBound_); |
- |
- this.reset(); |
- this.redraw(); |
-}; |
- |
-/** |
- * Disable ribbon. |
- */ |
-Ribbon.prototype.disable = function() { |
- this.dataModel_.removeEventListener('content', this.onContentBound_); |
- this.dataModel_.removeEventListener('splice', this.onSpliceBound_); |
- this.selectionModel_.removeEventListener('change', this.onSelectionBound_); |
- |
- this.removeVanishing_(); |
- this.textContent = ''; |
-}; |
- |
-/** |
- * Data model splice handler. |
- * @param {Event} event Event. |
- * @private |
- */ |
-Ribbon.prototype.onSplice_ = function(event) { |
- if (event.removed.length == 0) |
- return; |
- |
- if (event.removed.length > 1) { |
- console.error('Cannot remove multiple items'); |
- return; |
- } |
- |
- var removed = this.renderCache_[event.removed[0].getUrl()]; |
- if (!removed || !removed.parentNode || !removed.hasAttribute('selected')) { |
- console.error('Can only remove the selected item'); |
- return; |
- } |
- |
- var persistentNodes = this.querySelectorAll('.ribbon-image:not([vanishing])'); |
- if (this.lastVisibleIndex_ < this.dataModel_.length) { // Not at the end. |
- var lastNode = persistentNodes[persistentNodes.length - 1]; |
- if (lastNode.nextSibling) { |
- // Pull back a vanishing node from the right. |
- lastNode.nextSibling.removeAttribute('vanishing'); |
- } else { |
- // Push a new item at the right end. |
- this.appendChild(this.renderThumbnail_(this.lastVisibleIndex_)); |
- } |
- } else { |
- // No items to the right, move the window to the left. |
- this.lastVisibleIndex_--; |
- if (this.firstVisibleIndex_) { |
- this.firstVisibleIndex_--; |
- var firstNode = persistentNodes[0]; |
- if (firstNode.previousSibling) { |
- // Pull back a vanishing node from the left. |
- firstNode.previousSibling.removeAttribute('vanishing'); |
- } else { |
- // Push a new item at the left end. |
- var newThumbnail = this.renderThumbnail_(this.firstVisibleIndex_); |
- newThumbnail.style.marginLeft = -(this.clientHeight - 2) + 'px'; |
- this.insertBefore(newThumbnail, this.firstChild); |
- setTimeout(function() { |
- newThumbnail.style.marginLeft = '0'; |
- }, 0); |
- } |
- } |
- } |
- |
- removed.removeAttribute('selected'); |
- removed.setAttribute('vanishing', 'smooth'); |
- this.scheduleRemove_(); |
-}; |
- |
-/** |
- * Selection change handler. |
- * @private |
- */ |
-Ribbon.prototype.onSelection_ = function() { |
- var indexes = this.selectionModel_.selectedIndexes; |
- if (indexes.length == 0) |
- return; // Ignore temporary empty selection. |
- var selectedIndex = indexes[0]; |
- |
- var length = this.dataModel_.length; |
- |
- // TODO(dgozman): use margin instead of 2 here. |
- var itemWidth = this.clientHeight - 2; |
- var fullItems = Ribbon.ITEMS_COUNT; |
- fullItems = Math.min(fullItems, length); |
- var right = Math.floor((fullItems - 1) / 2); |
- |
- var fullWidth = fullItems * itemWidth; |
- this.style.width = fullWidth + 'px'; |
- |
- var lastIndex = selectedIndex + right; |
- lastIndex = Math.max(lastIndex, fullItems - 1); |
- lastIndex = Math.min(lastIndex, length - 1); |
- var firstIndex = lastIndex - fullItems + 1; |
- |
- if (this.firstVisibleIndex_ != firstIndex || |
- this.lastVisibleIndex_ != lastIndex) { |
- |
- if (this.lastVisibleIndex_ == -1) { |
- this.firstVisibleIndex_ = firstIndex; |
- this.lastVisibleIndex_ = lastIndex; |
- } |
- |
- this.removeVanishing_(); |
- |
- this.textContent = ''; |
- var startIndex = Math.min(firstIndex, this.firstVisibleIndex_); |
- // All the items except the first one treated equally. |
- for (var index = startIndex + 1; |
- index <= Math.max(lastIndex, this.lastVisibleIndex_); |
- ++index) { |
- // Only add items that are in either old or the new viewport. |
- if (this.lastVisibleIndex_ < index && index < firstIndex || |
- lastIndex < index && index < this.firstVisibleIndex_) |
- continue; |
- var box = this.renderThumbnail_(index); |
- box.style.marginLeft = '0'; |
- this.appendChild(box); |
- if (index < firstIndex || index > lastIndex) { |
- // If the node is not in the new viewport we only need it while |
- // the animation is playing out. |
- box.setAttribute('vanishing', 'slide'); |
- } |
- } |
- |
- var slideCount = this.childNodes.length + 1 - Ribbon.ITEMS_COUNT; |
- var margin = itemWidth * slideCount; |
- var startBox = this.renderThumbnail_(startIndex); |
- if (startIndex == firstIndex) { |
- // Sliding to the right. |
- startBox.style.marginLeft = -margin + 'px'; |
- if (this.firstChild) |
- this.insertBefore(startBox, this.firstChild); |
- else |
- this.appendChild(startBox); |
- setTimeout(function() { |
- startBox.style.marginLeft = '0'; |
- }, 0); |
- } else { |
- // Sliding to the left. Start item will become invisible and should be |
- // removed afterwards. |
- startBox.setAttribute('vanishing', 'slide'); |
- startBox.style.marginLeft = '0'; |
- if (this.firstChild) |
- this.insertBefore(startBox, this.firstChild); |
- else |
- this.appendChild(startBox); |
- setTimeout(function() { |
- startBox.style.marginLeft = -margin + 'px'; |
- }, 0); |
- } |
- |
- ImageUtil.setClass(this, 'fade-left', |
- firstIndex > 0 && selectedIndex != firstIndex); |
- |
- ImageUtil.setClass(this, 'fade-right', |
- lastIndex < length - 1 && selectedIndex != lastIndex); |
- |
- this.firstVisibleIndex_ = firstIndex; |
- this.lastVisibleIndex_ = lastIndex; |
- |
- this.scheduleRemove_(); |
- } |
- |
- var oldSelected = this.querySelector('[selected]'); |
- if (oldSelected) oldSelected.removeAttribute('selected'); |
- |
- var newSelected = |
- this.renderCache_[this.dataModel_.item(selectedIndex).getUrl()]; |
- if (newSelected) newSelected.setAttribute('selected', true); |
-}; |
- |
-/** |
- * Schedule the removal of thumbnails marked as vanishing. |
- * @private |
- */ |
-Ribbon.prototype.scheduleRemove_ = function() { |
- if (this.removeTimeout_) |
- clearTimeout(this.removeTimeout_); |
- |
- this.removeTimeout_ = setTimeout(function() { |
- this.removeTimeout_ = null; |
- this.removeVanishing_(); |
- }.bind(this), 200); |
-}; |
- |
-/** |
- * Remove all thumbnails marked as vanishing. |
- * @private |
- */ |
-Ribbon.prototype.removeVanishing_ = function() { |
- if (this.removeTimeout_) { |
- clearTimeout(this.removeTimeout_); |
- this.removeTimeout_ = 0; |
- } |
- var vanishingNodes = this.querySelectorAll('[vanishing]'); |
- for (var i = 0; i != vanishingNodes.length; i++) { |
- vanishingNodes[i].removeAttribute('vanishing'); |
- this.removeChild(vanishingNodes[i]); |
- } |
-}; |
- |
-/** |
- * Create a DOM element for a thumbnail. |
- * |
- * @param {number} index Item index. |
- * @return {Element} Newly created element. |
- * @private |
- */ |
-Ribbon.prototype.renderThumbnail_ = function(index) { |
- var item = this.dataModel_.item(index); |
- var url = item.getUrl(); |
- |
- var cached = this.renderCache_[url]; |
- if (cached) { |
- var img = cached.querySelector('img'); |
- if (img) |
- img.classList.add('cached'); |
- return cached; |
- } |
- |
- var thumbnail = this.ownerDocument.createElement('div'); |
- thumbnail.className = 'ribbon-image'; |
- thumbnail.addEventListener('click', function() { |
- var index = this.dataModel_.indexOf(item); |
- this.selectionModel_.unselectAll(); |
- this.selectionModel_.setIndexSelected(index, true); |
- }.bind(this)); |
- |
- util.createChild(thumbnail, 'image-wrapper'); |
- |
- this.metadataCache_.get(url, Gallery.METADATA_TYPE, |
- this.setThumbnailImage_.bind(this, thumbnail, url)); |
- |
- // TODO: Implement LRU eviction. |
- // Never evict the thumbnails that are currently in the DOM because we rely |
- // on this cache to find them by URL. |
- this.renderCache_[url] = thumbnail; |
- return thumbnail; |
-}; |
- |
-/** |
- * Set the thumbnail image. |
- * |
- * @param {Element} thumbnail Thumbnail element. |
- * @param {string} url Image url. |
- * @param {Object} metadata Metadata. |
- * @private |
- */ |
-Ribbon.prototype.setThumbnailImage_ = function(thumbnail, url, metadata) { |
- new ThumbnailLoader(url, ThumbnailLoader.LoaderType.IMAGE, metadata).load( |
- thumbnail.querySelector('.image-wrapper'), |
- ThumbnailLoader.FillMode.FILL /* fill */, |
- ThumbnailLoader.OptimizationMode.NEVER_DISCARD); |
-}; |
- |
-/** |
- * Content change handler. |
- * |
- * @param {Event} event Event. |
- * @private |
- */ |
-Ribbon.prototype.onContentChange_ = function(event) { |
- var url = event.item.getUrl(); |
- this.remapCache_(event.oldUrl, url); |
- |
- var thumbnail = this.renderCache_[url]; |
- if (thumbnail && event.metadata) |
- this.setThumbnailImage_(thumbnail, url, event.metadata); |
-}; |
- |
-/** |
- * Update the thumbnail element cache. |
- * |
- * @param {string} oldUrl Old url. |
- * @param {string} newUrl New url. |
- * @private |
- */ |
-Ribbon.prototype.remapCache_ = function(oldUrl, newUrl) { |
- if (oldUrl != newUrl && (oldUrl in this.renderCache_)) { |
- this.renderCache_[newUrl] = this.renderCache_[oldUrl]; |
- delete this.renderCache_[oldUrl]; |
- } |
-}; |