Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: chrome/browser/resources/file_manager/js/file_manager.js

Issue 9856014: Dragging files (not dropping yet). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review fixes. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 // Setting the src of an img to an empty string can crash the browser, so we 5 // Setting the src of an img to an empty string can crash the browser, so we
6 // use an empty 1x1 gif instead. 6 // use an empty 1x1 gif instead.
7 7
8 /** 8 /**
9 * FileManager constructor. 9 * FileManager constructor.
10 * 10 *
(...skipping 18 matching lines...) Expand all
29 this.selection = null; 29 this.selection = null;
30 30
31 this.butterTimer_ = null; 31 this.butterTimer_ = null;
32 this.currentButter_ = null; 32 this.currentButter_ = null;
33 this.butterLastShowTime_ = 0; 33 this.butterLastShowTime_ = 0;
34 34
35 this.watchedDirectoryUrl_ = null; 35 this.watchedDirectoryUrl_ = null;
36 36
37 this.commands_ = {}; 37 this.commands_ = {};
38 38
39 this.thumbnailUrlCache_ = {};
40
39 this.document_ = dialogDom.ownerDocument; 41 this.document_ = dialogDom.ownerDocument;
40 this.dialogType_ = this.params_.type || FileManager.DialogType.FULL_PAGE; 42 this.dialogType_ = this.params_.type || FileManager.DialogType.FULL_PAGE;
41 43
42 metrics.recordEnum('Create', this.dialogType_, 44 metrics.recordEnum('Create', this.dialogType_,
43 [FileManager.DialogType.SELECT_FOLDER, 45 [FileManager.DialogType.SELECT_FOLDER,
44 FileManager.DialogType.SELECT_SAVEAS_FILE, 46 FileManager.DialogType.SELECT_SAVEAS_FILE,
45 FileManager.DialogType.SELECT_OPEN_FILE, 47 FileManager.DialogType.SELECT_OPEN_FILE,
46 FileManager.DialogType.SELECT_OPEN_MULTI_FILE, 48 FileManager.DialogType.SELECT_OPEN_MULTI_FILE,
47 FileManager.DialogType.FULL_PAGE]); 49 FileManager.DialogType.FULL_PAGE]);
48 50
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 643
642 this.downloadsWarning_ = 644 this.downloadsWarning_ =
643 this.dialogDom_.querySelector('.downloads-warning'); 645 this.dialogDom_.querySelector('.downloads-warning');
644 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); 646 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING'));
645 this.downloadsWarning_.lastElementChild.innerHTML = html; 647 this.downloadsWarning_.lastElementChild.innerHTML = html;
646 var link = this.downloadsWarning_.querySelector('a'); 648 var link = this.downloadsWarning_.querySelector('a');
647 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this)); 649 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this));
648 650
649 this.document_.addEventListener('keydown', this.onKeyDown_.bind(this)); 651 this.document_.addEventListener('keydown', this.onKeyDown_.bind(this));
650 this.document_.addEventListener('copy', 652 this.document_.addEventListener('copy',
651 this.copySelectionToClipboard_.bind(this)); 653 this.onCopy_.bind(this));
652 // Disable the default browser context menu. 654 // Disable the default browser context menu.
653 this.document_.addEventListener('contextmenu', 655 this.document_.addEventListener('contextmenu',
654 function (e) { e.preventDefault() }); 656 function (e) { e.preventDefault() });
655 657
656 // We need to store a reference to the function returned by bind. Later, in 658 // We need to store a reference to the function returned by bind. Later, in
657 // canPaste function, we need to temporarily remove this event handler and 659 // canPaste function, we need to temporarily remove this event handler and
658 // use another 'paste' event handler to check the state of system clipboard. 660 // use another 'paste' event handler to check the state of system clipboard.
659 this.pasteFromClipboardBind_ = this.pasteFromClipboard_.bind(this); 661 this.onPasteBound_ = this.onPaste_.bind(this);
660 this.document_.addEventListener('paste', this.pasteFromClipboardBind_); 662 this.document_.addEventListener('paste', this.onPasteBound_);
661 663
662 // In pasteFromClipboard function, we need to reset system clipboard after 664 // In pasteFromClipboard function, we need to reset system clipboard after
663 // 'cut' and 'paste' command sequence. The clipboardData.clearData doesn't 665 // 'cut' and 'paste' command sequence. The clipboardData.clearData doesn't
664 // seem to work. We reset the system clipboard in another 'cut' event 666 // seem to work. We reset the system clipboard in another 'cut' event
665 // handler as a workaround. This reference is used to temporarily remove 667 // handler as a workaround. This reference is used to temporarily remove
666 // 'cut' event handler as well. 668 // 'cut' event handler as well.
667 this.cutFromClipboardBind_ = this.cutSelectionToClipboard_.bind(this); 669 this.onCutBound_ = this.onCut_.bind(this);
668 this.document_.addEventListener('cut', this.cutFromClipboardBind_); 670 this.document_.addEventListener('cut', this.onCutBound_);
669 671
670 this.renameInput_ = this.document_.createElement('input'); 672 this.renameInput_ = this.document_.createElement('input');
671 this.renameInput_.className = 'rename'; 673 this.renameInput_.className = 'rename';
672 674
673 this.renameInput_.addEventListener( 675 this.renameInput_.addEventListener(
674 'keydown', this.onRenameInputKeyDown_.bind(this)); 676 'keydown', this.onRenameInputKeyDown_.bind(this));
675 this.renameInput_.addEventListener( 677 this.renameInput_.addEventListener(
676 'blur', this.onRenameInputBlur_.bind(this)); 678 'blur', this.onRenameInputBlur_.bind(this));
677 679
678 this.filenameInput_.addEventListener( 680 this.filenameInput_.addEventListener(
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 var clipboardCanPaste = function(event) { 1109 var clipboardCanPaste = function(event) {
1108 event.preventDefault(); 1110 event.preventDefault();
1109 // Here we need to use lower case as clipboardData.types return lower 1111 // Here we need to use lower case as clipboardData.types return lower
1110 // case DomStringList. 1112 // case DomStringList.
1111 if (event.clipboardData && 1113 if (event.clipboardData &&
1112 event.clipboardData.types && 1114 event.clipboardData.types &&
1113 event.clipboardData.types.indexOf('fs/iscut') != -1) 1115 event.clipboardData.types.indexOf('fs/iscut') != -1)
1114 canPaste = true; 1116 canPaste = true;
1115 }; 1117 };
1116 1118
1117 this.document_.removeEventListener('paste', this.pasteFromClipboardBind_); 1119 this.document_.removeEventListener('paste', this.onPasteBound_);
1118 this.document_.addEventListener('paste', clipboardCanPaste); 1120 this.document_.addEventListener('paste', clipboardCanPaste);
1119 this.document_.execCommand('paste'); 1121 this.document_.execCommand('paste');
1120 this.document_.removeEventListener('paste', clipboardCanPaste); 1122 this.document_.removeEventListener('paste', clipboardCanPaste);
1121 this.document_.addEventListener('paste', this.pasteFromClipboardBind_); 1123 this.document_.addEventListener('paste', this.onPasteBound_);
1122 return canPaste && !readonly; 1124 return canPaste && !readonly;
1123 }; 1125 };
1124 1126
1125 /** 1127 /**
1126 * @param {string} commandId Command identifier. 1128 * @param {string} commandId Command identifier.
1127 * @return {boolean} True if the command can be executed for current 1129 * @return {boolean} True if the command can be executed for current
1128 * selection. 1130 * selection.
1129 */ 1131 */
1130 FileManager.prototype.canExecute_ = function(commandId) { 1132 FileManager.prototype.canExecute_ = function(commandId) {
1131 var readonly = this.directoryModel_.readonly; 1133 var readonly = this.directoryModel_.readonly;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 */ 1247 */
1246 FileManager.prototype.initGrid_ = function() { 1248 FileManager.prototype.initGrid_ = function() {
1247 var self = this; 1249 var self = this;
1248 this.grid_.itemConstructor = GridItem.bind(null, this); 1250 this.grid_.itemConstructor = GridItem.bind(null, this);
1249 1251
1250 this.grid_.addEventListener( 1252 this.grid_.addEventListener(
1251 'dblclick', this.onDetailDoubleClick_.bind(this)); 1253 'dblclick', this.onDetailDoubleClick_.bind(this));
1252 cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_); 1254 cr.ui.contextMenuHandler.setContextMenu(this.grid_, this.fileContextMenu_);
1253 this.grid_.addEventListener('mousedown', 1255 this.grid_.addEventListener('mousedown',
1254 this.onGridOrTableMouseDown_.bind(this)); 1256 this.onGridOrTableMouseDown_.bind(this));
1257 this.setupDragAndDrop_(this.grid_);
1255 }; 1258 };
1256 1259
1257 /** 1260 /**
1258 * Initialize the file list table. 1261 * Initialize the file list table.
1259 */ 1262 */
1260 FileManager.prototype.initTable_ = function() { 1263 FileManager.prototype.initTable_ = function() {
1261 var columns = [ 1264 var columns = [
1262 new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'), 1265 new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'),
1263 64), 1266 64),
1264 new cr.ui.table.TableColumn('cachedSize_', 1267 new cr.ui.table.TableColumn('cachedSize_',
(...skipping 24 matching lines...) Expand all
1289 1292
1290 // Don't pay attention to double clicks on the table header. 1293 // Don't pay attention to double clicks on the table header.
1291 this.table_.querySelector('.list').addEventListener( 1294 this.table_.querySelector('.list').addEventListener(
1292 'dblclick', this.onDetailDoubleClick_.bind(this)); 1295 'dblclick', this.onDetailDoubleClick_.bind(this));
1293 1296
1294 cr.ui.contextMenuHandler.setContextMenu(this.table_.querySelector('.list'), 1297 cr.ui.contextMenuHandler.setContextMenu(this.table_.querySelector('.list'),
1295 this.fileContextMenu_); 1298 this.fileContextMenu_);
1296 1299
1297 this.table_.addEventListener('mousedown', 1300 this.table_.addEventListener('mousedown',
1298 this.onGridOrTableMouseDown_.bind(this)); 1301 this.onGridOrTableMouseDown_.bind(this));
1302 this.setupDragAndDrop_(this.table_.list);
1303 };
1304
1305 FileManager.prototype.setupDragAndDrop_ = function(list) {
1306 list.addEventListener('dragstart', this.onDragStart_.bind(this));
1307 };
1308
1309 FileManager.prototype.onDragStart_ = function(event) {
1310 var dt = event.dataTransfer;
1311 var container = this.document_.querySelector('#drag-image-container');
1312 container.textContent = '';
1313 for (var i = 0; i < this.selection.dragNodes.length; i++) {
1314 var listItem = this.selection.dragNodes[i];
1315 listItem.selected = true;
1316 container.appendChild(listItem);
1317 }
1318
1319 this.cutOrCopyToClipboard_(dt, false);
1320
1321 dt.setDragImage(container, 0, 0);
1322 dt.effectAllowed = 'copyMove';
1299 }; 1323 };
1300 1324
1301 FileManager.prototype.initButter_ = function() { 1325 FileManager.prototype.initButter_ = function() {
1302 var self = this; 1326 var self = this;
1303 var progress = this.copyManager_.getProgress(); 1327 var progress = this.copyManager_.getProgress();
1304 1328
1305 var options = {progress: progress.percentage, actions:{}}; 1329 var options = {progress: progress.percentage, actions:{}};
1306 options.actions[str('CANCEL_LABEL')] = function cancelPaste() { 1330 options.actions[str('CANCEL_LABEL')] = function cancelPaste() {
1307 self.copyManager_.requestCancel(); 1331 self.copyManager_.requestCancel();
1308 }; 1332 };
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1722 * the image has been loaded before inserting 1746 * the image has been loaded before inserting
1723 * it into the DOM. 1747 * it into the DOM.
1724 * @return {HTMLDivElement} 1748 * @return {HTMLDivElement}
1725 */ 1749 */
1726 FileManager.prototype.renderThumbnailBox_ = function(entry, fill, 1750 FileManager.prototype.renderThumbnailBox_ = function(entry, fill,
1727 opt_imageLoadCallback) { 1751 opt_imageLoadCallback) {
1728 var box = this.document_.createElement('div'); 1752 var box = this.document_.createElement('div');
1729 box.className = 'img-container'; 1753 box.className = 'img-container';
1730 var img = this.document_.createElement('img'); 1754 var img = this.document_.createElement('img');
1731 var self = this; 1755 var self = this;
1732 this.getThumbnailURL(entry, function(iconType, url, transform) { 1756
1757 function onThumbnailURL(iconType, url, transform) {
1758 self.thumbnailUrlCache_[entry.fullPath] = {
1759 iconType: iconType,
1760 url: url,
1761 transform: transform
1762 };
1733 img.onload = function() { 1763 img.onload = function() {
1734 self.centerImage_(img.style, img.width, img.height, fill); 1764 self.centerImage_(img.style, img.width, img.height, fill);
1735 if (opt_imageLoadCallback) 1765 if (opt_imageLoadCallback)
1736 opt_imageLoadCallback(img, transform); 1766 opt_imageLoadCallback(img, transform);
1737 box.appendChild(img); 1767 box.appendChild(img);
1738 }; 1768 };
1739 img.src = url; 1769 img.src = url;
1740 self.applyImageTransformation_(box, transform); 1770 self.applyImageTransformation_(box, transform);
1741 }); 1771 }
1772
1773 var cached = this.thumbnailUrlCache_[entry.fullPath];
1774 if (cached)
1775 onThumbnailURL(cached.iconType, cached.url, cached.transform);
1776 else
1777 this.getThumbnailURL(entry, onThumbnailURL);
1778
1742 return box; 1779 return box;
1743 }; 1780 };
1744 1781
1745 FileManager.prototype.decorateThumbnail_ = function(li, entry) { 1782 FileManager.prototype.decorateThumbnail_ = function(li, entry) {
1746 li.className = 'thumbnail-item'; 1783 li.className = 'thumbnail-item';
1747 1784
1748 if (this.showCheckboxes_) 1785 if (this.showCheckboxes_)
1749 li.appendChild(this.renderCheckbox_(entry)); 1786 li.appendChild(this.renderCheckbox_(entry));
1750 1787
1751 li.appendChild(this.renderThumbnailBox_(entry, false)); 1788 li.appendChild(this.renderThumbnailBox_(entry, false));
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
2069 */ 2106 */
2070 FileManager.prototype.summarizeSelection_ = function() { 2107 FileManager.prototype.summarizeSelection_ = function() {
2071 var selection = this.selection = { 2108 var selection = this.selection = {
2072 entries: [], 2109 entries: [],
2073 urls: [], 2110 urls: [],
2074 totalCount: 0, 2111 totalCount: 0,
2075 fileCount: 0, 2112 fileCount: 0,
2076 directoryCount: 0, 2113 directoryCount: 0,
2077 bytes: 0, 2114 bytes: 0,
2078 iconType: null, 2115 iconType: null,
2079 indexes: this.currentList_.selectionModel.selectedIndexes 2116 indexes: this.currentList_.selectionModel.selectedIndexes,
2117 files: [],
2118 dragNodes: []
2080 }; 2119 };
2081 2120
2082 if (!selection.indexes.length) { 2121 if (!selection.indexes.length) {
2083 this.updateCommonActionButtons_(); 2122 this.updateCommonActionButtons_();
2084 this.updatePreviewPanelVisibility_(); 2123 this.updatePreviewPanelVisibility_();
2085 cr.dispatchSimpleEvent(this, 'selection-summarized'); 2124 cr.dispatchSimpleEvent(this, 'selection-summarized');
2086 return; 2125 return;
2087 } 2126 }
2088 2127
2089 this.previewSummary_.textContent = str('COMPUTING_SELECTION'); 2128 this.previewSummary_.textContent = str('COMPUTING_SELECTION');
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 var thumbnail = this.renderThumbnailBox_(entry, true, imageLoadCalback); 2161 var thumbnail = this.renderThumbnailBox_(entry, true, imageLoadCalback);
2123 box.appendChild(thumbnail); 2162 box.appendChild(thumbnail);
2124 box.style.zIndex = MAX_PREVIEW_THUMBAIL_COUNT + 1 - i; 2163 box.style.zIndex = MAX_PREVIEW_THUMBAIL_COUNT + 1 - i;
2125 box.addEventListener('click', 2164 box.addEventListener('click',
2126 this.dispatchDefaultTask_.bind(this, selection)); 2165 this.dispatchDefaultTask_.bind(this, selection));
2127 2166
2128 this.previewThumbnails_.appendChild(box); 2167 this.previewThumbnails_.appendChild(box);
2129 thumbnailCount++; 2168 thumbnailCount++;
2130 } 2169 }
2131 2170
2171 // Items to drag are created in advance. Images must be loaded
2172 // at the time the 'dragstart' event comes. Otherwise draggable
2173 // image will be rendered without IMG tags.
2174 if (selection.dragNodes.length < MAX_PREVIEW_THUMBAIL_COUNT)
2175 selection.dragNodes.push(new GridItem(this, entry));
2176
2132 selection.totalCount++; 2177 selection.totalCount++;
2133 2178
2134 if (entry.isFile) { 2179 if (entry.isFile) {
2135 selection.fileCount += 1; 2180 selection.fileCount += 1;
2136 if (!('cachedSize_' in entry)) { 2181 if (!('cachedSize_' in entry)) {
2137 // Any file that hasn't been rendered may be missing its cachedSize_ 2182 // Any file that hasn't been rendered may be missing its cachedSize_
2138 // property. For example, visit a large file list, and press ctrl-a 2183 // property. For example, visit a large file list, and press ctrl-a
2139 // to select all. In this case, we need to asynchronously get the 2184 // to select all. In this case, we need to asynchronously get the
2140 // sizes for these files before telling the world the selection has 2185 // sizes for these files before telling the world the selection has
2141 // been summarized. See the 'computeNextFile' logic below. 2186 // been summarized. See the 'computeNextFile' logic below.
2142 pendingFiles.push(entry); 2187 pendingFiles.push(entry);
2143 continue; 2188 continue;
2144 } else { 2189 } else {
2145 selection.bytes += entry.cachedSize_; 2190 selection.bytes += entry.cachedSize_;
2146 } 2191 }
2192 // File object must be prepeared in advance for clipboard operations
2193 // (copy, paste and drag). Clipboard object closes for write after
2194 // returning control from that handlers so they may not have
2195 // asynchronous operations.
2196 // TODO(serya): Put file objects into the clipboard.
2197 if (!this.isOnGData()) {
2198 entry.file(function(f) {
2199 selection.files.push(f);
2200 });
2201 }
2147 } else { 2202 } else {
2148 selection.directoryCount += 1; 2203 selection.directoryCount += 1;
2149 } 2204 }
2150 } 2205 }
2151 2206
2152 // Now this.selection is complete. Update buttons. 2207 // Now this.selection is complete. Update buttons.
2153 this.updateCommonActionButtons_(); 2208 this.updateCommonActionButtons_();
2154 this.updatePreviewPanelVisibility_(); 2209 this.updatePreviewPanelVisibility_();
2155 2210
2156 var self = this; 2211 var self = this;
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
3054 var listItem = self.currentList_.getListItemByIndex(selectedIndex); 3109 var listItem = self.currentList_.getListItemByIndex(selectedIndex);
3055 if (listItem) 3110 if (listItem)
3056 listItem.classList.remove('blink'); 3111 listItem.classList.remove('blink');
3057 } 3112 }
3058 }, 100); 3113 }, 100);
3059 }; 3114 };
3060 3115
3061 /** 3116 /**
3062 * Write the current selection to system clipboard. 3117 * Write the current selection to system clipboard.
3063 * 3118 *
3064 * @param {Event} event Cut or Copy event. 3119 * @param {Clipboard} clipboard Clipboard from the event.
3065 * @param {boolean} isCut True if the current command is cut. 3120 * @param {boolean} isCut True if the current command is cut.
3066 */ 3121 */
3067 FileManager.prototype.cutOrCopyToClipboard_ = function(event, isCut) { 3122 FileManager.prototype.cutOrCopyToClipboard_ = function(clipboard, isCut) {
3068 event.preventDefault(); 3123 var directories = '';
3124 var files = '';
3125 for(var i = 0, entry; i < this.selection.entries.length; i++) {
3126 entry = this.selection.entries[i];
3127 if (entry.isDirectory)
3128 directories += entry.fullPath + '\n';
3129 else
3130 files += entry.fullPath + '\n';
3131 }
3069 3132
3070 var directories = ''; 3133 clipboard.setData('fs/isCut', isCut.toString());
3071 var files = ''; 3134 clipboard.setData('fs/sourceDir',
3072 for(var i = 0, entry; i < this.selection.entries.length; i++) {
3073 entry = this.selection.entries[i];
3074 if (entry.isDirectory)
3075 directories += entry.fullPath + '\n';
3076 else
3077 files += entry.fullPath + '\n';
3078 }
3079
3080 event.clipboardData.setData('fs/isCut', isCut.toString());
3081 event.clipboardData.setData('fs/isOnGData',
3082 this.isOnGData().toString());
3083 event.clipboardData.setData('fs/sourceDir',
3084 this.directoryModel_.currentEntry.fullPath); 3135 this.directoryModel_.currentEntry.fullPath);
3085 event.clipboardData.setData('fs/directories', directories); 3136 clipboard.setData('fs/sourceOnGData', this.isOnGData());
3086 event.clipboardData.setData('fs/files', files); 3137 clipboard.setData('fs/directories', directories);
3138 clipboard.setData('fs/files', files);
3087 } 3139 }
3088 3140
3089 FileManager.prototype.copySelectionToClipboard_ = function(event) { 3141 FileManager.prototype.onCopy_ = function(event) {
3090 if (!this.selection || this.selection.totalCount == 0) 3142 if (!this.selection || this.selection.totalCount == 0)
3091 return; 3143 return;
3092 3144
3093 this.cutOrCopyToClipboard_(event, false); 3145 event.preventDefault();
3146 this.cutOrCopyToClipboard_(event.clipboardData, false);
3094 3147
3095 this.blinkSelection(); 3148 this.blinkSelection();
3096 }; 3149 };
3097 3150
3098 FileManager.prototype.cutSelectionToClipboard_ = function(event) { 3151 FileManager.prototype.onCut_ = function(event) {
3099 if (!this.selection || this.selection.totalCount == 0 || 3152 if (!this.selection || this.selection.totalCount == 0 ||
3100 this.commands_['cut'].disabled) 3153 this.commands_['cut'].disabled)
3101 return; 3154 return;
3102 3155
3103 this.cutOrCopyToClipboard_(event, true); 3156 event.preventDefault();
3157 this.cutOrCopyToClipboard_(event.clipboardData, true);
3104 3158
3105 this.blinkSelection(); 3159 this.blinkSelection();
3106 }; 3160 };
3107 3161
3162 FileManager.prototype.onPaste_ = function(event) {
3163 event.preventDefault();
3164 this.pasteFromClipboard_(event.clipboardData);
3165 };
3166
3108 /** 3167 /**
3109 * Queue up a file copy operation based on the current system clipboard. 3168 * Queue up a file copy operation based on the current system clipboard.
3110 */ 3169 */
3111 FileManager.prototype.pasteFromClipboard_ = function(event) { 3170 FileManager.prototype.pasteFromClipboard_ = function(clipboard) {
3112 event.preventDefault();
3113
3114 if (!event.clipboardData.getData('fs/isCut')) 3171 if (!event.clipboardData.getData('fs/isCut'))
3115 return; 3172 return;
3116 3173
3117 var clipboard = { 3174 var operationInfo = {
3118 isCut: event.clipboardData.getData('fs/isCut'), 3175 isCut: clipboard.getData('fs/isCut'),
3119 isOnGData: event.clipboardData.getData('fs/isOnGData'), 3176 sourceDir: clipboard.getData('fs/sourceDir'),
3120 sourceDir: event.clipboardData.getData('fs/sourceDir'), 3177 sourceOnGData: clipboard.getData('fs/sourceOnGData'),
3121 directories: event.clipboardData.getData('fs/directories'), 3178 directories: clipboard.getData('fs/directories'),
3122 files: event.clipboardData.getData('fs/files') 3179 files: clipboard.getData('fs/files')
3123 }; 3180 };
3124 3181
3125 this.copyManager_.paste(clipboard, 3182 // If both source and target are on GData, FileCopyManager uses
3183 // FileEntry.copyTo() / FileEntry.moveTo() to copy / move files.
3184 var sourceAndTargetOnGData = operationInfo.sourceOnGData &&
3185 this.isOnGData();
3186 this.copyManager_.paste(operationInfo,
3126 this.directoryModel_.currentEntry, 3187 this.directoryModel_.currentEntry,
3127 this.isOnGData(), 3188 this.isOnGData(),
3128 this.filesystem_.root); 3189 this.filesystem_.root);
3129 3190
3130 var clearClipboard = function (event) { 3191 var clearClipboard = function (event) {
3131 event.preventDefault(); 3192 event.preventDefault();
3132 event.clipboardData.setData('fs/clear', ''); 3193 event.clipboardData.setData('fs/clear', '');
3133 } 3194 }
3134 3195
3135 // On cut, we clear the clipboard after the file is pasted/moved so we don't 3196 // On cut, we clear the clipboard after the file is pasted/moved so we don't
3136 // try to move/delete the original file again. 3197 // try to move/delete the original file again.
3137 if (clipboard.isCut == 'true') { 3198 if (operationInfo.isCut == 'true') {
3138 this.document_.removeEventListener('cut', this.cutFromClipboardBind_); 3199 this.document_.removeEventListener('cut', this.onCutBound_);
3139 this.document_.addEventListener('cut', clearClipboard); 3200 this.document_.addEventListener('cut', clearClipboard);
3140 this.document_.execCommand('cut'); 3201 this.document_.execCommand('cut');
3141 this.document_.removeEventListener('cut', clearClipboard); 3202 this.document_.removeEventListener('cut', clearClipboard);
3142 this.document_.addEventListener('cut', this.cutFromClipboardBind_); 3203 this.document_.addEventListener('cut', this.onCutBound_);
3143 } 3204 }
3144 }; 3205 };
3145 3206
3146 /** 3207 /**
3147 * Update the selection summary UI when the selection summarization completes. 3208 * Update the selection summary UI when the selection summarization completes.
3148 */ 3209 */
3149 FileManager.prototype.onSelectionSummarized_ = function() { 3210 FileManager.prototype.onSelectionSummarized_ = function() {
3150 var selection = this.selection; 3211 var selection = this.selection;
3151 var bytes = util.bytesToSi(selection.bytes); 3212 var bytes = util.bytesToSi(selection.bytes);
3152 var text = ''; 3213 var text = '';
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
3258 if (this.selection && 3319 if (this.selection &&
3259 this.selection.totalCount == 1 && 3320 this.selection.totalCount == 1 &&
3260 this.selection.entries[0].isFile && 3321 this.selection.entries[0].isFile &&
3261 this.filenameInput_.value != this.selection.entries[0].name) { 3322 this.filenameInput_.value != this.selection.entries[0].name) {
3262 this.filenameInput_.value = this.selection.entries[0].name; 3323 this.filenameInput_.value = this.selection.entries[0].name;
3263 } 3324 }
3264 } 3325 }
3265 3326
3266 this.updateOkButton_(); 3327 this.updateOkButton_();
3267 3328
3268 var self = this; 3329 var newThumbnailUrlCache = {};
3269 setTimeout(function() { self.onSelectionChangeComplete_(event) }, 0); 3330 if (this.selection) {
3331 const entries = this.selection.entries;
3332 for (var i = 0; i < entries.length; i++) {
3333 var path = entries[i].fullPath;
3334 if (path in this.thumbnailUrlCache_)
3335 newThumbnailUrlCache[path] = this.thumbnailUrlCache_[path];
3336 }
3337 }
3338 this.thumbnailUrlCache_ = newThumbnailUrlCache;
3339
3340 setTimeout(this.onSelectionChangeComplete_.bind(this, event), 0);
3270 }; 3341 };
3271 3342
3272 /** 3343 /**
3273 * Handle selection change related tasks that won't run properly during 3344 * Handle selection change related tasks that won't run properly during
3274 * the actual selection change event. 3345 * the actual selection change event.
3275 */ 3346 */
3276 FileManager.prototype.onSelectionChangeComplete_ = function(event) { 3347 FileManager.prototype.onSelectionChangeComplete_ = function(event) {
3277 // Inform tests it's OK to click buttons now. 3348 // Inform tests it's OK to click buttons now.
3278 chrome.test.sendMessage('selection-change-complete'); 3349 chrome.test.sendMessage('selection-change-complete');
3279 3350
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3512 if (metadata && dm.rootEntry == rootEntry) 3583 if (metadata && dm.rootEntry == rootEntry)
3513 dm.readonly = metadata.isReadOnly; 3584 dm.readonly = metadata.isReadOnly;
3514 }); 3585 });
3515 }; 3586 };
3516 3587
3517 FileManager.prototype.findListItemForEvent_ = function(event) { 3588 FileManager.prototype.findListItemForEvent_ = function(event) {
3518 return this.findListItemForNode_(event.srcElement); 3589 return this.findListItemForNode_(event.srcElement);
3519 }; 3590 };
3520 3591
3521 FileManager.prototype.findListItemForNode_ = function(node) { 3592 FileManager.prototype.findListItemForNode_ = function(node) {
3522 var list = this.currentList_; 3593 var item = this.currentList_.getListItemAncestor(node);
3523 // Assume list items are direct children of the list. 3594 // TODO(serya): list should check that.
3524 if (node == list) 3595 return item && this.currentList_.isItem(item) ? item : null;
3525 return null;
3526 while (node) {
3527 var parent = node.parentNode;
3528 if (parent == list && node instanceof cr.ui.ListItem)
3529 return node;
3530 node = parent;
3531 }
3532 return null;
3533 }; 3596 };
3534 3597
3535 FileManager.prototype.onGridOrTableMouseDown_ = function(event) { 3598 FileManager.prototype.onGridOrTableMouseDown_ = function(event) {
3536 var item = this.findListItemForEvent_(event); 3599 var item = this.findListItemForEvent_(event);
3537 if (!item) 3600 if (!item)
3538 return; 3601 return;
3539 3602
3540 if (this.allowRenameClick_(event, item)) { 3603 if (this.allowRenameClick_(event, item)) {
3541 event.preventDefault(); 3604 event.preventDefault();
3542 this.directoryModel_.fileListSelection.selectedIndex = item.listIndex; 3605 this.directoryModel_.fileListSelection.selectedIndex = item.listIndex;
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
4279 }); 4342 });
4280 }, onError); 4343 }, onError);
4281 4344
4282 function onError(err) { 4345 function onError(err) {
4283 console.log('Error while checking free space: ' + err); 4346 console.log('Error while checking free space: ' + err);
4284 setTimeout(doCheck, 1000 * 60); 4347 setTimeout(doCheck, 1000 * 60);
4285 } 4348 }
4286 } 4349 }
4287 } 4350 }
4288 })(); 4351 })();
OLDNEW
« no previous file with comments | « chrome/browser/resources/file_manager/css/file_manager.css ('k') | chrome/browser/resources/file_manager/main.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698