OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 const EMPTY_IMAGE_URI = 'data:image/gif;base64,' | 7 const EMPTY_IMAGE_URI = 'data:image/gif;base64,' |
8 + 'R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw%3D%3D'; | 8 + 'R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw%3D%3D'; |
9 | 9 |
10 var g_slideshow_data = null; | 10 var g_slideshow_data = null; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 metrics.recordEnum('Create', this.dialogType_, | 58 metrics.recordEnum('Create', this.dialogType_, |
59 [FileManager.DialogType.SELECT_FOLDER, | 59 [FileManager.DialogType.SELECT_FOLDER, |
60 FileManager.DialogType.SELECT_SAVEAS_FILE, | 60 FileManager.DialogType.SELECT_SAVEAS_FILE, |
61 FileManager.DialogType.SELECT_OPEN_FILE, | 61 FileManager.DialogType.SELECT_OPEN_FILE, |
62 FileManager.DialogType.SELECT_OPEN_MULTI_FILE, | 62 FileManager.DialogType.SELECT_OPEN_MULTI_FILE, |
63 FileManager.DialogType.FULL_PAGE]); | 63 FileManager.DialogType.FULL_PAGE]); |
64 | 64 |
65 // TODO(dgozman): This will be changed to LocaleInfo. | 65 // TODO(dgozman): This will be changed to LocaleInfo. |
66 this.locale_ = new v8Locale(navigator.language); | 66 this.locale_ = new v8Locale(navigator.language); |
67 | 67 |
68 this.resolveRoots_(); | 68 this.requestFileSystem_(); |
69 this.initDom_(); | 69 this.initDom_(); |
70 this.initDialogType_(); | 70 this.initDialogType_(); |
71 this.dialogDom_.style.opacity = '1'; | 71 this.dialogDom_.style.opacity = '1'; |
72 } | 72 } |
73 | 73 |
74 FileManager.prototype = { | 74 FileManager.prototype = { |
75 __proto__: cr.EventTarget.prototype | 75 __proto__: cr.EventTarget.prototype |
76 }; | 76 }; |
77 | 77 |
78 // Anonymous "namespace". | 78 // Anonymous "namespace". |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
460 chrome.fileBrowserPrivate.getStrings(function(strings) { | 460 chrome.fileBrowserPrivate.getStrings(function(strings) { |
461 localStrings = new LocalStrings(strings); | 461 localStrings = new LocalStrings(strings); |
462 if (callback) | 462 if (callback) |
463 callback(); | 463 callback(); |
464 }); | 464 }); |
465 }; | 465 }; |
466 | 466 |
467 // Instance methods. | 467 // Instance methods. |
468 | 468 |
469 /** | 469 /** |
470 * Request file system and get root entries asynchronously. Invokes init_ | 470 * Request local file system, resolve roots and init_ after that. |
471 * when have finished. | |
472 */ | 471 */ |
473 FileManager.prototype.resolveRoots_ = function(callback) { | 472 FileManager.prototype.requestFileSystem_ = function() { |
474 var rootPaths = ['Downloads', 'removable', 'archive']; | 473 util.installFileErrorToString(); |
474 metrics.startInterval('RequestLocalFileSystem'); | |
475 | 475 |
476 metrics.startInterval('RequestLocalFileSystem'); | |
477 var self = this; | 476 var self = this; |
478 | 477 |
479 // The list of active mount points to distinct them from other directories. | 478 // The list of active mount points to distinct them from other directories. |
480 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { | 479 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { |
481 self.mountPoints_ = mountPoints; | 480 self.mountPoints_ = mountPoints; |
482 onDone(); | 481 onDone(); |
483 }); | 482 }); |
484 | 483 |
485 function onDone() { | 484 function onDone() { |
486 if (self.mountPoints_ && self.rootEntries_) | 485 if (self.mountPoints_ && self.rootEntries_) |
487 self.init_(); | 486 self.init_(); |
488 } | 487 } |
489 | 488 |
490 chrome.fileBrowserPrivate.requestLocalFileSystem(function(filesystem) { | 489 chrome.fileBrowserPrivate.requestLocalFileSystem(function(filesystem) { |
491 self.filesystem_ = filesystem; | |
492 util.installFileErrorToString(); | |
493 | |
494 metrics.recordTime('RequestLocalFileSystem'); | 490 metrics.recordTime('RequestLocalFileSystem'); |
495 console.log('Found filesystem: ' + filesystem.name, filesystem); | 491 console.log('Found filesystem: ' + filesystem.name, filesystem); |
496 | 492 |
497 var rootEntries = []; | 493 self.filesystem_ = filesystem; |
498 | 494 self.resolveRoots_(function(rootEntries) { |
499 function onAllRootsFound() { | |
500 self.rootEntries_ = rootEntries; | 495 self.rootEntries_ = rootEntries; |
501 onDone(); | 496 onDone(); |
502 } | 497 }); |
503 | |
504 function onPathError(path, err) { | |
505 console.error('Error locating root path: ' + path + ': ' + err); | |
506 } | |
507 | |
508 function onEntryFound(entry) { | |
509 if (entry) { | |
510 rootEntries.push(entry); | |
511 } else { | |
512 onAllRootsFound(); | |
513 } | |
514 } | |
515 | |
516 metrics.startInterval('EnumerateRoots'); | |
517 if (filesystem.name.match(/^chrome-extension_\S+:external/i)) { | |
518 // We've been handed the local filesystem, whose root directory | |
519 // cannot be enumerated. | |
520 util.getDirectories(filesystem.root, {create: false}, rootPaths, | |
521 onEntryFound, onPathError); | |
522 } else { | |
523 util.forEachDirEntry(filesystem.root, onEntryFound); | |
524 } | |
525 }); | 498 }); |
526 }; | 499 }; |
527 | 500 |
528 /** | 501 /** |
502 * Get root entries asynchronously. Invokes callback | |
503 * when have finished. | |
504 */ | |
505 FileManager.prototype.resolveRoots_ = function(callback) { | |
506 var rootPaths = [DOWNLOADS_DIRECTORY, ARCHIVE_DIRECTORY, | |
507 REMOVABLE_DIRECTORY].map(function(s) { return s.substring(1); }); | |
508 var rootEntries = []; | |
509 | |
510 // The number of entries left to enumerate to get all roots. | |
511 // When equals to zero, we are done. | |
512 // Initially is 100 to prevent finishing before these entries themselves | |
513 // are found. | |
514 var entriesToEnumerate = 100; | |
515 | |
516 function onPathError(path, err) { | |
517 console.error('Error locating root path: ' + path + ': ' + err); | |
518 } | |
519 | |
520 function onRootFound(root) { | |
521 if (root) { | |
522 rootEntries.push(root); | |
523 } else { | |
524 entriesToEnumerate--; | |
525 if (entriesToEnumerate == 0) | |
526 callback(rootEntries); | |
527 } | |
528 } | |
529 | |
530 function onEntryFound(entry) { | |
531 if (entry) { | |
532 entriesToEnumerate++; | |
533 var path = entry.fullPath; | |
534 if (path == ARCHIVE_DIRECTORY || path == REMOVABLE_DIRECTORY) { | |
535 // All removable devices and mounted archives are considered | |
536 // roots, and are shown in the sidebar. | |
537 util.forEachDirEntry(entry, onRootFound); | |
538 } else { | |
539 onRootFound(entry); | |
540 onRootFound(null); | |
541 } | |
542 } else { | |
543 // No more entries to enumerate - remove fake 100. | |
544 entriesToEnumerate -= 100; | |
545 } | |
546 } | |
547 | |
548 metrics.startInterval('EnumerateRoots'); | |
549 if (this.filesystem_.name.match(/^chrome-extension_\S+:external/i)) { | |
550 // We've been handed the local filesystem, whose root directory | |
551 // cannot be enumerated. | |
552 util.getDirectories(this.filesystem_.root, {create: false}, rootPaths, | |
553 onEntryFound, onPathError); | |
554 } else { | |
555 util.forEachDirEntry(this.filesystem_.root, onEntryFound); | |
556 } | |
557 }; | |
558 | |
559 /** | |
529 * Continue initializing the file manager after resolving roots. | 560 * Continue initializing the file manager after resolving roots. |
530 */ | 561 */ |
531 FileManager.prototype.init_ = function() { | 562 FileManager.prototype.init_ = function() { |
532 metrics.startInterval('InitFileManager'); | 563 metrics.startInterval('InitFileManager'); |
564 this.initCommands_(); | |
533 | 565 |
534 // TODO(rginda): 6/22/11: Remove this test when createDateTimeFormat is | 566 // TODO(rginda): 6/22/11: Remove this test when createDateTimeFormat is |
535 // available in all chrome trunk builds. | 567 // available in all chrome trunk builds. |
536 if ('createDateTimeFormat' in this.locale_) { | 568 if ('createDateTimeFormat' in this.locale_) { |
537 this.shortDateFormatter_ = | 569 this.shortDateFormatter_ = |
538 this.locale_.createDateTimeFormat({'dateType': 'medium'}); | 570 this.locale_.createDateTimeFormat({'dateType': 'medium'}); |
539 } else { | 571 } else { |
540 this.shortDateFormatter_ = { | 572 this.shortDateFormatter_ = { |
541 format: function(d) { | 573 format: function(d) { |
542 return (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear(); | 574 return (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
580 window.addEventListener('unload', this.onUnload_.bind(this)); | 612 window.addEventListener('unload', this.onUnload_.bind(this)); |
581 | 613 |
582 this.addEventListener('directory-changed', | 614 this.addEventListener('directory-changed', |
583 this.onDirectoryChanged_.bind(this)); | 615 this.onDirectoryChanged_.bind(this)); |
584 this.addEventListener('selection-summarized', | 616 this.addEventListener('selection-summarized', |
585 this.onSelectionSummarized_.bind(this)); | 617 this.onSelectionSummarized_.bind(this)); |
586 | 618 |
587 // The list of archives requested to mount. We will show contents once | 619 // The list of archives requested to mount. We will show contents once |
588 // archive is mounted, but only for mounts from within this filebrowser tab. | 620 // archive is mounted, but only for mounts from within this filebrowser tab. |
589 this.mountRequests_ = []; | 621 this.mountRequests_ = []; |
622 this.unmountRequests_ = []; | |
590 chrome.fileBrowserPrivate.onMountCompleted.addListener( | 623 chrome.fileBrowserPrivate.onMountCompleted.addListener( |
591 this.onMountCompleted_.bind(this)); | 624 this.onMountCompleted_.bind(this)); |
592 | 625 |
593 chrome.fileBrowserPrivate.onFileChanged.addListener( | 626 chrome.fileBrowserPrivate.onFileChanged.addListener( |
594 this.onFileChanged_.bind(this)); | 627 this.onFileChanged_.bind(this)); |
595 | 628 |
596 var self = this; | 629 var self = this; |
597 | 630 |
598 // The list of callbacks to be invoked during the directory rescan after | 631 // The list of callbacks to be invoked during the directory rescan after |
599 // all paste tasks are complete. | 632 // all paste tasks are complete. |
600 this.pasteSuccessCallbacks_ = []; | 633 this.pasteSuccessCallbacks_ = []; |
601 | 634 |
602 this.initCommands_(); | |
603 | |
604 this.setupCurrentDirectory_(); | 635 this.setupCurrentDirectory_(); |
605 | 636 |
606 this.summarizeSelection_(); | 637 this.summarizeSelection_(); |
607 | 638 |
608 this.dataModel_.sort('cachedMtime_', 'desc'); | 639 this.dataModel_.sort('cachedMtime_', 'desc'); |
609 | 640 |
610 this.refocus(); | 641 this.refocus(); |
611 | 642 |
612 this.createMetadataProvider_(); | 643 this.createMetadataProvider_(); |
613 metrics.recordTime('InitFileManager'); | 644 metrics.recordTime('InitFileManager'); |
614 metrics.recordTime('TotalLoad'); | 645 metrics.recordTime('TotalLoad'); |
615 }; | 646 }; |
616 | 647 |
617 /** | 648 /** |
618 * One-time initialization of commands. | 649 * One-time initialization of commands. |
619 */ | 650 */ |
620 FileManager.prototype.initCommands_ = function() { | 651 FileManager.prototype.initCommands_ = function() { |
621 var commands = this.dialogDom_.querySelectorAll('command'); | 652 var commands = this.dialogDom_.querySelectorAll('command'); |
622 for (var i = 0; i < commands.length; i++) { | 653 for (var i = 0; i < commands.length; i++) { |
623 var command = commands[i]; | 654 var command = commands[i]; |
624 cr.ui.Command.decorate(command); | 655 cr.ui.Command.decorate(command); |
656 command.label = command.textContent; | |
657 command.textContent = ''; | |
625 this.commands_[command.id] = command; | 658 this.commands_[command.id] = command; |
626 } | 659 } |
627 | 660 |
628 this.fileContextMenu_ = this.dialogDom_.querySelector('.file-context-menu'); | 661 this.fileContextMenu_ = this.dialogDom_.querySelector('.file-context-menu'); |
629 cr.ui.Menu.decorate(this.fileContextMenu_); | 662 cr.ui.Menu.decorate(this.fileContextMenu_); |
630 | 663 |
631 this.document_.addEventListener('canExecute', | 664 this.document_.addEventListener('canExecute', |
632 this.onCanExecute_.bind(this)); | 665 this.onCanExecute_.bind(this)); |
633 this.document_.addEventListener('command', this.onCommand_.bind(this)); | 666 this.document_.addEventListener('command', this.onCommand_.bind(this)); |
634 } | 667 } |
(...skipping 17 matching lines...) Expand all Loading... | |
652 // Cache nodes we'll be manipulating. | 685 // Cache nodes we'll be manipulating. |
653 this.previewThumbnails_ = | 686 this.previewThumbnails_ = |
654 this.dialogDom_.querySelector('.preview-thumbnails'); | 687 this.dialogDom_.querySelector('.preview-thumbnails'); |
655 this.previewPanel_ = this.dialogDom_.querySelector('.preview-panel'); | 688 this.previewPanel_ = this.dialogDom_.querySelector('.preview-panel'); |
656 this.previewFilename_ = this.dialogDom_.querySelector('.preview-filename'); | 689 this.previewFilename_ = this.dialogDom_.querySelector('.preview-filename'); |
657 this.previewSummary_ = this.dialogDom_.querySelector('.preview-summary'); | 690 this.previewSummary_ = this.dialogDom_.querySelector('.preview-summary'); |
658 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input'); | 691 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input'); |
659 this.taskButtons_ = this.dialogDom_.querySelector('.task-buttons'); | 692 this.taskButtons_ = this.dialogDom_.querySelector('.task-buttons'); |
660 this.okButton_ = this.dialogDom_.querySelector('.ok'); | 693 this.okButton_ = this.dialogDom_.querySelector('.ok'); |
661 this.cancelButton_ = this.dialogDom_.querySelector('.cancel'); | 694 this.cancelButton_ = this.dialogDom_.querySelector('.cancel'); |
662 this.newFolderButton_ = this.dialogDom_.querySelector('.new-folder'); | |
663 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button'); | 695 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button'); |
664 | 696 |
665 this.downloadsWarning_ = | 697 this.downloadsWarning_ = |
666 this.dialogDom_.querySelector('.downloads-warning'); | 698 this.dialogDom_.querySelector('.downloads-warning'); |
667 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); | 699 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); |
668 this.downloadsWarning_.lastElementChild.innerHTML = html; | 700 this.downloadsWarning_.lastElementChild.innerHTML = html; |
669 var link = this.downloadsWarning_.querySelector('a'); | 701 var link = this.downloadsWarning_.querySelector('a'); |
670 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this)); | 702 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this)); |
671 | 703 |
672 this.document_.addEventListener('keydown', this.onKeyDown_.bind(this)); | 704 this.document_.addEventListener('keydown', this.onKeyDown_.bind(this)); |
(...skipping 10 matching lines...) Expand all Loading... | |
683 'keyup', this.onFilenameInputKeyUp_.bind(this)); | 715 'keyup', this.onFilenameInputKeyUp_.bind(this)); |
684 this.filenameInput_.addEventListener( | 716 this.filenameInput_.addEventListener( |
685 'focus', this.onFilenameInputFocus_.bind(this)); | 717 'focus', this.onFilenameInputFocus_.bind(this)); |
686 | 718 |
687 var listContainer = this.dialogDom_.querySelector('.list-container'); | 719 var listContainer = this.dialogDom_.querySelector('.list-container'); |
688 listContainer.addEventListener('keydown', this.onListKeyDown_.bind(this)); | 720 listContainer.addEventListener('keydown', this.onListKeyDown_.bind(this)); |
689 listContainer.addEventListener('keypress', this.onListKeyPress_.bind(this)); | 721 listContainer.addEventListener('keypress', this.onListKeyPress_.bind(this)); |
690 this.okButton_.addEventListener('click', this.onOk_.bind(this)); | 722 this.okButton_.addEventListener('click', this.onOk_.bind(this)); |
691 this.cancelButton_.addEventListener('click', this.onCancel_.bind(this)); | 723 this.cancelButton_.addEventListener('click', this.onCancel_.bind(this)); |
692 | 724 |
693 this.dialogDom_.querySelector('button.new-folder').addEventListener( | 725 this.dialogDom_.querySelector('div.open-sidebar').addEventListener( |
694 'click', this.onNewFolderButtonClick_.bind(this)); | 726 'click', this.onToggleSidebar_.bind(this)); |
727 this.dialogDom_.querySelector('div.close-sidebar').addEventListener( | |
728 'click', this.onToggleSidebar_.bind(this)); | |
729 this.dialogContainer_ = this.dialogDom_.querySelector('.dialog-container'); | |
695 | 730 |
696 this.dialogDom_.querySelector('button.detail-view').addEventListener( | 731 this.dialogDom_.querySelector('button.detail-view').addEventListener( |
697 'click', this.onDetailViewButtonClick_.bind(this)); | 732 'click', this.onDetailViewButtonClick_.bind(this)); |
698 this.dialogDom_.querySelector('button.thumbnail-view').addEventListener( | 733 this.dialogDom_.querySelector('button.thumbnail-view').addEventListener( |
699 'click', this.onThumbnailViewButtonClick_.bind(this)); | 734 'click', this.onThumbnailViewButtonClick_.bind(this)); |
700 | 735 |
701 this.dialogDom_.ownerDocument.defaultView.addEventListener( | 736 this.dialogDom_.ownerDocument.defaultView.addEventListener( |
702 'resize', this.onResize_.bind(this)); | 737 'resize', this.onResize_.bind(this)); |
703 | 738 |
704 var ary = this.dialogDom_.querySelectorAll('[visibleif]'); | 739 var ary = this.dialogDom_.querySelectorAll('[visibleif]'); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
737 if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE || | 772 if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE || |
738 this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FOLDER || | 773 this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FOLDER || |
739 this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { | 774 this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { |
740 this.selectionModelClass_ = cr.ui.ListSingleSelectionModel; | 775 this.selectionModelClass_ = cr.ui.ListSingleSelectionModel; |
741 } else { | 776 } else { |
742 this.selectionModelClass_ = cr.ui.ListSelectionModel; | 777 this.selectionModelClass_ = cr.ui.ListSelectionModel; |
743 } | 778 } |
744 | 779 |
745 this.initTable_(); | 780 this.initTable_(); |
746 this.initGrid_(); | 781 this.initGrid_(); |
782 this.initRootsList_(); | |
747 | 783 |
748 this.setListType(FileManager.ListType.DETAIL); | 784 this.setListType(FileManager.ListType.DETAIL); |
749 | 785 |
750 this.onResize_(); | 786 this.onResize_(); |
751 | 787 |
752 this.textSearchState_ = {text: '', date: new Date()}; | 788 this.textSearchState_ = {text: '', date: new Date()}; |
753 }; | 789 }; |
754 | 790 |
791 FileManager.prototype.initRootsList_ = function() { | |
792 this.rootsList_ = this.dialogDom_.querySelector('.roots-list'); | |
793 cr.ui.List.decorate(this.rootsList_); | |
794 | |
795 var self = this; | |
796 this.rootsList_.itemConstructor = function(entry) { | |
797 return self.renderRoot_(entry); | |
798 }; | |
799 | |
800 this.rootsList_.selectionModel = new cr.ui.ListSingleSelectionModel(); | |
801 this.rootsList_.selectionModel.addEventListener( | |
802 'change', this.onRootsSelectionChanged_.bind(this)); | |
803 | |
804 // TODO(dgozman): add "Add a drive" item. | |
805 this.rootsList_.dataModel = new cr.ui.ArrayDataModel(this.rootEntries_); | |
806 }; | |
807 | |
808 FileManager.prototype.updateRoots_ = function(opt_changeDirectoryTo) { | |
809 var self = this; | |
810 this.resolveRoots_(function(rootEntries) { | |
811 self.rootEntries_ = rootEntries; | |
812 | |
813 var dataModel = self.rootsList_.dataModel; | |
814 var args = [0, dataModel.length].concat(rootEntries); | |
815 dataModel.splice.apply(dataModel, args); | |
816 | |
817 self.updateRootsListSelection_(); | |
818 | |
819 if (opt_changeDirectoryTo) | |
820 self.changeDirectory(opt_changeDirectoryTo); | |
821 }); | |
822 }; | |
823 | |
755 /** | 824 /** |
756 * Get the icon type for a given Entry. | 825 * Get the icon type for a given Entry. |
757 * | 826 * |
758 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). | 827 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). |
759 * @return {string} | 828 * @return {string} |
760 */ | 829 */ |
761 FileManager.prototype.getIconType = function(entry) { | 830 FileManager.prototype.getIconType = function(entry) { |
762 if (!('cachedIconType_' in entry)) | 831 if (!('cachedIconType_' in entry)) |
763 entry.cachedIconType_ = this.computeIconType_(entry); | 832 entry.cachedIconType_ = this.computeIconType_(entry); |
764 return entry.cachedIconType_; | 833 return entry.cachedIconType_; |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1064 !isSystemDirEntry(this.currentDirEntry_)); | 1133 !isSystemDirEntry(this.currentDirEntry_)); |
1065 | 1134 |
1066 case 'delete': | 1135 case 'delete': |
1067 return (// Initialized to the point where we have a current directory | 1136 return (// Initialized to the point where we have a current directory |
1068 this.currentDirEntry_ && | 1137 this.currentDirEntry_ && |
1069 // Rename not in progress. | 1138 // Rename not in progress. |
1070 !this.renameInput_.currentEntry && | 1139 !this.renameInput_.currentEntry && |
1071 !isSystemDirEntry(this.currentDirEntry_)) && | 1140 !isSystemDirEntry(this.currentDirEntry_)) && |
1072 this.selection && | 1141 this.selection && |
1073 this.selection.totalCount > 0; | 1142 this.selection.totalCount > 0; |
1143 | |
1144 case 'newfolder': | |
1145 return this.currentDirEntry_ && | |
1146 (this.dialogType_ == 'saveas-file' || | |
1147 this.dialogType_ == 'full-page'); | |
1074 } | 1148 } |
1075 }; | 1149 }; |
1076 | 1150 |
1077 FileManager.prototype.updateCommonActionButtons_ = function() { | 1151 FileManager.prototype.updateCommonActionButtons_ = function() { |
1078 if (this.deleteButton_) | 1152 if (this.deleteButton_) |
1079 this.deleteButton_.disabled = !this.canExecute_('delete'); | 1153 this.deleteButton_.disabled = !this.canExecute_('delete'); |
1080 }; | 1154 }; |
1081 | 1155 |
1082 FileManager.prototype.setListType = function(type) { | 1156 FileManager.prototype.setListType = function(type) { |
1083 if (type && type == this.listType_) | 1157 if (type && type == this.listType_) |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1271 leadIndex); | 1345 leadIndex); |
1272 return; | 1346 return; |
1273 } | 1347 } |
1274 | 1348 |
1275 this.initiateRename_(label); | 1349 this.initiateRename_(label); |
1276 return; | 1350 return; |
1277 | 1351 |
1278 case 'delete': | 1352 case 'delete': |
1279 this.deleteEntries(this.selection.entries); | 1353 this.deleteEntries(this.selection.entries); |
1280 return; | 1354 return; |
1355 | |
1356 case 'newfolder': | |
1357 this.onNewFolderCommand_(event); | |
1358 return; | |
1281 } | 1359 } |
1282 }; | 1360 }; |
1283 | 1361 |
1284 /** | 1362 /** |
1285 * Respond to the back and forward buttons. | 1363 * Respond to the back and forward buttons. |
1286 */ | 1364 */ |
1287 FileManager.prototype.onPopState_ = function(event) { | 1365 FileManager.prototype.onPopState_ = function(event) { |
1288 // TODO(serya): We should restore selected items here. | 1366 // TODO(serya): We should restore selected items here. |
1289 if (this.rootEntries_) | 1367 if (this.rootEntries_) |
1290 this.setupCurrentDirectory_(); | 1368 this.setupCurrentDirectory_(); |
1291 }; | 1369 }; |
1292 | 1370 |
1293 FileManager.prototype.requestResize_ = function(timeout) { | 1371 FileManager.prototype.requestResize_ = function(timeout) { |
1294 var self = this; | 1372 var self = this; |
1295 setTimeout(function() { self.onResize_() }, timeout || 0); | 1373 setTimeout(function() { self.onResize_() }, timeout || 0); |
1296 }; | 1374 }; |
1297 | 1375 |
1298 /** | 1376 /** |
1299 * Resize details and thumb views to fit the new window size. | 1377 * Resize details and thumb views to fit the new window size. |
1300 */ | 1378 */ |
1301 FileManager.prototype.onResize_ = function() { | 1379 FileManager.prototype.onResize_ = function() { |
1302 this.table_.style.height = this.grid_.style.height = | 1380 this.table_.style.height = this.grid_.style.height = |
1303 this.grid_.parentNode.clientHeight + 'px'; | 1381 this.grid_.parentNode.clientHeight + 'px'; |
1304 this.table_.style.width = this.grid_.style.width = | |
1305 this.grid_.parentNode.clientWidth + 'px'; | |
1306 | |
1307 this.table_.list_.style.width = this.table_.parentNode.clientWidth + 'px'; | |
1308 this.table_.list_.style.height = (this.table_.clientHeight - 1 - | 1382 this.table_.list_.style.height = (this.table_.clientHeight - 1 - |
1309 this.table_.header_.clientHeight) + 'px'; | 1383 this.table_.header_.clientHeight) + 'px'; |
1310 | 1384 |
1311 if (this.listType_ == FileManager.ListType.THUMBNAIL) { | 1385 if (this.listType_ == FileManager.ListType.THUMBNAIL) { |
1312 var self = this; | 1386 var self = this; |
1313 setTimeout(function() { | 1387 setTimeout(function() { |
1314 self.grid_.columns = 0; | 1388 self.grid_.columns = 0; |
1315 self.grid_.redraw(); | 1389 self.grid_.redraw(); |
1316 }, 0); | 1390 }, 0); |
1317 } else { | 1391 } else { |
1318 this.currentList_.redraw(); | 1392 this.currentList_.redraw(); |
1319 } | 1393 } |
1394 | |
1395 this.rootsList_.style.height = | |
1396 this.rootsList_.parentNode.clientHeight + 'px'; | |
1397 this.rootsList_.redraw(); | |
1320 }; | 1398 }; |
1321 | 1399 |
1322 FileManager.prototype.resolvePath = function( | 1400 FileManager.prototype.resolvePath = function( |
1323 path, resultCallback, errorCallback) { | 1401 path, resultCallback, errorCallback) { |
1324 return util.resolvePath(this.filesystem_.root, path, resultCallback, | 1402 return util.resolvePath(this.filesystem_.root, path, resultCallback, |
1325 errorCallback); | 1403 errorCallback); |
1326 }; | 1404 }; |
1327 | 1405 |
1328 /** | 1406 /** |
1329 * Restores current directory and may be a selected item after page load (or | 1407 * Restores current directory and may be a selected item after page load (or |
(...skipping 13 matching lines...) Expand all Loading... | |
1343 this.setupPath_(this.params_.defaultPath); | 1421 this.setupPath_(this.params_.defaultPath); |
1344 } else { | 1422 } else { |
1345 this.setupDefaultPath_(); | 1423 this.setupDefaultPath_(); |
1346 } | 1424 } |
1347 }; | 1425 }; |
1348 | 1426 |
1349 FileManager.prototype.setupDefaultPath_ = function() { | 1427 FileManager.prototype.setupDefaultPath_ = function() { |
1350 // No preset given, find a good place to start. | 1428 // No preset given, find a good place to start. |
1351 // Check for removable devices, if there are none, go to Downloads. | 1429 // Check for removable devices, if there are none, go to Downloads. |
1352 var removableDirectoryEntry = this.rootEntries_.filter(function(rootEntry) { | 1430 var removableDirectoryEntry = this.rootEntries_.filter(function(rootEntry) { |
1353 return rootEntry.fullPath == REMOVABLE_DIRECTORY; | 1431 return isParentPath(REMOVABLE_DIRECTORY, rootEntry.fullPath); |
1354 })[0]; | 1432 })[0]; |
1355 if (!removableDirectoryEntry) { | 1433 this.changeDirectory( |
1356 this.changeDirectory(DOWNLOADS_DIRECTORY, CD_NO_HISTORY); | 1434 removableDirectoryEntry.fullPath || DOWNLOADS_DIRECTORY, |
1357 return; | 1435 CD_NO_HISTORY); |
1358 } | |
1359 | |
1360 var foundRemovable = false; | |
1361 util.forEachDirEntry(removableDirectoryEntry, function(result) { | |
1362 if (result) { | |
1363 foundRemovable = true; | |
1364 } else { // Done enumerating, and we know the answer. | |
1365 this.changeDirectory(foundRemovable ? '/' : DOWNLOADS_DIRECTORY, | |
1366 CD_NO_HISTORY); | |
1367 } | |
1368 }.bind(this)); | |
1369 }; | 1436 }; |
1370 | 1437 |
1371 FileManager.prototype.setupPath_ = function(path) { | 1438 FileManager.prototype.setupPath_ = function(path) { |
1372 // Split the dirname from the basename. | 1439 // Split the dirname from the basename. |
1373 var ary = path.match(/^(?:(.*)\/)?([^\/]*)$/); | 1440 var ary = path.match(/^(?:(.*)\/)?([^\/]*)$/); |
1374 if (!ary) { | 1441 if (!ary) { |
1375 console.warn('Unable to split default path: ' + path); | 1442 console.warn('Unable to split default path: ' + path); |
1376 self.changeDirectory('/', CD_NO_HISTORY); | 1443 self.changeDirectory('/', CD_NO_HISTORY); |
1377 return; | 1444 return; |
1378 } | 1445 } |
(...skipping 16 matching lines...) Expand all Loading... | |
1395 return; | 1462 return; |
1396 } | 1463 } |
1397 | 1464 |
1398 // Leaf is an existing file, cd to its parent directory and select it. | 1465 // Leaf is an existing file, cd to its parent directory and select it. |
1399 self.changeDirectoryEntry(baseDirEntry, CD_NO_HISTORY, leafEntry.name); | 1466 self.changeDirectoryEntry(baseDirEntry, CD_NO_HISTORY, leafEntry.name); |
1400 } | 1467 } |
1401 | 1468 |
1402 function onLeafError(err) { | 1469 function onLeafError(err) { |
1403 // Set filename first so OK button will update in changeDirectoryEntry. | 1470 // Set filename first so OK button will update in changeDirectoryEntry. |
1404 self.filenameInput_.value = leafName; | 1471 self.filenameInput_.value = leafName; |
1472 self.selectDefaultPathInFilenameInput_(); | |
1405 if (err = FileError.NOT_FOUND_ERR) { | 1473 if (err = FileError.NOT_FOUND_ERR) { |
1406 // Leaf does not exist, it's just a suggested file name. | 1474 // Leaf does not exist, it's just a suggested file name. |
1407 self.changeDirectoryEntry(baseDirEntry, CD_NO_HISTORY); | 1475 self.changeDirectoryEntry(baseDirEntry, CD_NO_HISTORY); |
1408 } else { | 1476 } else { |
1409 console.log('Unexpected error resolving default leaf: ' + err); | 1477 console.log('Unexpected error resolving default leaf: ' + err); |
1410 self.changeDirectoryEntry('/', CD_NO_HISTORY); | 1478 self.changeDirectoryEntry('/', CD_NO_HISTORY); |
1411 } | 1479 } |
1412 } | 1480 } |
1413 | 1481 |
1414 self.resolvePath(path, onLeafFound, onLeafError); | 1482 self.resolvePath(path, onLeafFound, onLeafError); |
1415 } | 1483 } |
1416 | 1484 |
1417 function onBaseError(err) { | 1485 function onBaseError(err) { |
1418 // Set filename first so OK button will update in changeDirectory. | 1486 // Set filename first so OK button will update in changeDirectory. |
1419 self.filenameInput_.value = leafName; | 1487 self.filenameInput_.value = leafName; |
1488 self.selectDefaultPathInFilenameInput_(); | |
1420 console.log('Unexpected error resolving default base "' + | 1489 console.log('Unexpected error resolving default base "' + |
1421 baseName + '": ' + err); | 1490 baseName + '": ' + err); |
1422 self.changeDirectory('/', CD_NO_HISTORY); | 1491 self.changeDirectory('/', CD_NO_HISTORY); |
1423 } | 1492 } |
1424 | 1493 |
1425 if (baseName) { | 1494 if (baseName) { |
1426 this.filesystem_.root.getDirectory( | 1495 this.filesystem_.root.getDirectory( |
1427 baseName, {create: false}, onBaseFound, onBaseError); | 1496 baseName, {create: false}, onBaseFound, onBaseError); |
1428 } else { | 1497 } else { |
1429 onBaseFound(this.filesystem_.root); | 1498 onBaseFound(this.filesystem_.root); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1675 icon.className = 'detail-icon'; | 1744 icon.className = 'detail-icon'; |
1676 this.getIconType(entry); | 1745 this.getIconType(entry); |
1677 icon.setAttribute('iconType', entry.cachedIconType_); | 1746 icon.setAttribute('iconType', entry.cachedIconType_); |
1678 div.appendChild(icon); | 1747 div.appendChild(icon); |
1679 | 1748 |
1680 return div; | 1749 return div; |
1681 }; | 1750 }; |
1682 | 1751 |
1683 FileManager.prototype.getLabelForRootPath_ = function(path) { | 1752 FileManager.prototype.getLabelForRootPath_ = function(path) { |
1684 // This hack lets us localize the top level directories. | 1753 // This hack lets us localize the top level directories. |
1685 if (path == 'Downloads') | 1754 if (path == DOWNLOADS_DIRECTORY) |
1686 return str('DOWNLOADS_DIRECTORY_LABEL'); | 1755 return str('CHROMEBOOK_DIRECTORY_LABEL'); |
1687 | 1756 |
1688 if (path == 'archive') | 1757 if (path == ARCHIVE_DIRECTORY) |
1689 return str('ARCHIVE_DIRECTORY_LABEL'); | 1758 return str('ARCHIVE_DIRECTORY_LABEL'); |
1759 if (isParentPath(ARCHIVE_DIRECTORY, path)) | |
1760 return path.substring(ARCHIVE_DIRECTORY.length + 1); | |
1690 | 1761 |
1691 if (path == 'removable') | 1762 if (path == REMOVABLE_DIRECTORY) |
1692 return str('REMOVABLE_DIRECTORY_LABEL'); | 1763 return str('REMOVABLE_DIRECTORY_LABEL'); |
1764 if (isParentPath(REMOVABLE_DIRECTORY, path)) | |
1765 return path.substring(REMOVABLE_DIRECTORY.length + 1); | |
1693 | 1766 |
1694 return path || str('ROOT_DIRECTORY_LABEL'); | 1767 return path || str('ROOT_DIRECTORY_LABEL'); |
1695 }; | 1768 }; |
1696 | 1769 |
1770 FileManager.prototype.getRootIconUrl_ = function(path, opt_small) { | |
1771 var iconUrl = opt_small ? 'images/chromebook_28x28.png' : | |
1772 'images/chromebook_24x24.png'; | |
1773 if (isParentPath(REMOVABLE_DIRECTORY, path)) | |
1774 iconUrl = 'images/filetype_device.png'; | |
1775 if (isParentPath(ARCHIVE_DIRECTORY, path)) | |
1776 iconUrl = 'images/icon_mount_archive_16x16.png'; | |
1777 return chrome.extension.getURL(iconUrl); | |
1778 }; | |
1779 | |
1780 FileManager.prototype.renderRoot_ = function(entry) { | |
1781 var li = this.document_.createElement('li'); | |
1782 li.className = 'root-item'; | |
1783 | |
1784 var icon = this.document_.createElement('img'); | |
1785 icon.setAttribute('src', this.getRootIconUrl_(entry.fullPath, false)); | |
1786 li.appendChild(icon); | |
1787 | |
1788 var div = this.document_.createElement('div'); | |
1789 div.textContent = this.getLabelForRootPath_(entry.fullPath); | |
1790 li.appendChild(div); | |
1791 | |
1792 if (isParentPath(REMOVABLE_DIRECTORY, entry.fullPath) || | |
1793 isParentPath(ARCHIVE_DIRECTORY, entry.fullPath)) { | |
1794 var spacer = this.document_.createElement('div'); | |
1795 spacer.className = 'spacer'; | |
1796 li.appendChild(spacer); | |
1797 | |
1798 var eject = this.document_.createElement('img'); | |
1799 eject.className = 'root-eject'; | |
1800 eject.setAttribute('src', chrome.extension.getURL('images/eject.png')); | |
1801 eject.addEventListener('click', this.onEjectClick_.bind(this, entry)); | |
1802 li.appendChild(eject); | |
1803 } | |
1804 | |
1805 cr.defineProperty(li, 'lead', cr.PropertyKind.BOOL_ATTR); | |
1806 cr.defineProperty(li, 'selected', cr.PropertyKind.BOOL_ATTR); | |
1807 return li; | |
1808 }; | |
1809 | |
1810 /** | |
1811 * Handler for eject button clicked. | |
1812 * @param {Entry} entry Entry to eject. | |
1813 * @param {Event} event The event. | |
1814 */ | |
1815 FileManager.prototype.onEjectClick_ = function(entry, event) { | |
1816 this.unmountRequests_.push(entry.toURL()); | |
1817 chrome.fileBrowserPrivate.removeMount(entry.fullPath); | |
1818 }; | |
1819 | |
1697 /** | 1820 /** |
1698 * Render the Name column of the detail table. | 1821 * Render the Name column of the detail table. |
1699 * | 1822 * |
1700 * Invoked by cr.ui.Table when a file needs to be rendered. | 1823 * Invoked by cr.ui.Table when a file needs to be rendered. |
1701 * | 1824 * |
1702 * @param {Entry} entry The Entry object to render. | 1825 * @param {Entry} entry The Entry object to render. |
1703 * @param {string} columnId The id of the column to be rendered. | 1826 * @param {string} columnId The id of the column to be rendered. |
1704 * @param {cr.ui.Table} table The table doing the rendering. | 1827 * @param {cr.ui.Table} table The table doing the rendering. |
1705 */ | 1828 */ |
1706 FileManager.prototype.renderName_ = function(entry, columnId, table) { | 1829 FileManager.prototype.renderName_ = function(entry, columnId, table) { |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2035 // Skip the button creation. | 2158 // Skip the button creation. |
2036 if (!str('ENABLE_PHOTO_EDITOR')) continue; | 2159 if (!str('ENABLE_PHOTO_EDITOR')) continue; |
2037 this.galleryTask_ = task; | 2160 this.galleryTask_ = task; |
2038 } | 2161 } |
2039 } | 2162 } |
2040 this.renderTaskButton_(task); | 2163 this.renderTaskButton_(task); |
2041 } | 2164 } |
2042 | 2165 |
2043 // These are done in separate functions, as the checks require | 2166 // These are done in separate functions, as the checks require |
2044 // asynchronous function calls. | 2167 // asynchronous function calls. |
2045 this.maybeRenderUnmountTask_(selection); | |
2046 this.maybeRenderFormattingTask_(selection); | 2168 this.maybeRenderFormattingTask_(selection); |
2047 }; | 2169 }; |
2048 | 2170 |
2049 FileManager.prototype.renderTaskButton_ = function(task) { | 2171 FileManager.prototype.renderTaskButton_ = function(task) { |
2050 var button = this.document_.createElement('button'); | 2172 var button = this.document_.createElement('button'); |
2051 button.addEventListener('click', | 2173 button.addEventListener('click', |
2052 this.onTaskButtonClicked_.bind(this, task)); | 2174 this.onTaskButtonClicked_.bind(this, task)); |
2053 button.className = 'task-button'; | 2175 button.className = 'task-button'; |
2054 | 2176 |
2055 var img = this.document_.createElement('img'); | 2177 var img = this.document_.createElement('img'); |
2056 img.src = task.iconUrl; | 2178 img.src = task.iconUrl; |
2057 | 2179 |
2058 button.appendChild(img); | 2180 button.appendChild(img); |
2059 var label = this.document_.createElement('div'); | 2181 var label = this.document_.createElement('div'); |
2060 label.appendChild(this.document_.createTextNode(task.title)) | 2182 label.appendChild(this.document_.createTextNode(task.title)) |
2061 button.appendChild(label); | 2183 button.appendChild(label); |
2062 | 2184 |
2063 this.taskButtons_.appendChild(button); | 2185 this.taskButtons_.appendChild(button); |
2064 }; | 2186 }; |
2065 | 2187 |
2066 /** | 2188 /** |
2067 * Checks whether unmount task should be displayed and if the answer is | |
2068 * affirmative renders it. | |
2069 * @param {Object} selection Selected files object. | |
2070 */ | |
2071 FileManager.prototype.maybeRenderUnmountTask_ = function(selection) { | |
2072 for (var index = 0; index < selection.urls.length; ++index) { | |
2073 // Each url should be a mount point. | |
2074 var path = selection.entries[index].fullPath; | |
2075 var found = false; | |
2076 for (var i = 0; i < this.mountPoints_.length; i++) { | |
2077 var mountPath = this.mountPoints_[i].mountPath; | |
2078 if (mountPath[0] != '/') { | |
2079 mountPath = '/' + mountPath; | |
2080 } | |
2081 if (mountPath == path && this.mountPoints_[i].mountType == 'file') { | |
2082 found = true; | |
2083 break; | |
2084 } | |
2085 } | |
2086 if (!found) | |
2087 return; | |
2088 } | |
2089 this.renderTaskButton_({ | |
2090 taskId: this.getExtensionId_() + '|unmount-archive', | |
2091 iconUrl: | |
2092 chrome.extension.getURL('images/icon_unmount_archive_16x16.png'), | |
2093 title: str('UNMOUNT_ARCHIVE'), | |
2094 internal: true | |
2095 }); | |
2096 }; | |
2097 | |
2098 /** | |
2099 * Checks whether formatting task should be displayed and if the answer is | 2189 * Checks whether formatting task should be displayed and if the answer is |
2100 * affirmative renders it. Includes asynchronous calls, so it's splitted into | 2190 * affirmative renders it. Includes asynchronous calls, so it's splitted into |
2101 * three parts. | 2191 * three parts. |
2102 * @param {Object} selection Selected files object. | 2192 * @param {Object} selection Selected files object. |
2103 */ | 2193 */ |
2104 FileManager.prototype.maybeRenderFormattingTask_ = function(selection) { | 2194 FileManager.prototype.maybeRenderFormattingTask_ = function(selection) { |
2105 // Not to make unnecessary getMountPoints() call we doublecheck if there is | 2195 // Not to make unnecessary getMountPoints() call we doublecheck if there is |
2106 // only one selected entry. | 2196 // only one selected entry. |
2107 if (selection.entries.length != 1) | 2197 if (selection.entries.length != 1) |
2108 return; | 2198 return; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2169 chrome.fileBrowserPrivate.executeTask(task.taskId, urls); | 2259 chrome.fileBrowserPrivate.executeTask(task.taskId, urls); |
2170 }; | 2260 }; |
2171 | 2261 |
2172 /** | 2262 /** |
2173 * Event handler called when some volume was mounted or unmouted. | 2263 * Event handler called when some volume was mounted or unmouted. |
2174 */ | 2264 */ |
2175 FileManager.prototype.onMountCompleted_ = function(event) { | 2265 FileManager.prototype.onMountCompleted_ = function(event) { |
2176 var self = this; | 2266 var self = this; |
2177 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { | 2267 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { |
2178 self.mountPoints_ = mountPoints; | 2268 self.mountPoints_ = mountPoints; |
2269 var changeDirectoryTo = null; | |
2270 | |
2179 if (event.eventType == 'mount') { | 2271 if (event.eventType == 'mount') { |
2180 for (var index = 0; index < self.mountRequests_.length; ++index) { | 2272 // Mount request finished - remove it. |
2181 if (self.mountRequests_[index] == event.sourceUrl) { | 2273 var index = self.mountRequests_.indexOf(event.sourceUrl); |
2182 self.mountRequests_.splice(index, 1); | 2274 if (index != -1) { |
2183 if (event.status == 'success') { | 2275 self.mountRequests_.splice(index, 1); |
2184 self.changeDirectory(event.mountPath); | 2276 // Go to mounted directory, if request was initiated from this tab. |
2185 } else { | 2277 if (event.status == 'success') |
2186 // Report mount error. | 2278 changeDirectoryTo = event.mountPath; |
2187 if (event.mountType == 'file') { | |
2188 var fileName = event.sourceUrl.substr( | |
2189 event.sourceUrl.lastIndexOf('/') + 1); | |
2190 self.alert.show(strf('ARCHIVE_MOUNT_FAILED', fileName, | |
2191 event.status)); | |
2192 } | |
2193 } | |
2194 return; | |
2195 } | |
2196 } | 2279 } |
2197 } | 2280 } |
2198 | 2281 |
2282 if (event.eventType == 'unmount') { | |
2283 // Unmount request finished - remove it. | |
2284 var index = self.unmountRequests_.indexOf(event.sourceUrl); | |
2285 if (index != -1) | |
2286 self.unmountRequests_.splice(index, 1); | |
2287 } | |
2288 | |
2289 if (event.eventType == 'mount' && event.status != 'success' && | |
2290 event.mountType == 'file') { | |
2291 // Report mount error. | |
2292 var fileName = event.sourceUrl.substr( | |
2293 event.sourceUrl.lastIndexOf('/') + 1); | |
2294 self.alert.show(strf('ARCHIVE_MOUNT_FAILED', fileName, | |
2295 event.status)); | |
2296 } | |
2297 | |
2298 if (event.eventType == 'unmount' && event.status != 'success') { | |
2299 // Report unmount error. | |
2300 // TODO(dgozman): introduce string and show alert here. | |
2301 } | |
2302 | |
2199 if (event.eventType == 'unmount' && event.status == 'success' && | 2303 if (event.eventType == 'unmount' && event.status == 'success' && |
2200 self.currentDirEntry_ && | 2304 self.currentDirEntry_ && |
2201 isParentPath(event.mountPath, self.currentDirEntry_.fullPath)) { | 2305 isParentPath(event.mountPath, self.currentDirEntry_.fullPath)) { |
2202 self.changeDirectory(getParentPath(event.mountPath)); | 2306 changeDirectoryTo = getParentPath(event.mountPath); |
2203 return; | |
2204 } | 2307 } |
2205 | 2308 |
2206 var rescanDirectoryNeeded = (event.status == 'success'); | 2309 // In the case of success, roots are changed and should be rescanned. |
2310 if (event.status == 'success') | |
2311 self.updateRoots_(changeDirectoryTo); | |
2312 | |
2313 var rescanDirectoryNeeded = false; | |
Dmitry Zvorygin
2011/11/22 14:42:47
rescanDirecoty API has changed a bit. There's auto
dgozman
2011/11/22 14:51:38
Deleted this. Hooray!
| |
2207 for (var i = 0; i < mountPoints.length; i++) { | 2314 for (var i = 0; i < mountPoints.length; i++) { |
2208 if (event.sourceUrl == mountPoints[i].sourceUrl && | 2315 if (event.sourceUrl == mountPoints[i].sourceUrl && |
2209 mountPoints[i].mountCondition != '') { | 2316 mountPoints[i].mountCondition != '') { |
2210 rescanDirectoryNeeded = true; | 2317 rescanDirectoryNeeded = true; |
2211 } | 2318 } |
2212 } | 2319 } |
2213 // TODO(dgozman): rescan directory, only if it contains mounted points, | |
2214 // when mounts location will be decided. | |
2215 if (rescanDirectoryNeeded) | 2320 if (rescanDirectoryNeeded) |
2216 self.rescanDirectory_(null, 300); | 2321 self.rescanDirectory_(null, 300); |
Dmitry Zvorygin
2011/11/22 14:42:47
Rescan directory second parameter is error callbac
dgozman
2011/11/22 14:51:38
And this too. Hooray!
| |
2217 }); | 2322 }); |
2218 }; | 2323 }; |
2219 | 2324 |
2220 /** | 2325 /** |
2221 * Event handler called when some internal task should be executed. | 2326 * Event handler called when some internal task should be executed. |
2222 */ | 2327 */ |
2223 FileManager.prototype.onFileTaskExecute_ = function(id, details) { | 2328 FileManager.prototype.onFileTaskExecute_ = function(id, details) { |
2224 var urls = details.urls; | 2329 var urls = details.urls; |
2225 if (id == 'preview') { | 2330 if (id == 'preview') { |
2226 g_slideshow_data = urls; | 2331 g_slideshow_data = urls; |
2227 chrome.tabs.create({url: "slideshow.html"}); | 2332 chrome.tabs.create({url: "slideshow.html"}); |
2228 } else if (id == 'play' || id == 'enqueue') { | 2333 } else if (id == 'play' || id == 'enqueue') { |
2229 chrome.fileBrowserPrivate.viewFiles(urls, id); | 2334 chrome.fileBrowserPrivate.viewFiles(urls, id); |
2230 } else if (id == 'mount-archive') { | 2335 } else if (id == 'mount-archive') { |
2231 for (var index = 0; index < urls.length; ++index) { | 2336 for (var index = 0; index < urls.length; ++index) { |
2232 this.mountRequests_.push(urls[index]); | 2337 this.mountRequests_.push(urls[index]); |
2233 chrome.fileBrowserPrivate.addMount(urls[index], 'file', {}); | 2338 chrome.fileBrowserPrivate.addMount(urls[index], 'file', {}); |
2234 } | 2339 } |
2235 } else if (id == 'unmount-archive') { | |
2236 for (var index = 0; index < urls.length; ++index) { | |
2237 chrome.fileBrowserPrivate.removeMount(urls[index]); | |
2238 } | |
2239 } else if (id == 'format-device') { | 2340 } else if (id == 'format-device') { |
2240 this.confirm.show(str('FORMATTING_WARNING'), function() { | 2341 this.confirm.show(str('FORMATTING_WARNING'), function() { |
2241 chrome.fileBrowserPrivate.formatDevice(urls[0]); | 2342 chrome.fileBrowserPrivate.formatDevice(urls[0]); |
2242 }); | 2343 }); |
2243 } else if (id == 'gallery') { | 2344 } else if (id == 'gallery') { |
2244 // Pass to gallery all possible tasks except the gallery itself. | 2345 // Pass to gallery all possible tasks except the gallery itself. |
2245 var noGallery = []; | 2346 var noGallery = []; |
2246 for (var index = 0; index < details.task.allTasks.length; index++) { | 2347 for (var index = 0; index < details.task.allTasks.length; index++) { |
2247 var task = details.task.allTasks[index]; | 2348 var task = details.task.allTasks[index]; |
2248 if (task.taskId != this.getExtensionId_() + '|gallery') { | 2349 if (task.taskId != this.getExtensionId_() + '|gallery') { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2305 self.metadataProvider_, | 2406 self.metadataProvider_, |
2306 shareActions, | 2407 shareActions, |
2307 str); | 2408 str); |
2308 }; | 2409 }; |
2309 | 2410 |
2310 galleryFrame.src = 'js/image_editor/gallery.html'; | 2411 galleryFrame.src = 'js/image_editor/gallery.html'; |
2311 this.dialogDom_.appendChild(galleryFrame); | 2412 this.dialogDom_.appendChild(galleryFrame); |
2312 galleryFrame.focus(); | 2413 galleryFrame.focus(); |
2313 }; | 2414 }; |
2314 | 2415 |
2416 FileManager.prototype.getRootForPath_ = function(path) { | |
2417 for (var index = 0; index < this.rootEntries_.length; index++) { | |
2418 if (isParentPath(this.rootEntries_[index].fullPath, path)) { | |
2419 return index; | |
2420 } | |
2421 } | |
2422 return -1; | |
2423 }; | |
2424 | |
2315 /** | 2425 /** |
2316 * Update the breadcrumb display to reflect the current directory. | 2426 * Update the breadcrumb display to reflect the current directory. |
2317 */ | 2427 */ |
2318 FileManager.prototype.updateBreadcrumbs_ = function() { | 2428 FileManager.prototype.updateBreadcrumbs_ = function() { |
2319 var bc = this.dialogDom_.querySelector('.breadcrumbs'); | 2429 var bc = this.dialogDom_.querySelector('.breadcrumbs'); |
2320 bc.innerHTML = ''; | 2430 bc.innerHTML = ''; |
2321 | 2431 |
2322 var fullPath = this.currentDirEntry_.fullPath.replace(/\/$/, ''); | 2432 var fullPath = this.currentDirEntry_.fullPath; |
2323 var pathNames = fullPath.split('/'); | 2433 var rootIndex = this.getRootForPath_(fullPath); |
2324 var path = ''; | 2434 if (rootIndex == -1) { |
2435 console.error('Not root for: ' + fullPath); | |
2436 return; | |
2437 } | |
2438 var root = this.rootEntries_[rootIndex]; | |
2439 | |
2440 var icon = this.document_.createElement('img'); | |
2441 icon.className = 'breadcrumb-icon'; | |
2442 icon.setAttribute('src', this.getRootIconUrl_(root.fullPath, true)); | |
2443 bc.appendChild(icon); | |
2444 | |
2445 var rootPath = root.fullPath; | |
2446 var relativePath = fullPath.substring(rootPath.length); | |
2447 var pathNames = relativePath.replace(/\/$/, '').split('/'); | |
2448 if (pathNames[0] == '') | |
2449 pathNames.splice(0, 1); | |
2450 | |
2451 // We need a first breadcrumb for root, so placing last name from | |
2452 // rootPath as first name of relativePath. | |
2453 var rootPathNames = rootPath.replace(/\/$/, '').split('/'); | |
2454 pathNames.splice(0, 0, rootPathNames[rootPathNames.length - 1]); | |
2455 rootPathNames.splice(rootPathNames.length - 1, 1); | |
2456 var path = rootPathNames.join('/') + '/'; | |
2325 | 2457 |
2326 for (var i = 0; i < pathNames.length; i++) { | 2458 for (var i = 0; i < pathNames.length; i++) { |
2327 var pathName = pathNames[i]; | 2459 var pathName = pathNames[i]; |
2328 path += pathName + '/'; | 2460 path += pathName; |
2329 | 2461 |
2330 var div = this.document_.createElement('div'); | 2462 var div = this.document_.createElement('div'); |
2331 div.className = 'breadcrumb-path'; | 2463 div.className = 'breadcrumb-path'; |
2332 if (i <= 1) { | 2464 if (i == 0) { |
2333 // i == 0: root directory itself, i == 1: the files it contains. | 2465 div.textContent = this.getLabelForRootPath_(path); |
2334 div.textContent = this.getLabelForRootPath_(pathName); | |
2335 } else { | 2466 } else { |
2336 div.textContent = pathName; | 2467 div.textContent = pathName; |
2337 } | 2468 } |
2338 | 2469 |
2470 path = path + '/'; | |
2339 div.path = path; | 2471 div.path = path; |
2340 div.addEventListener('click', this.onBreadcrumbClick_.bind(this)); | 2472 div.addEventListener('click', this.onBreadcrumbClick_.bind(this)); |
2341 | 2473 |
2342 bc.appendChild(div); | 2474 bc.appendChild(div); |
2343 | 2475 |
2344 if (i == pathNames.length - 1) { | 2476 if (i == pathNames.length - 1) { |
2345 div.classList.add('breadcrumb-last'); | 2477 div.classList.add('breadcrumb-last'); |
2346 } else { | 2478 } else { |
2347 var spacer = this.document_.createElement('div'); | 2479 var spacer = this.document_.createElement('div'); |
2348 spacer.className = 'breadcrumb-spacer'; | 2480 spacer.className = 'breadcrumb-spacer'; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2428 for (var i = 0; i < this.dataModel_.length; i++) { | 2560 for (var i = 0; i < this.dataModel_.length; i++) { |
2429 if (this.dataModel_.item(i).name == name) { | 2561 if (this.dataModel_.item(i).name == name) { |
2430 this.currentList_.selectionModel.selectedIndex = i; | 2562 this.currentList_.selectionModel.selectedIndex = i; |
2431 this.currentList_.scrollIndexIntoView(i); | 2563 this.currentList_.scrollIndexIntoView(i); |
2432 this.currentList_.focus(); | 2564 this.currentList_.focus(); |
2433 return; | 2565 return; |
2434 } | 2566 } |
2435 } | 2567 } |
2436 }; | 2568 }; |
2437 | 2569 |
2570 FileManager.prototype.updateRootsListSelection_ = function() { | |
2571 if (!this.currentDirEntry_) return; | |
2572 var index = this.getRootForPath_(this.currentDirEntry_.fullPath); | |
2573 if (index == -1) { | |
2574 this.rootsList_.selectionModel.selectedIndex = 0; | |
2575 } else { | |
2576 if (this.rootsList_.selectionModel.selectedIndex != index) | |
2577 this.rootsList_.selectionModel.selectedIndex = index; | |
2578 } | |
2579 }; | |
2580 | |
2438 /** | 2581 /** |
2439 * Add the file/directory with given name to the current selection. | 2582 * Add the file/directory with given name to the current selection. |
2440 * | 2583 * |
2441 * @param {string} name The name of the entry to select. | 2584 * @param {string} name The name of the entry to select. |
2442 * @return {boolean} Whether entry exists. | 2585 * @return {boolean} Whether entry exists. |
2443 */ | 2586 */ |
2444 FileManager.prototype.addItemToSelection = function(name) { | 2587 FileManager.prototype.addItemToSelection = function(name) { |
2445 var entryExists = false; | 2588 var entryExists = false; |
2446 for (var i = 0; i < this.dataModel_.length; i++) { | 2589 for (var i = 0; i < this.dataModel_.length; i++) { |
2447 if (this.dataModel_.item(i).name == name) { | 2590 if (this.dataModel_.item(i).name == name) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2543 FileManager.prototype.changeDirectoryEntry = function(dirEntry, | 2686 FileManager.prototype.changeDirectoryEntry = function(dirEntry, |
2544 opt_saveHistory, | 2687 opt_saveHistory, |
2545 opt_selectedEntry, | 2688 opt_selectedEntry, |
2546 opt_callback) { | 2689 opt_callback) { |
2547 if (typeof opt_saveHistory == 'undefined') { | 2690 if (typeof opt_saveHistory == 'undefined') { |
2548 opt_saveHistory = true; | 2691 opt_saveHistory = true; |
2549 } else { | 2692 } else { |
2550 opt_saveHistory = !!opt_saveHistory; | 2693 opt_saveHistory = !!opt_saveHistory; |
2551 } | 2694 } |
2552 | 2695 |
2696 // Some directories are above roots, so we instead show the first root. | |
2697 // There may be request to change directory above the roots. For example, | |
2698 // when usb-dirve is removed, we try to change to the parent directory, | |
2699 // which is REMOVABLE_DIRECTORY. | |
2700 if (!dirEntry || dirEntry.fullPath == '/' || | |
2701 dirEntry.fullPath == REMOVABLE_DIRECTORY || | |
2702 dirEntry.fullPath == ARCHIVE_DIRECTORY) { | |
2703 dirEntry = this.rootEntries_[0] || dirEntry; | |
2704 } | |
2705 | |
2553 var location = '#' + encodeURI(dirEntry.fullPath); | 2706 var location = '#' + encodeURI(dirEntry.fullPath); |
2554 if (opt_saveHistory) { | 2707 if (opt_saveHistory) { |
2555 history.pushState(undefined, dirEntry.fullPath, location); | 2708 history.pushState(undefined, dirEntry.fullPath, location); |
2556 } else if (window.location.hash != location) { | 2709 } else if (window.location.hash != location) { |
2557 // If the user typed URL manually that is not canonical it would be fixed | 2710 // If the user typed URL manually that is not canonical it would be fixed |
2558 // here. However it seems history.replaceState doesn't work properly | 2711 // here. However it seems history.replaceState doesn't work properly |
2559 // with rewritable URLs (while does with history.pushState). It changes | 2712 // with rewritable URLs (while does with history.pushState). It changes |
2560 // window.location but doesn't change content of the ombibox. | 2713 // window.location but doesn't change content of the ombibox. |
2561 history.replaceState(undefined, dirEntry.fullPath, location); | 2714 history.replaceState(undefined, dirEntry.fullPath, location); |
2562 } | 2715 } |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2779 // then the default action of this click event fires and toggles the | 2932 // then the default action of this click event fires and toggles the |
2780 // checkbox back off. | 2933 // checkbox back off. |
2781 // | 2934 // |
2782 // Since we're going to force checkboxes into the correct state for any | 2935 // Since we're going to force checkboxes into the correct state for any |
2783 // multi-selection, we can prevent this shift click from toggling the | 2936 // multi-selection, we can prevent this shift click from toggling the |
2784 // checkbox and avoid the trouble. | 2937 // checkbox and avoid the trouble. |
2785 event.preventDefault(); | 2938 event.preventDefault(); |
2786 } | 2939 } |
2787 }; | 2940 }; |
2788 | 2941 |
2942 FileManager.prototype.onRootsSelectionChanged_ = function(event) { | |
2943 var root = this.rootEntries_[this.rootsList_.selectionModel.selectedIndex]; | |
2944 this.changeDirectoryEntry(root); | |
2945 }; | |
2946 | |
2947 FileManager.prototype.selectDefaultPathInFilenameInput_ = function() { | |
2948 var input = this.filenameInput_; | |
2949 input.focus(); | |
2950 var selectionEnd = input.value.lastIndexOf('.'); | |
2951 if (selectionEnd == -1) { | |
2952 input.select(); | |
2953 } else { | |
2954 input.selectionStart = 0; | |
2955 input.selectionEnd = selectionEnd; | |
2956 } | |
2957 // Clear, so we never do this again. | |
2958 this.params_.defaultPath = ''; | |
2959 }; | |
2960 | |
2789 /** | 2961 /** |
2790 * Update the UI when the selection model changes. | 2962 * Update the UI when the selection model changes. |
2791 * | 2963 * |
2792 * @param {cr.Event} event The change event. | 2964 * @param {cr.Event} event The change event. |
2793 */ | 2965 */ |
2794 FileManager.prototype.onSelectionChanged_ = function(event) { | 2966 FileManager.prototype.onSelectionChanged_ = function(event) { |
2795 this.summarizeSelection_(); | 2967 this.summarizeSelection_(); |
2796 | 2968 |
2797 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { | 2969 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { |
2798 // If this is a save-as dialog, copy the selected file into the filename | 2970 // If this is a save-as dialog, copy the selected file into the filename |
2799 // input text box. | 2971 // input text box. |
2800 | 2972 |
2801 if (this.selection && | 2973 if (this.selection && |
2802 this.selection.totalCount == 1 && | 2974 this.selection.totalCount == 1 && |
2803 this.selection.entries[0].isFile) | 2975 this.selection.entries[0].isFile && |
2976 this.filenameInput_.value != this.selection.entries[0].name) { | |
2804 this.filenameInput_.value = this.selection.entries[0].name; | 2977 this.filenameInput_.value = this.selection.entries[0].name; |
2978 if (this.params_.defaultPath == this.selection.entries[0].fullPath) | |
2979 this.selectDefaultPathInFilenameInput_(); | |
2980 } | |
2805 } | 2981 } |
2806 | 2982 |
2807 this.updateOkButton_(); | 2983 this.updateOkButton_(); |
2808 | 2984 |
2809 var self = this; | 2985 var self = this; |
2810 setTimeout(function() { self.onSelectionChangeComplete_(event) }, 0); | 2986 setTimeout(function() { self.onSelectionChangeComplete_(event) }, 0); |
2811 }; | 2987 }; |
2812 | 2988 |
2813 /** | 2989 /** |
2814 * Handle selection change related tasks that won't run properly during | 2990 * Handle selection change related tasks that won't run properly during |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2947 * Update the UI when the current directory changes. | 3123 * Update the UI when the current directory changes. |
2948 * | 3124 * |
2949 * @param {cr.Event} event The directory-changed event. | 3125 * @param {cr.Event} event The directory-changed event. |
2950 */ | 3126 */ |
2951 FileManager.prototype.onDirectoryChanged_ = function(event) { | 3127 FileManager.prototype.onDirectoryChanged_ = function(event) { |
2952 this.updateCommands_(); | 3128 this.updateCommands_(); |
2953 this.updateOkButton_(); | 3129 this.updateOkButton_(); |
2954 | 3130 |
2955 this.checkFreeSpace_(this.currentDirEntry_.fullPath); | 3131 this.checkFreeSpace_(this.currentDirEntry_.fullPath); |
2956 | 3132 |
2957 // New folder should never be enabled in the root or media/ directories. | 3133 // TODO(dgozman): title may be better than this. |
2958 this.newFolderButton_.disabled = isSystemDirEntry(this.currentDirEntry_); | |
2959 | |
2960 this.document_.title = this.currentDirEntry_.fullPath; | 3134 this.document_.title = this.currentDirEntry_.fullPath; |
2961 | 3135 |
2962 var self = this; | 3136 var self = this; |
2963 | 3137 |
2964 if (this.subscribedOnDirectoryChanges_) { | 3138 if (this.subscribedOnDirectoryChanges_) { |
2965 chrome.fileBrowserPrivate.removeFileWatch(event.previousDirEntry.toURL(), | 3139 chrome.fileBrowserPrivate.removeFileWatch(event.previousDirEntry.toURL(), |
2966 function(result) { | 3140 function(result) { |
2967 if (!result) { | 3141 if (!result) { |
2968 console.log('Failed to remove file watch'); | 3142 console.log('Failed to remove file watch'); |
2969 } | 3143 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3045 // Updated when a user clicks on the label of a file, used to detect | 3219 // Updated when a user clicks on the label of a file, used to detect |
3046 // when a click is eligible to trigger a rename. Can be null, or | 3220 // when a click is eligible to trigger a rename. Can be null, or |
3047 // an object with 'path' and 'date' properties. | 3221 // an object with 'path' and 'date' properties. |
3048 this.lastLabelClick_ = null; | 3222 this.lastLabelClick_ = null; |
3049 | 3223 |
3050 // Clear the table first. | 3224 // Clear the table first. |
3051 this.dataModel_.splice(0, this.dataModel_.length); | 3225 this.dataModel_.splice(0, this.dataModel_.length); |
3052 this.currentList_.selectionModel.clear(); | 3226 this.currentList_.selectionModel.clear(); |
3053 | 3227 |
3054 this.updateBreadcrumbs_(); | 3228 this.updateBreadcrumbs_(); |
3229 this.updateRootsListSelection_(); | |
3055 | 3230 |
3056 if (this.currentDirEntry_.fullPath != '/') { | 3231 if (this.currentDirEntry_.fullPath != '/') { |
3057 // Add current request to pending result list | 3232 // Add current request to pending result list |
3058 this.pendingRescanQueue_.push({ | 3233 this.pendingRescanQueue_.push({ |
3059 onSuccess:opt_callback, | 3234 onSuccess:opt_callback, |
3060 onError:opt_onError | 3235 onError:opt_onError |
3061 }); | 3236 }); |
3062 | 3237 |
3063 if (this.rescanRunning_) | 3238 if (this.rescanRunning_) |
3064 return; | 3239 return; |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3393 var selectionEnd = input.value.lastIndexOf('.'); | 3568 var selectionEnd = input.value.lastIndexOf('.'); |
3394 if (selectionEnd == -1) { | 3569 if (selectionEnd == -1) { |
3395 input.select(); | 3570 input.select(); |
3396 } else { | 3571 } else { |
3397 input.selectionStart = 0; | 3572 input.selectionStart = 0; |
3398 input.selectionEnd = selectionEnd; | 3573 input.selectionEnd = selectionEnd; |
3399 } | 3574 } |
3400 }, 0); | 3575 }, 0); |
3401 }; | 3576 }; |
3402 | 3577 |
3403 FileManager.prototype.onNewFolderButtonClick_ = function(event) { | 3578 FileManager.prototype.onToggleSidebar_ = function(event) { |
3579 if (this.dialogContainer_.hasAttribute('sidebar')) { | |
3580 this.dialogContainer_.removeAttribute('sidebar'); | |
3581 } else { | |
3582 this.dialogContainer_.setAttribute('sidebar', 'sidebar'); | |
3583 } | |
3584 setTimeout(this.onResize_.bind(this), 300); | |
3585 }; | |
3586 | |
3587 FileManager.prototype.onNewFolderCommand_ = function(event) { | |
3404 var self = this; | 3588 var self = this; |
3405 | 3589 |
3406 function onNameSelected(name) { | 3590 function onNameSelected(name) { |
3407 var valid = self.validateFileName_(name, function() { | 3591 var valid = self.validateFileName_(name, function() { |
3408 promptForName(name); | 3592 promptForName(name); |
3409 }); | 3593 }); |
3410 | 3594 |
3411 if (!valid) { | 3595 if (!valid) { |
3412 // Validation failed. User will be prompted for a new name after they | 3596 // Validation failed. User will be prompted for a new name after they |
3413 // dismiss the validation error dialog. | 3597 // dismiss the validation error dialog. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3522 this.dialogType_ != FileManager.SELECT_FOLDER) { | 3706 this.dialogType_ != FileManager.SELECT_FOLDER) { |
3523 event.preventDefault(); | 3707 event.preventDefault(); |
3524 this.onDirectoryAction(this.selection.entries[0]); | 3708 this.onDirectoryAction(this.selection.entries[0]); |
3525 } else if (!this.okButton_.disabled) { | 3709 } else if (!this.okButton_.disabled) { |
3526 event.preventDefault(); | 3710 event.preventDefault(); |
3527 this.onOk_(); | 3711 this.onOk_(); |
3528 } | 3712 } |
3529 break; | 3713 break; |
3530 | 3714 |
3531 case 32: // Ctrl-Space => New Folder. | 3715 case 32: // Ctrl-Space => New Folder. |
3532 if (this.newFolderButton_.style.display != 'none' && event.ctrlKey) { | 3716 if ((this.dialogType_ == 'saveas-file' || |
3717 this.dialogType_ == 'full-page') && event.ctrlKey) { | |
3533 event.preventDefault(); | 3718 event.preventDefault(); |
3534 this.onNewFolderButtonClick_(); | 3719 this.onNewFolderCommand_(); |
3535 } | 3720 } |
3536 break; | 3721 break; |
3537 | 3722 |
3538 case 88: // Ctrl-X => Cut. | 3723 case 88: // Ctrl-X => Cut. |
3539 this.updateCommands_(); | 3724 this.updateCommands_(); |
3540 if (!this.commands_['cut'].disabled) { | 3725 if (!this.commands_['cut'].disabled) { |
3541 event.preventDefault(); | 3726 event.preventDefault(); |
3542 this.commands_['cut'].execute(); | 3727 this.commands_['cut'].execute(); |
3543 } | 3728 } |
3544 break; | 3729 break; |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3853 }); | 4038 }); |
3854 }, onError); | 4039 }, onError); |
3855 | 4040 |
3856 function onError(err) { | 4041 function onError(err) { |
3857 console.log('Error while checking free space: ' + err); | 4042 console.log('Error while checking free space: ' + err); |
3858 setTimeout(doCheck, 1000 * 60); | 4043 setTimeout(doCheck, 1000 * 60); |
3859 } | 4044 } |
3860 } | 4045 } |
3861 } | 4046 } |
3862 })(); | 4047 })(); |
OLD | NEW |