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 'use strict'; | 5 'use strict'; |
6 | 6 |
7 // If directory files changes too often, don't rescan directory more than once | 7 // If directory files changes too often, don't rescan directory more than once |
8 // per specified interval | 8 // per specified interval |
9 var SIMULTANEOUS_RESCAN_INTERVAL = 1000; | 9 var SIMULTANEOUS_RESCAN_INTERVAL = 1000; |
10 // Used for operations that require almost instant rescan. | 10 // Used for operations that require almost instant rescan. |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 }; | 186 }; |
187 | 187 |
188 /** | 188 /** |
189 * @return {DirectoryEntry} Current directory. | 189 * @return {DirectoryEntry} Current directory. |
190 */ | 190 */ |
191 DirectoryModel.prototype.getCurrentDirEntry = function() { | 191 DirectoryModel.prototype.getCurrentDirEntry = function() { |
192 return this.currentDirContents_.getDirectoryEntry(); | 192 return this.currentDirContents_.getDirectoryEntry(); |
193 }; | 193 }; |
194 | 194 |
195 /** | 195 /** |
196 * @return {Array.<string>} File paths of selected files. | 196 * @return {Array.<Entry>} Array of selected entries.. |
197 * @private | 197 * @private |
198 */ | 198 */ |
199 DirectoryModel.prototype.getSelectedPaths_ = function() { | 199 DirectoryModel.prototype.getSelectedEntries_ = function() { |
200 var indexes = this.fileListSelection_.selectedIndexes; | 200 var indexes = this.fileListSelection_.selectedIndexes; |
201 var fileList = this.getFileList(); | 201 var fileList = this.getFileList(); |
202 if (fileList) { | 202 if (fileList) { |
203 return indexes.map(function(i) { | 203 return indexes.map(function(i) { |
204 return fileList.item(i).fullPath; | 204 return fileList.item(i); |
205 }); | 205 }); |
206 } | 206 } |
207 return []; | 207 return []; |
208 }; | 208 }; |
209 | 209 |
210 /** | 210 /** |
211 * @param {Array.<string>} value List of file paths of selected files. | 211 * @param {Array.<Entry>} value List of selected entries. |
212 * @private | 212 * @private |
213 */ | 213 */ |
214 DirectoryModel.prototype.setSelectedPaths_ = function(value) { | 214 DirectoryModel.prototype.setSelectedEntries_ = function(value) { |
215 var indexes = []; | 215 var indexes = []; |
216 var fileList = this.getFileList(); | 216 var fileList = this.getFileList(); |
217 | 217 var urls = util.entriesToURLs(value); |
218 var safeKey = function(key) { | |
219 // The transformation must: | |
220 // 1. Never generate a reserved name ('__proto__') | |
221 // 2. Keep different keys different. | |
222 return '#' + key; | |
223 }; | |
224 | |
225 var hash = {}; | |
226 | |
227 for (var i = 0; i < value.length; i++) | |
228 hash[safeKey(value[i])] = 1; | |
229 | 218 |
230 for (var i = 0; i < fileList.length; i++) { | 219 for (var i = 0; i < fileList.length; i++) { |
231 if (hash.hasOwnProperty(safeKey(fileList.item(i).fullPath))) | 220 if (urls.indexOf(fileList.item(i).toURL()) !== -1) |
232 indexes.push(i); | 221 indexes.push(i); |
233 } | 222 } |
234 this.fileListSelection_.selectedIndexes = indexes; | 223 this.fileListSelection_.selectedIndexes = indexes; |
235 }; | 224 }; |
236 | 225 |
237 /** | 226 /** |
238 * @return {string} Lead item file path. | 227 * @return {Entry} Lead entry. |
239 * @private | 228 * @private |
240 */ | 229 */ |
241 DirectoryModel.prototype.getLeadPath_ = function() { | 230 DirectoryModel.prototype.getLeadEntry_ = function() { |
242 var index = this.fileListSelection_.leadIndex; | 231 var index = this.fileListSelection_.leadIndex; |
243 return index >= 0 && this.getFileList().item(index).fullPath; | 232 return index >= 0 && this.getFileList().item(index); |
244 }; | 233 }; |
245 | 234 |
246 /** | 235 /** |
247 * @param {string} value The name of new lead index. | 236 * @param {Entry} value The new lead entry. |
248 * @private | 237 * @private |
249 */ | 238 */ |
250 DirectoryModel.prototype.setLeadPath_ = function(value) { | 239 DirectoryModel.prototype.setLeadEntry_ = function(value) { |
251 var fileList = this.getFileList(); | 240 var fileList = this.getFileList(); |
252 for (var i = 0; i < fileList.length; i++) { | 241 for (var i = 0; i < fileList.length; i++) { |
253 if (fileList.item(i).fullPath === value) { | 242 if (util.isSameEntry(fileList.item(i), value)) { |
254 this.fileListSelection_.leadIndex = i; | 243 this.fileListSelection_.leadIndex = i; |
255 return; | 244 return; |
256 } | 245 } |
257 } | 246 } |
258 }; | 247 }; |
259 | 248 |
260 /** | 249 /** |
261 * Schedule rescan with short delay. | 250 * Schedule rescan with short delay. |
262 */ | 251 */ |
263 DirectoryModel.prototype.rescanSoon = function() { | 252 DirectoryModel.prototype.rescanSoon = function() { |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 dirContents.scan(); | 441 dirContents.scan(); |
453 }; | 442 }; |
454 | 443 |
455 /** | 444 /** |
456 * @param {DirectoryContents} dirContents DirectoryContents instance. | 445 * @param {DirectoryContents} dirContents DirectoryContents instance. |
457 * @private | 446 * @private |
458 */ | 447 */ |
459 DirectoryModel.prototype.replaceDirectoryContents_ = function(dirContents) { | 448 DirectoryModel.prototype.replaceDirectoryContents_ = function(dirContents) { |
460 cr.dispatchSimpleEvent(this, 'begin-update-files'); | 449 cr.dispatchSimpleEvent(this, 'begin-update-files'); |
461 this.updateSelectionAndPublishEvent_(this.fileListSelection_, function() { | 450 this.updateSelectionAndPublishEvent_(this.fileListSelection_, function() { |
462 var selectedPaths = this.getSelectedPaths_(); | 451 var selectedEntries = this.getSelectedEntries_(); |
463 var selectedIndices = this.fileListSelection_.selectedIndexes; | 452 var selectedIndices = this.fileListSelection_.selectedIndexes; |
464 | 453 |
465 // Restore leadIndex in case leadName no longer exists. | 454 // Restore leadIndex in case leadName no longer exists. |
466 var leadIndex = this.fileListSelection_.leadIndex; | 455 var leadIndex = this.fileListSelection_.leadIndex; |
467 var leadPath = this.getLeadPath_(); | 456 var leadEntry = this.getLeadEntry_(); |
468 | 457 |
469 this.currentDirContents_ = dirContents; | 458 this.currentDirContents_ = dirContents; |
470 dirContents.replaceContextFileList(); | 459 dirContents.replaceContextFileList(); |
471 | 460 |
472 this.setSelectedPaths_(selectedPaths); | 461 this.setSelectedEntries_(selectedEntries); |
473 this.fileListSelection_.leadIndex = leadIndex; | 462 this.fileListSelection_.leadIndex = leadIndex; |
474 this.setLeadPath_(leadPath); | 463 this.setLeadEntry_(leadEntry); |
475 | 464 |
476 // If nothing is selected after update, then select file next to the | 465 // If nothing is selected after update, then select file next to the |
477 // latest selection | 466 // latest selection |
478 var forceChangeEvent = false; | 467 var forceChangeEvent = false; |
479 if (this.fileListSelection_.selectedIndexes.length == 0 && | 468 if (this.fileListSelection_.selectedIndexes.length == 0 && |
480 selectedIndices.length != 0) { | 469 selectedIndices.length != 0) { |
481 var maxIdx = Math.max.apply(null, selectedIndices); | 470 var maxIdx = Math.max.apply(null, selectedIndices); |
482 this.selectIndex(Math.min(maxIdx - selectedIndices.length + 2, | 471 this.selectIndex(Math.min(maxIdx - selectedIndices.length + 2, |
483 this.getFileList().length) - 1); | 472 this.getFileList().length) - 1); |
484 forceChangeEvent = true; | 473 forceChangeEvent = true; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 if (entry.isFile) { | 701 if (entry.isFile) { |
713 onError(util.createFileError(FileError.TYPE_MISMATCH_ERR)); | 702 onError(util.createFileError(FileError.TYPE_MISMATCH_ERR)); |
714 return; | 703 return; |
715 } | 704 } |
716 successCallback(entry); | 705 successCallback(entry); |
717 }, | 706 }, |
718 onError); | 707 onError); |
719 }; | 708 }; |
720 | 709 |
721 /** | 710 /** |
722 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. | 711 * @param {DirectoryEntry} dirEntry The entry of the new directory. |
723 * @param {function()=} opt_callback Executed if the directory loads | 712 * @param {function()=} opt_callback Executed if the directory loads |
724 * successfully. | 713 * successfully. |
725 * @private | 714 * @private |
726 */ | 715 */ |
727 DirectoryModel.prototype.changeDirectoryEntrySilent_ = function(dirEntry, | 716 DirectoryModel.prototype.changeDirectoryEntrySilent_ = function(dirEntry, |
728 opt_callback) { | 717 opt_callback) { |
729 var onScanComplete = function() { | 718 var onScanComplete = function() { |
730 if (opt_callback) | 719 if (opt_callback) |
731 opt_callback(); | 720 opt_callback(); |
732 // For tests that open the dialog to empty directories, everything | 721 // For tests that open the dialog to empty directories, everything |
733 // is loaded at this point. | 722 // is loaded at this point. |
734 chrome.test.sendMessage('directory-change-complete'); | 723 chrome.test.sendMessage('directory-change-complete'); |
735 }; | 724 }; |
736 this.clearAndScan_( | 725 this.clearAndScan_( |
737 DirectoryContents.createForDirectory(this.currentFileListContext_, | 726 DirectoryContents.createForDirectory(this.currentFileListContext_, |
738 dirEntry), | 727 dirEntry), |
739 onScanComplete.bind(this)); | 728 onScanComplete.bind(this)); |
740 }; | 729 }; |
741 | 730 |
742 /** | 731 /** |
743 * Change the current directory to the directory represented by a | 732 * Change the current directory to the directory represented by a |
744 * DirectoryEntry. | 733 * DirectoryEntry. |
745 * | 734 * |
746 * Dispatches the 'directory-changed' event when the directory is successfully | 735 * Dispatches the 'directory-changed' event when the directory is successfully |
747 * changed. | 736 * changed. |
748 * | 737 * |
749 * @param {DirectoryEntry} dirEntry The absolute path to the new directory. | 738 * @param {DirectoryEntry} dirEntry The entry of the new directory. |
750 * @param {function()=} opt_callback Executed if the directory loads | 739 * @param {function()=} opt_callback Executed if the directory loads |
751 * successfully. | 740 * successfully. |
752 */ | 741 */ |
753 DirectoryModel.prototype.changeDirectoryEntry = function( | 742 DirectoryModel.prototype.changeDirectoryEntry = function( |
754 dirEntry, opt_callback) { | 743 dirEntry, opt_callback) { |
755 this.fileWatcher_.changeWatchedDirectory(dirEntry, function(sequence) { | 744 this.fileWatcher_.changeWatchedDirectory(dirEntry, function(sequence) { |
756 if (this.changeDirectorySequence_ !== sequence) | 745 if (this.changeDirectorySequence_ !== sequence) |
757 return; | 746 return; |
758 var previous = this.currentDirContents_.getDirectoryEntry(); | 747 var previous = this.currentDirContents_.getDirectoryEntry(); |
759 this.clearSearch_(); | 748 this.clearSearch_(); |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 if (this.onSearchCompleted_) { | 1043 if (this.onSearchCompleted_) { |
1055 this.removeEventListener('scan-completed', this.onSearchCompleted_); | 1044 this.removeEventListener('scan-completed', this.onSearchCompleted_); |
1056 this.onSearchCompleted_ = null; | 1045 this.onSearchCompleted_ = null; |
1057 } | 1046 } |
1058 | 1047 |
1059 if (this.onClearSearch_) { | 1048 if (this.onClearSearch_) { |
1060 this.onClearSearch_(); | 1049 this.onClearSearch_(); |
1061 this.onClearSearch_ = null; | 1050 this.onClearSearch_ = null; |
1062 } | 1051 } |
1063 }; | 1052 }; |
OLD | NEW |