Chromium Code Reviews| 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())) |
|
hirono
2014/01/17 03:11:29
!== -1 is needed?
mtomasz
2014/01/17 04:16:42
Oops. Done.
| |
| 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 |