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.initFileSystem_(); |
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.initFileSystem_ = 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 var entriesToEnumerate = 0; | |
513 // Entries may be enumerated faster than next one appears, so we have this | |
514 // guard to not finish too early. | |
515 var allEntriesFound = false; | |
516 | |
517 function onPathError(path, err) { | |
518 console.error('Error locating root path: ' + path + ': ' + err); | |
519 } | |
520 | |
521 function onRootFound(root) { | |
522 if (root) { | |
523 rootEntries.push(root); | |
524 } else { | |
525 entriesToEnumerate--; | |
526 if (entriesToEnumerate == 0 && allEntriesFound) { | |
527 metrics.recordTime('EnumerateRoots'); | |
528 callback(rootEntries); | |
529 } | |
530 } | |
531 } | |
532 | |
533 function onEntryFound(entry) { | |
534 if (entry) { | |
535 entriesToEnumerate++; | |
536 var path = entry.fullPath; | |
537 if (path == ARCHIVE_DIRECTORY || path == REMOVABLE_DIRECTORY) { | |
538 // All removable devices and mounted archives are considered | |
539 // roots, and are shown in the sidebar. | |
540 util.forEachDirEntry(entry, onRootFound); | |
541 } else { | |
542 onRootFound(entry); | |
543 onRootFound(null); | |
544 } | |
545 } else { | |
546 allEntriesFound = true; | |
547 } | |
548 } | |
549 | |
550 metrics.startInterval('EnumerateRoots'); | |
551 if (this.filesystem_.name.match(/^chrome-extension_\S+:external/i)) { | |
552 // We've been handed the local filesystem, whose root directory | |
553 // cannot be enumerated. | |
554 util.getDirectories(this.filesystem_.root, {create: false}, rootPaths, | |
555 onEntryFound, onPathError); | |
556 } else { | |
557 util.forEachDirEntry(this.filesystem_.root, onEntryFound); | |
558 } | |
559 }; | |
560 | |
561 /** | |
529 * Continue initializing the file manager after resolving roots. | 562 * Continue initializing the file manager after resolving roots. |
530 */ | 563 */ |
531 FileManager.prototype.init_ = function() { | 564 FileManager.prototype.init_ = function() { |
532 metrics.startInterval('InitFileManager'); | 565 metrics.startInterval('InitFileManager'); |
566 this.initCommands_(); | |
533 | 567 |
534 // TODO(rginda): 6/22/11: Remove this test when createDateTimeFormat is | 568 // TODO(rginda): 6/22/11: Remove this test when createDateTimeFormat is |
535 // available in all chrome trunk builds. | 569 // available in all chrome trunk builds. |
536 if ('createDateTimeFormat' in this.locale_) { | 570 if ('createDateTimeFormat' in this.locale_) { |
537 this.shortDateFormatter_ = | 571 this.shortDateFormatter_ = |
538 this.locale_.createDateTimeFormat({'dateType': 'medium'}); | 572 this.locale_.createDateTimeFormat({'dateType': 'medium'}); |
539 } else { | 573 } else { |
540 this.shortDateFormatter_ = { | 574 this.shortDateFormatter_ = { |
541 format: function(d) { | 575 format: function(d) { |
542 return (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear(); | 576 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)); | 614 window.addEventListener('unload', this.onUnload_.bind(this)); |
581 | 615 |
582 this.addEventListener('directory-changed', | 616 this.addEventListener('directory-changed', |
583 this.onDirectoryChanged_.bind(this)); | 617 this.onDirectoryChanged_.bind(this)); |
584 this.addEventListener('selection-summarized', | 618 this.addEventListener('selection-summarized', |
585 this.onSelectionSummarized_.bind(this)); | 619 this.onSelectionSummarized_.bind(this)); |
586 | 620 |
587 // The list of archives requested to mount. We will show contents once | 621 // 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. | 622 // archive is mounted, but only for mounts from within this filebrowser tab. |
589 this.mountRequests_ = []; | 623 this.mountRequests_ = []; |
624 this.unmountRequests_ = []; | |
590 chrome.fileBrowserPrivate.onMountCompleted.addListener( | 625 chrome.fileBrowserPrivate.onMountCompleted.addListener( |
591 this.onMountCompleted_.bind(this)); | 626 this.onMountCompleted_.bind(this)); |
592 | 627 |
593 chrome.fileBrowserPrivate.onFileChanged.addListener( | 628 chrome.fileBrowserPrivate.onFileChanged.addListener( |
594 this.onFileChanged_.bind(this)); | 629 this.onFileChanged_.bind(this)); |
595 | 630 |
596 var self = this; | 631 var self = this; |
597 | 632 |
598 // The list of callbacks to be invoked during the directory rescan after | 633 // The list of callbacks to be invoked during the directory rescan after |
599 // all paste tasks are complete. | 634 // all paste tasks are complete. |
600 this.pasteSuccessCallbacks_ = []; | 635 this.pasteSuccessCallbacks_ = []; |
601 | 636 |
602 this.initCommands_(); | |
603 | |
604 this.setupCurrentDirectory_(); | 637 this.setupCurrentDirectory_(); |
605 | 638 |
606 this.summarizeSelection_(); | 639 this.summarizeSelection_(); |
607 | 640 |
608 this.dataModel_.sort('cachedMtime_', 'desc'); | 641 this.dataModel_.sort('cachedMtime_', 'desc'); |
609 | 642 |
610 this.refocus(); | 643 this.refocus(); |
611 | 644 |
612 this.createMetadataProvider_(); | 645 this.createMetadataProvider_(); |
613 metrics.recordTime('InitFileManager'); | 646 metrics.recordTime('InitFileManager'); |
614 metrics.recordTime('TotalLoad'); | 647 metrics.recordTime('TotalLoad'); |
615 }; | 648 }; |
616 | 649 |
617 /** | 650 /** |
618 * One-time initialization of commands. | 651 * One-time initialization of commands. |
619 */ | 652 */ |
620 FileManager.prototype.initCommands_ = function() { | 653 FileManager.prototype.initCommands_ = function() { |
621 var commands = this.dialogDom_.querySelectorAll('command'); | 654 var commands = this.dialogDom_.querySelectorAll('command'); |
622 for (var i = 0; i < commands.length; i++) { | 655 for (var i = 0; i < commands.length; i++) { |
623 var command = commands[i]; | 656 var command = commands[i]; |
624 cr.ui.Command.decorate(command); | 657 cr.ui.Command.decorate(command); |
658 command.label = command.textContent; | |
SeRya
2011/11/28 10:30:55
Right way to int-ze the labes is using 'i18-values
dgozman
2011/11/28 11:45:53
Done.
| |
659 command.textContent = ''; | |
625 this.commands_[command.id] = command; | 660 this.commands_[command.id] = command; |
626 } | 661 } |
627 | 662 |
628 this.fileContextMenu_ = this.dialogDom_.querySelector('.file-context-menu'); | 663 this.fileContextMenu_ = this.dialogDom_.querySelector('.file-context-menu'); |
629 cr.ui.Menu.decorate(this.fileContextMenu_); | 664 cr.ui.Menu.decorate(this.fileContextMenu_); |
630 | 665 |
631 this.document_.addEventListener('canExecute', | 666 this.document_.addEventListener('canExecute', |
632 this.onCanExecute_.bind(this)); | 667 this.onCanExecute_.bind(this)); |
633 this.document_.addEventListener('command', this.onCommand_.bind(this)); | 668 this.document_.addEventListener('command', this.onCommand_.bind(this)); |
634 } | 669 } |
(...skipping 17 matching lines...) Expand all Loading... | |
652 // Cache nodes we'll be manipulating. | 687 // Cache nodes we'll be manipulating. |
653 this.previewThumbnails_ = | 688 this.previewThumbnails_ = |
654 this.dialogDom_.querySelector('.preview-thumbnails'); | 689 this.dialogDom_.querySelector('.preview-thumbnails'); |
655 this.previewPanel_ = this.dialogDom_.querySelector('.preview-panel'); | 690 this.previewPanel_ = this.dialogDom_.querySelector('.preview-panel'); |
656 this.previewFilename_ = this.dialogDom_.querySelector('.preview-filename'); | 691 this.previewFilename_ = this.dialogDom_.querySelector('.preview-filename'); |
657 this.previewSummary_ = this.dialogDom_.querySelector('.preview-summary'); | 692 this.previewSummary_ = this.dialogDom_.querySelector('.preview-summary'); |
658 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input'); | 693 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input'); |
659 this.taskButtons_ = this.dialogDom_.querySelector('.task-buttons'); | 694 this.taskButtons_ = this.dialogDom_.querySelector('.task-buttons'); |
660 this.okButton_ = this.dialogDom_.querySelector('.ok'); | 695 this.okButton_ = this.dialogDom_.querySelector('.ok'); |
661 this.cancelButton_ = this.dialogDom_.querySelector('.cancel'); | 696 this.cancelButton_ = this.dialogDom_.querySelector('.cancel'); |
662 this.newFolderButton_ = this.dialogDom_.querySelector('.new-folder'); | |
663 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button'); | 697 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button'); |
664 | 698 |
665 this.downloadsWarning_ = | 699 this.downloadsWarning_ = |
666 this.dialogDom_.querySelector('.downloads-warning'); | 700 this.dialogDom_.querySelector('.downloads-warning'); |
667 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); | 701 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); |
668 this.downloadsWarning_.lastElementChild.innerHTML = html; | 702 this.downloadsWarning_.lastElementChild.innerHTML = html; |
669 var link = this.downloadsWarning_.querySelector('a'); | 703 var link = this.downloadsWarning_.querySelector('a'); |
670 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this)); | 704 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this)); |
671 | 705 |
672 this.document_.addEventListener('keydown', this.onKeyDown_.bind(this)); | 706 this.document_.addEventListener('keydown', this.onKeyDown_.bind(this)); |
(...skipping 10 matching lines...) Expand all Loading... | |
683 'keyup', this.onFilenameInputKeyUp_.bind(this)); | 717 'keyup', this.onFilenameInputKeyUp_.bind(this)); |
684 this.filenameInput_.addEventListener( | 718 this.filenameInput_.addEventListener( |
685 'focus', this.onFilenameInputFocus_.bind(this)); | 719 'focus', this.onFilenameInputFocus_.bind(this)); |
686 | 720 |
687 var listContainer = this.dialogDom_.querySelector('.list-container'); | 721 var listContainer = this.dialogDom_.querySelector('.list-container'); |
688 listContainer.addEventListener('keydown', this.onListKeyDown_.bind(this)); | 722 listContainer.addEventListener('keydown', this.onListKeyDown_.bind(this)); |
689 listContainer.addEventListener('keypress', this.onListKeyPress_.bind(this)); | 723 listContainer.addEventListener('keypress', this.onListKeyPress_.bind(this)); |
690 this.okButton_.addEventListener('click', this.onOk_.bind(this)); | 724 this.okButton_.addEventListener('click', this.onOk_.bind(this)); |
691 this.cancelButton_.addEventListener('click', this.onCancel_.bind(this)); | 725 this.cancelButton_.addEventListener('click', this.onCancel_.bind(this)); |
692 | 726 |
693 this.dialogDom_.querySelector('button.new-folder').addEventListener( | 727 this.dialogDom_.querySelector('div.open-sidebar').addEventListener( |
694 'click', this.onNewFolderButtonClick_.bind(this)); | 728 'click', this.onToggleSidebar_.bind(this)); |
729 this.dialogDom_.querySelector('div.close-sidebar').addEventListener( | |
730 'click', this.onToggleSidebar_.bind(this)); | |
731 this.dialogContainer_ = this.dialogDom_.querySelector('.dialog-container'); | |
695 | 732 |
696 this.dialogDom_.querySelector('button.detail-view').addEventListener( | 733 this.dialogDom_.querySelector('button.detail-view').addEventListener( |
697 'click', this.onDetailViewButtonClick_.bind(this)); | 734 'click', this.onDetailViewButtonClick_.bind(this)); |
698 this.dialogDom_.querySelector('button.thumbnail-view').addEventListener( | 735 this.dialogDom_.querySelector('button.thumbnail-view').addEventListener( |
699 'click', this.onThumbnailViewButtonClick_.bind(this)); | 736 'click', this.onThumbnailViewButtonClick_.bind(this)); |
700 | 737 |
701 this.dialogDom_.ownerDocument.defaultView.addEventListener( | 738 this.dialogDom_.ownerDocument.defaultView.addEventListener( |
702 'resize', this.onResize_.bind(this)); | 739 'resize', this.onResize_.bind(this)); |
703 | 740 |
704 var ary = this.dialogDom_.querySelectorAll('[visibleif]'); | 741 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 || | 774 if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE || |
738 this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FOLDER || | 775 this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FOLDER || |
739 this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { | 776 this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { |
740 this.selectionModelClass_ = cr.ui.ListSingleSelectionModel; | 777 this.selectionModelClass_ = cr.ui.ListSingleSelectionModel; |
741 } else { | 778 } else { |
742 this.selectionModelClass_ = cr.ui.ListSelectionModel; | 779 this.selectionModelClass_ = cr.ui.ListSelectionModel; |
743 } | 780 } |
744 | 781 |
745 this.initTable_(); | 782 this.initTable_(); |
746 this.initGrid_(); | 783 this.initGrid_(); |
784 this.initRootsList_(); | |
747 | 785 |
748 this.setListType(FileManager.ListType.DETAIL); | 786 this.setListType(FileManager.ListType.DETAIL); |
749 | 787 |
750 this.onResize_(); | 788 this.onResize_(); |
751 | 789 |
752 this.textSearchState_ = {text: '', date: new Date()}; | 790 this.textSearchState_ = {text: '', date: new Date()}; |
753 }; | 791 }; |
754 | 792 |
793 FileManager.prototype.initRootsList_ = function() { | |
794 this.rootsList_ = this.dialogDom_.querySelector('.roots-list'); | |
795 cr.ui.List.decorate(this.rootsList_); | |
796 | |
797 var self = this; | |
798 this.rootsList_.itemConstructor = function(entry) { | |
799 return self.renderRoot_(entry); | |
800 }; | |
801 | |
802 this.rootsList_.selectionModel = new cr.ui.ListSingleSelectionModel(); | |
803 this.rootsList_.selectionModel.addEventListener( | |
804 'change', this.onRootsSelectionChanged_.bind(this)); | |
805 | |
806 // TODO(dgozman): add "Add a drive" item. | |
807 this.rootsList_.dataModel = new cr.ui.ArrayDataModel(this.rootEntries_); | |
808 }; | |
809 | |
810 FileManager.prototype.updateRoots_ = function(opt_changeDirectoryTo) { | |
811 var self = this; | |
812 this.resolveRoots_(function(rootEntries) { | |
813 self.rootEntries_ = rootEntries; | |
814 | |
815 var dataModel = self.rootsList_.dataModel; | |
816 var args = [0, dataModel.length].concat(rootEntries); | |
817 dataModel.splice.apply(dataModel, args); | |
818 | |
819 self.updateRootsListSelection_(); | |
820 | |
821 if (opt_changeDirectoryTo) | |
822 self.changeDirectory(opt_changeDirectoryTo); | |
823 }); | |
824 }; | |
825 | |
755 /** | 826 /** |
756 * Get the icon type for a given Entry. | 827 * Get the icon type for a given Entry. |
757 * | 828 * |
758 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). | 829 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). |
759 * @return {string} | 830 * @return {string} |
760 */ | 831 */ |
761 FileManager.prototype.getIconType = function(entry) { | 832 FileManager.prototype.getIconType = function(entry) { |
762 if (!('cachedIconType_' in entry)) | 833 if (!('cachedIconType_' in entry)) |
763 entry.cachedIconType_ = this.computeIconType_(entry); | 834 entry.cachedIconType_ = this.computeIconType_(entry); |
764 return entry.cachedIconType_; | 835 return entry.cachedIconType_; |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1064 !isSystemDirEntry(this.currentDirEntry_)); | 1135 !isSystemDirEntry(this.currentDirEntry_)); |
1065 | 1136 |
1066 case 'delete': | 1137 case 'delete': |
1067 return (// Initialized to the point where we have a current directory | 1138 return (// Initialized to the point where we have a current directory |
1068 this.currentDirEntry_ && | 1139 this.currentDirEntry_ && |
1069 // Rename not in progress. | 1140 // Rename not in progress. |
1070 !this.renameInput_.currentEntry && | 1141 !this.renameInput_.currentEntry && |
1071 !isSystemDirEntry(this.currentDirEntry_)) && | 1142 !isSystemDirEntry(this.currentDirEntry_)) && |
1072 this.selection && | 1143 this.selection && |
1073 this.selection.totalCount > 0; | 1144 this.selection.totalCount > 0; |
1145 | |
1146 case 'newfolder': | |
1147 return this.currentDirEntry_ && | |
1148 (this.dialogType_ == 'saveas-file' || | |
1149 this.dialogType_ == 'full-page'); | |
1074 } | 1150 } |
1075 }; | 1151 }; |
1076 | 1152 |
1077 FileManager.prototype.updateCommonActionButtons_ = function() { | 1153 FileManager.prototype.updateCommonActionButtons_ = function() { |
1078 if (this.deleteButton_) | 1154 if (this.deleteButton_) |
1079 this.deleteButton_.disabled = !this.canExecute_('delete'); | 1155 this.deleteButton_.disabled = !this.canExecute_('delete'); |
1080 }; | 1156 }; |
1081 | 1157 |
1082 FileManager.prototype.setListType = function(type) { | 1158 FileManager.prototype.setListType = function(type) { |
1083 if (type && type == this.listType_) | 1159 if (type && type == this.listType_) |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1271 leadIndex); | 1347 leadIndex); |
1272 return; | 1348 return; |
1273 } | 1349 } |
1274 | 1350 |
1275 this.initiateRename_(label); | 1351 this.initiateRename_(label); |
1276 return; | 1352 return; |
1277 | 1353 |
1278 case 'delete': | 1354 case 'delete': |
1279 this.deleteEntries(this.selection.entries); | 1355 this.deleteEntries(this.selection.entries); |
1280 return; | 1356 return; |
1357 | |
1358 case 'newfolder': | |
1359 this.onNewFolderCommand_(event); | |
1360 return; | |
1281 } | 1361 } |
1282 }; | 1362 }; |
1283 | 1363 |
1284 /** | 1364 /** |
1285 * Respond to the back and forward buttons. | 1365 * Respond to the back and forward buttons. |
1286 */ | 1366 */ |
1287 FileManager.prototype.onPopState_ = function(event) { | 1367 FileManager.prototype.onPopState_ = function(event) { |
1288 // TODO(serya): We should restore selected items here. | 1368 // TODO(serya): We should restore selected items here. |
1289 if (this.rootEntries_) | 1369 if (this.rootEntries_) |
1290 this.setupCurrentDirectory_(); | 1370 this.setupCurrentDirectory_(); |
1291 }; | 1371 }; |
1292 | 1372 |
1293 FileManager.prototype.requestResize_ = function(timeout) { | 1373 FileManager.prototype.requestResize_ = function(timeout) { |
1294 var self = this; | 1374 var self = this; |
1295 setTimeout(function() { self.onResize_() }, timeout || 0); | 1375 setTimeout(function() { self.onResize_() }, timeout || 0); |
1296 }; | 1376 }; |
1297 | 1377 |
1298 /** | 1378 /** |
1299 * Resize details and thumb views to fit the new window size. | 1379 * Resize details and thumb views to fit the new window size. |
1300 */ | 1380 */ |
1301 FileManager.prototype.onResize_ = function() { | 1381 FileManager.prototype.onResize_ = function() { |
1302 this.table_.style.height = this.grid_.style.height = | 1382 this.table_.style.height = this.grid_.style.height = |
1303 this.grid_.parentNode.clientHeight + 'px'; | 1383 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 - | 1384 this.table_.list_.style.height = (this.table_.clientHeight - 1 - |
1309 this.table_.header_.clientHeight) + 'px'; | 1385 this.table_.header_.clientHeight) + 'px'; |
1310 | 1386 |
1311 if (this.listType_ == FileManager.ListType.THUMBNAIL) { | 1387 if (this.listType_ == FileManager.ListType.THUMBNAIL) { |
1312 var self = this; | 1388 var self = this; |
1313 setTimeout(function() { | 1389 setTimeout(function() { |
1314 self.grid_.columns = 0; | 1390 self.grid_.columns = 0; |
1315 self.grid_.redraw(); | 1391 self.grid_.redraw(); |
1316 }, 0); | 1392 }, 0); |
1317 } else { | 1393 } else { |
1318 this.currentList_.redraw(); | 1394 this.currentList_.redraw(); |
1319 } | 1395 } |
1396 | |
1397 this.rootsList_.style.height = | |
1398 this.rootsList_.parentNode.clientHeight + 'px'; | |
1399 this.rootsList_.redraw(); | |
1320 }; | 1400 }; |
1321 | 1401 |
1322 FileManager.prototype.resolvePath = function( | 1402 FileManager.prototype.resolvePath = function( |
1323 path, resultCallback, errorCallback) { | 1403 path, resultCallback, errorCallback) { |
1324 return util.resolvePath(this.filesystem_.root, path, resultCallback, | 1404 return util.resolvePath(this.filesystem_.root, path, resultCallback, |
1325 errorCallback); | 1405 errorCallback); |
1326 }; | 1406 }; |
1327 | 1407 |
1328 /** | 1408 /** |
1329 * Restores current directory and may be a selected item after page load (or | 1409 * 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); | 1423 this.setupPath_(this.params_.defaultPath); |
1344 } else { | 1424 } else { |
1345 this.setupDefaultPath_(); | 1425 this.setupDefaultPath_(); |
1346 } | 1426 } |
1347 }; | 1427 }; |
1348 | 1428 |
1349 FileManager.prototype.setupDefaultPath_ = function() { | 1429 FileManager.prototype.setupDefaultPath_ = function() { |
1350 // No preset given, find a good place to start. | 1430 // No preset given, find a good place to start. |
1351 // Check for removable devices, if there are none, go to Downloads. | 1431 // Check for removable devices, if there are none, go to Downloads. |
1352 var removableDirectoryEntry = this.rootEntries_.filter(function(rootEntry) { | 1432 var removableDirectoryEntry = this.rootEntries_.filter(function(rootEntry) { |
1353 return rootEntry.fullPath == REMOVABLE_DIRECTORY; | 1433 return isParentPath(REMOVABLE_DIRECTORY, rootEntry.fullPath); |
1354 })[0]; | 1434 })[0]; |
1355 if (!removableDirectoryEntry) { | 1435 this.changeDirectory( |
1356 this.changeDirectory(DOWNLOADS_DIRECTORY, CD_NO_HISTORY); | 1436 removableDirectoryEntry.fullPath || DOWNLOADS_DIRECTORY, |
SeRya
2011/11/28 10:30:55
removableDirectoryEntry may be undefined. Access t
dgozman
2011/11/28 11:45:53
Done.
| |
1357 return; | 1437 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 }; | 1438 }; |
1370 | 1439 |
1371 FileManager.prototype.setupPath_ = function(path) { | 1440 FileManager.prototype.setupPath_ = function(path) { |
1372 // Split the dirname from the basename. | 1441 // Split the dirname from the basename. |
1373 var ary = path.match(/^(?:(.*)\/)?([^\/]*)$/); | 1442 var ary = path.match(/^(?:(.*)\/)?([^\/]*)$/); |
1374 if (!ary) { | 1443 if (!ary) { |
1375 console.warn('Unable to split default path: ' + path); | 1444 console.warn('Unable to split default path: ' + path); |
1376 self.changeDirectory('/', CD_NO_HISTORY); | 1445 self.changeDirectory('/', CD_NO_HISTORY); |
1377 return; | 1446 return; |
1378 } | 1447 } |
(...skipping 16 matching lines...) Expand all Loading... | |
1395 return; | 1464 return; |
1396 } | 1465 } |
1397 | 1466 |
1398 // Leaf is an existing file, cd to its parent directory and select it. | 1467 // Leaf is an existing file, cd to its parent directory and select it. |
1399 self.changeDirectoryEntry(baseDirEntry, CD_NO_HISTORY, leafEntry.name); | 1468 self.changeDirectoryEntry(baseDirEntry, CD_NO_HISTORY, leafEntry.name); |
1400 } | 1469 } |
1401 | 1470 |
1402 function onLeafError(err) { | 1471 function onLeafError(err) { |
1403 // Set filename first so OK button will update in changeDirectoryEntry. | 1472 // Set filename first so OK button will update in changeDirectoryEntry. |
1404 self.filenameInput_.value = leafName; | 1473 self.filenameInput_.value = leafName; |
1474 self.selectDefaultPathInFilenameInput_(); | |
1405 if (err = FileError.NOT_FOUND_ERR) { | 1475 if (err = FileError.NOT_FOUND_ERR) { |
1406 // Leaf does not exist, it's just a suggested file name. | 1476 // Leaf does not exist, it's just a suggested file name. |
1407 self.changeDirectoryEntry(baseDirEntry, CD_NO_HISTORY); | 1477 self.changeDirectoryEntry(baseDirEntry, CD_NO_HISTORY); |
1408 } else { | 1478 } else { |
1409 console.log('Unexpected error resolving default leaf: ' + err); | 1479 console.log('Unexpected error resolving default leaf: ' + err); |
1410 self.changeDirectoryEntry('/', CD_NO_HISTORY); | 1480 self.changeDirectoryEntry('/', CD_NO_HISTORY); |
1411 } | 1481 } |
1412 } | 1482 } |
1413 | 1483 |
1414 self.resolvePath(path, onLeafFound, onLeafError); | 1484 self.resolvePath(path, onLeafFound, onLeafError); |
1415 } | 1485 } |
1416 | 1486 |
1417 function onBaseError(err) { | 1487 function onBaseError(err) { |
1418 // Set filename first so OK button will update in changeDirectory. | 1488 // Set filename first so OK button will update in changeDirectory. |
1419 self.filenameInput_.value = leafName; | 1489 self.filenameInput_.value = leafName; |
1490 self.selectDefaultPathInFilenameInput_(); | |
1420 console.log('Unexpected error resolving default base "' + | 1491 console.log('Unexpected error resolving default base "' + |
1421 baseName + '": ' + err); | 1492 baseName + '": ' + err); |
1422 self.changeDirectory('/', CD_NO_HISTORY); | 1493 self.changeDirectory('/', CD_NO_HISTORY); |
1423 } | 1494 } |
1424 | 1495 |
1425 if (baseName) { | 1496 if (baseName) { |
1426 this.filesystem_.root.getDirectory( | 1497 this.filesystem_.root.getDirectory( |
1427 baseName, {create: false}, onBaseFound, onBaseError); | 1498 baseName, {create: false}, onBaseFound, onBaseError); |
1428 } else { | 1499 } else { |
1429 onBaseFound(this.filesystem_.root); | 1500 onBaseFound(this.filesystem_.root); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1673 | 1744 |
1674 var icon = this.document_.createElement('div'); | 1745 var icon = this.document_.createElement('div'); |
1675 icon.className = 'detail-icon'; | 1746 icon.className = 'detail-icon'; |
1676 this.getIconType(entry); | 1747 this.getIconType(entry); |
1677 icon.setAttribute('iconType', entry.cachedIconType_); | 1748 icon.setAttribute('iconType', entry.cachedIconType_); |
1678 div.appendChild(icon); | 1749 div.appendChild(icon); |
1679 | 1750 |
1680 return div; | 1751 return div; |
1681 }; | 1752 }; |
1682 | 1753 |
1683 FileManager.prototype.getLabelForRootPath_ = function(path) { | 1754 FileManager.prototype.getLabelForRootPath_ = function(path) { |
SeRya
2011/11/28 10:30:55
Looks like meaning of the parameter has changed. N
dgozman
2011/11/28 11:45:53
Done.
| |
1684 // This hack lets us localize the top level directories. | 1755 // This hack lets us localize the top level directories. |
1685 if (path == 'Downloads') | 1756 if (path == DOWNLOADS_DIRECTORY) |
1686 return str('DOWNLOADS_DIRECTORY_LABEL'); | 1757 return str('CHROMEBOOK_DIRECTORY_LABEL'); |
1687 | 1758 |
1688 if (path == 'archive') | 1759 if (path == ARCHIVE_DIRECTORY) |
1689 return str('ARCHIVE_DIRECTORY_LABEL'); | 1760 return str('ARCHIVE_DIRECTORY_LABEL'); |
1761 if (isParentPath(ARCHIVE_DIRECTORY, path)) | |
1762 return path.substring(ARCHIVE_DIRECTORY.length + 1); | |
1690 | 1763 |
1691 if (path == 'removable') | 1764 if (path == REMOVABLE_DIRECTORY) |
1692 return str('REMOVABLE_DIRECTORY_LABEL'); | 1765 return str('REMOVABLE_DIRECTORY_LABEL'); |
1766 if (isParentPath(REMOVABLE_DIRECTORY, path)) | |
1767 return path.substring(REMOVABLE_DIRECTORY.length + 1); | |
1693 | 1768 |
1694 return path || str('ROOT_DIRECTORY_LABEL'); | 1769 return path || str('ROOT_DIRECTORY_LABEL'); |
SeRya
2011/11/28 10:30:55
path == '/', right?
dgozman
2011/11/28 11:45:53
Path may be arbitrary here. Changed to remove |pat
| |
1695 }; | 1770 }; |
1696 | 1771 |
1772 FileManager.prototype.getRootIconUrl_ = function(path, opt_small) { | |
1773 var iconUrl = opt_small ? 'images/chromebook_28x28.png' : | |
1774 'images/chromebook_24x24.png'; | |
1775 if (isParentPath(REMOVABLE_DIRECTORY, path)) | |
1776 iconUrl = 'images/filetype_device.png'; | |
1777 if (isParentPath(ARCHIVE_DIRECTORY, path)) | |
1778 iconUrl = 'images/icon_mount_archive_16x16.png'; | |
1779 return chrome.extension.getURL(iconUrl); | |
1780 }; | |
1781 | |
1782 FileManager.prototype.renderRoot_ = function(entry) { | |
1783 var li = this.document_.createElement('li'); | |
1784 li.className = 'root-item'; | |
1785 | |
1786 var icon = this.document_.createElement('img'); | |
1787 icon.setAttribute('src', this.getRootIconUrl_(entry.fullPath, false)); | |
1788 li.appendChild(icon); | |
1789 | |
1790 var div = this.document_.createElement('div'); | |
1791 div.textContent = this.getLabelForRootPath_(entry.fullPath); | |
1792 li.appendChild(div); | |
1793 | |
1794 if (isParentPath(REMOVABLE_DIRECTORY, entry.fullPath) || | |
1795 isParentPath(ARCHIVE_DIRECTORY, entry.fullPath)) { | |
1796 var spacer = this.document_.createElement('div'); | |
1797 spacer.className = 'spacer'; | |
1798 li.appendChild(spacer); | |
1799 | |
1800 var eject = this.document_.createElement('img'); | |
1801 eject.className = 'root-eject'; | |
1802 eject.setAttribute('src', chrome.extension.getURL('images/eject.png')); | |
1803 eject.addEventListener('click', this.onEjectClick_.bind(this, entry)); | |
1804 li.appendChild(eject); | |
1805 } | |
1806 | |
1807 cr.defineProperty(li, 'lead', cr.PropertyKind.BOOL_ATTR); | |
1808 cr.defineProperty(li, 'selected', cr.PropertyKind.BOOL_ATTR); | |
1809 return li; | |
1810 }; | |
1811 | |
1812 /** | |
1813 * Handler for eject button clicked. | |
1814 * @param {Entry} entry Entry to eject. | |
1815 * @param {Event} event The event. | |
1816 */ | |
1817 FileManager.prototype.onEjectClick_ = function(entry, event) { | |
1818 this.unmountRequests_.push(entry.toURL()); | |
1819 chrome.fileBrowserPrivate.removeMount(entry.fullPath); | |
1820 }; | |
1821 | |
1697 /** | 1822 /** |
1698 * Render the Name column of the detail table. | 1823 * Render the Name column of the detail table. |
1699 * | 1824 * |
1700 * Invoked by cr.ui.Table when a file needs to be rendered. | 1825 * Invoked by cr.ui.Table when a file needs to be rendered. |
1701 * | 1826 * |
1702 * @param {Entry} entry The Entry object to render. | 1827 * @param {Entry} entry The Entry object to render. |
1703 * @param {string} columnId The id of the column to be rendered. | 1828 * @param {string} columnId The id of the column to be rendered. |
1704 * @param {cr.ui.Table} table The table doing the rendering. | 1829 * @param {cr.ui.Table} table The table doing the rendering. |
1705 */ | 1830 */ |
1706 FileManager.prototype.renderName_ = function(entry, columnId, table) { | 1831 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. | 2160 // Skip the button creation. |
2036 if (!str('ENABLE_PHOTO_EDITOR')) continue; | 2161 if (!str('ENABLE_PHOTO_EDITOR')) continue; |
2037 this.galleryTask_ = task; | 2162 this.galleryTask_ = task; |
2038 } | 2163 } |
2039 } | 2164 } |
2040 this.renderTaskButton_(task); | 2165 this.renderTaskButton_(task); |
2041 } | 2166 } |
2042 | 2167 |
2043 // These are done in separate functions, as the checks require | 2168 // These are done in separate functions, as the checks require |
2044 // asynchronous function calls. | 2169 // asynchronous function calls. |
2045 this.maybeRenderUnmountTask_(selection); | |
2046 this.maybeRenderFormattingTask_(selection); | 2170 this.maybeRenderFormattingTask_(selection); |
2047 }; | 2171 }; |
2048 | 2172 |
2049 FileManager.prototype.renderTaskButton_ = function(task) { | 2173 FileManager.prototype.renderTaskButton_ = function(task) { |
2050 var button = this.document_.createElement('button'); | 2174 var button = this.document_.createElement('button'); |
2051 button.addEventListener('click', | 2175 button.addEventListener('click', |
2052 this.onTaskButtonClicked_.bind(this, task)); | 2176 this.onTaskButtonClicked_.bind(this, task)); |
2053 button.className = 'task-button'; | 2177 button.className = 'task-button'; |
2054 | 2178 |
2055 var img = this.document_.createElement('img'); | 2179 var img = this.document_.createElement('img'); |
2056 img.src = task.iconUrl; | 2180 img.src = task.iconUrl; |
2057 | 2181 |
2058 button.appendChild(img); | 2182 button.appendChild(img); |
2059 var label = this.document_.createElement('div'); | 2183 var label = this.document_.createElement('div'); |
2060 label.appendChild(this.document_.createTextNode(task.title)) | 2184 label.appendChild(this.document_.createTextNode(task.title)) |
2061 button.appendChild(label); | 2185 button.appendChild(label); |
2062 | 2186 |
2063 this.taskButtons_.appendChild(button); | 2187 this.taskButtons_.appendChild(button); |
2064 }; | 2188 }; |
2065 | 2189 |
2066 /** | 2190 /** |
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 | 2191 * Checks whether formatting task should be displayed and if the answer is |
2100 * affirmative renders it. Includes asynchronous calls, so it's splitted into | 2192 * affirmative renders it. Includes asynchronous calls, so it's splitted into |
2101 * three parts. | 2193 * three parts. |
2102 * @param {Object} selection Selected files object. | 2194 * @param {Object} selection Selected files object. |
2103 */ | 2195 */ |
2104 FileManager.prototype.maybeRenderFormattingTask_ = function(selection) { | 2196 FileManager.prototype.maybeRenderFormattingTask_ = function(selection) { |
2105 // Not to make unnecessary getMountPoints() call we doublecheck if there is | 2197 // Not to make unnecessary getMountPoints() call we doublecheck if there is |
2106 // only one selected entry. | 2198 // only one selected entry. |
2107 if (selection.entries.length != 1) | 2199 if (selection.entries.length != 1) |
2108 return; | 2200 return; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2169 chrome.fileBrowserPrivate.executeTask(task.taskId, urls); | 2261 chrome.fileBrowserPrivate.executeTask(task.taskId, urls); |
2170 }; | 2262 }; |
2171 | 2263 |
2172 /** | 2264 /** |
2173 * Event handler called when some volume was mounted or unmouted. | 2265 * Event handler called when some volume was mounted or unmouted. |
2174 */ | 2266 */ |
2175 FileManager.prototype.onMountCompleted_ = function(event) { | 2267 FileManager.prototype.onMountCompleted_ = function(event) { |
2176 var self = this; | 2268 var self = this; |
2177 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { | 2269 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { |
2178 self.mountPoints_ = mountPoints; | 2270 self.mountPoints_ = mountPoints; |
2271 var changeDirectoryTo = null; | |
2272 | |
2179 if (event.eventType == 'mount') { | 2273 if (event.eventType == 'mount') { |
2180 for (var index = 0; index < self.mountRequests_.length; ++index) { | 2274 // Mount request finished - remove it. |
2181 if (self.mountRequests_[index] == event.sourceUrl) { | 2275 var index = self.mountRequests_.indexOf(event.sourceUrl); |
2182 self.mountRequests_.splice(index, 1); | 2276 if (index != -1) { |
2183 if (event.status == 'success') { | 2277 self.mountRequests_.splice(index, 1); |
2184 self.changeDirectory(event.mountPath); | 2278 // Go to mounted directory, if request was initiated from this tab. |
2185 } else { | 2279 if (event.status == 'success') |
2186 // Report mount error. | 2280 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 } | 2281 } |
2197 } | 2282 } |
2198 | 2283 |
2284 if (event.eventType == 'unmount') { | |
2285 // Unmount request finished - remove it. | |
2286 var index = self.unmountRequests_.indexOf(event.sourceUrl); | |
2287 if (index != -1) | |
2288 self.unmountRequests_.splice(index, 1); | |
2289 } | |
2290 | |
2291 if (event.eventType == 'mount' && event.status != 'success' && | |
2292 event.mountType == 'file') { | |
2293 // Report mount error. | |
2294 var fileName = event.sourceUrl.substr( | |
2295 event.sourceUrl.lastIndexOf('/') + 1); | |
2296 self.alert.show(strf('ARCHIVE_MOUNT_FAILED', fileName, | |
2297 event.status)); | |
2298 } | |
2299 | |
2300 if (event.eventType == 'unmount' && event.status != 'success') { | |
2301 // Report unmount error. | |
2302 // TODO(dgozman): introduce string and show alert here. | |
2303 } | |
2304 | |
2199 if (event.eventType == 'unmount' && event.status == 'success' && | 2305 if (event.eventType == 'unmount' && event.status == 'success' && |
2200 self.currentDirEntry_ && | 2306 self.currentDirEntry_ && |
2201 isParentPath(event.mountPath, self.currentDirEntry_.fullPath)) { | 2307 isParentPath(event.mountPath, self.currentDirEntry_.fullPath)) { |
2202 self.changeDirectory(getParentPath(event.mountPath)); | 2308 changeDirectoryTo = getParentPath(event.mountPath); |
2203 return; | |
2204 } | 2309 } |
2205 | 2310 |
2206 var rescanDirectoryNeeded = (event.status == 'success'); | 2311 // In the case of success, roots are changed and should be rescanned. |
2207 for (var i = 0; i < mountPoints.length; i++) { | 2312 if (event.status == 'success') |
2208 if (event.sourceUrl == mountPoints[i].sourceUrl && | 2313 self.updateRoots_(changeDirectoryTo); |
2209 mountPoints[i].mountCondition != '') { | |
2210 rescanDirectoryNeeded = true; | |
2211 } | |
2212 } | |
2213 // TODO(dgozman): rescan directory, only if it contains mounted points, | |
2214 // when mounts location will be decided. | |
2215 if (rescanDirectoryNeeded) | |
2216 self.rescanDirectory_(null, 300); | |
2217 }); | 2314 }); |
2218 }; | 2315 }; |
2219 | 2316 |
2220 /** | 2317 /** |
2221 * Event handler called when some internal task should be executed. | 2318 * Event handler called when some internal task should be executed. |
2222 */ | 2319 */ |
2223 FileManager.prototype.onFileTaskExecute_ = function(id, details) { | 2320 FileManager.prototype.onFileTaskExecute_ = function(id, details) { |
2224 var urls = details.urls; | 2321 var urls = details.urls; |
2225 if (id == 'preview') { | 2322 if (id == 'preview') { |
2226 g_slideshow_data = urls; | 2323 g_slideshow_data = urls; |
2227 chrome.tabs.create({url: "slideshow.html"}); | 2324 chrome.tabs.create({url: "slideshow.html"}); |
2228 } else if (id == 'play' || id == 'enqueue') { | 2325 } else if (id == 'play' || id == 'enqueue') { |
2229 chrome.fileBrowserPrivate.viewFiles(urls, id); | 2326 chrome.fileBrowserPrivate.viewFiles(urls, id); |
2230 } else if (id == 'mount-archive') { | 2327 } else if (id == 'mount-archive') { |
2231 for (var index = 0; index < urls.length; ++index) { | 2328 for (var index = 0; index < urls.length; ++index) { |
2232 this.mountRequests_.push(urls[index]); | 2329 this.mountRequests_.push(urls[index]); |
2233 chrome.fileBrowserPrivate.addMount(urls[index], 'file', {}); | 2330 chrome.fileBrowserPrivate.addMount(urls[index], 'file', {}); |
2234 } | 2331 } |
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') { | 2332 } else if (id == 'format-device') { |
2240 this.confirm.show(str('FORMATTING_WARNING'), function() { | 2333 this.confirm.show(str('FORMATTING_WARNING'), function() { |
2241 chrome.fileBrowserPrivate.formatDevice(urls[0]); | 2334 chrome.fileBrowserPrivate.formatDevice(urls[0]); |
2242 }); | 2335 }); |
2243 } else if (id == 'gallery') { | 2336 } else if (id == 'gallery') { |
2244 // Pass to gallery all possible tasks except the gallery itself. | 2337 // Pass to gallery all possible tasks except the gallery itself. |
2245 var noGallery = []; | 2338 var noGallery = []; |
2246 for (var index = 0; index < details.task.allTasks.length; index++) { | 2339 for (var index = 0; index < details.task.allTasks.length; index++) { |
2247 var task = details.task.allTasks[index]; | 2340 var task = details.task.allTasks[index]; |
2248 if (task.taskId != this.getExtensionId_() + '|gallery') { | 2341 if (task.taskId != this.getExtensionId_() + '|gallery') { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2305 self.metadataProvider_, | 2398 self.metadataProvider_, |
2306 shareActions, | 2399 shareActions, |
2307 str); | 2400 str); |
2308 }; | 2401 }; |
2309 | 2402 |
2310 galleryFrame.src = 'js/image_editor/gallery.html'; | 2403 galleryFrame.src = 'js/image_editor/gallery.html'; |
2311 this.dialogDom_.appendChild(galleryFrame); | 2404 this.dialogDom_.appendChild(galleryFrame); |
2312 galleryFrame.focus(); | 2405 galleryFrame.focus(); |
2313 }; | 2406 }; |
2314 | 2407 |
2408 FileManager.prototype.getRootForPath_ = function(path) { | |
2409 for (var index = 0; index < this.rootEntries_.length; index++) { | |
2410 if (isParentPath(this.rootEntries_[index].fullPath, path)) { | |
2411 return index; | |
2412 } | |
2413 } | |
2414 return -1; | |
2415 }; | |
2416 | |
2315 /** | 2417 /** |
2316 * Update the breadcrumb display to reflect the current directory. | 2418 * Update the breadcrumb display to reflect the current directory. |
2317 */ | 2419 */ |
2318 FileManager.prototype.updateBreadcrumbs_ = function() { | 2420 FileManager.prototype.updateBreadcrumbs_ = function() { |
2319 var bc = this.dialogDom_.querySelector('.breadcrumbs'); | 2421 var bc = this.dialogDom_.querySelector('.breadcrumbs'); |
2320 bc.innerHTML = ''; | 2422 bc.innerHTML = ''; |
2321 | 2423 |
2322 var fullPath = this.currentDirEntry_.fullPath.replace(/\/$/, ''); | 2424 var fullPath = this.currentDirEntry_.fullPath; |
2323 var pathNames = fullPath.split('/'); | 2425 var rootIndex = this.getRootForPath_(fullPath); |
2324 var path = ''; | 2426 if (rootIndex == -1) { |
2427 console.error('Not root for: ' + fullPath); | |
2428 return; | |
2429 } | |
2430 var root = this.rootEntries_[rootIndex]; | |
2431 | |
2432 var icon = this.document_.createElement('img'); | |
2433 icon.className = 'breadcrumb-icon'; | |
2434 icon.setAttribute('src', this.getRootIconUrl_(root.fullPath, true)); | |
2435 bc.appendChild(icon); | |
2436 | |
2437 var rootPath = root.fullPath; | |
2438 var relativePath = fullPath.substring(rootPath.length); | |
2439 var pathNames = relativePath.replace(/\/$/, '').split('/'); | |
2440 if (pathNames[0] == '') | |
2441 pathNames.splice(0, 1); | |
2442 | |
2443 // We need a first breadcrumb for root, so placing last name from | |
2444 // rootPath as first name of relativePath. | |
2445 var rootPathNames = rootPath.replace(/\/$/, '').split('/'); | |
2446 pathNames.splice(0, 0, rootPathNames[rootPathNames.length - 1]); | |
2447 rootPathNames.splice(rootPathNames.length - 1, 1); | |
2448 var path = rootPathNames.join('/') + '/'; | |
2325 | 2449 |
2326 for (var i = 0; i < pathNames.length; i++) { | 2450 for (var i = 0; i < pathNames.length; i++) { |
2327 var pathName = pathNames[i]; | 2451 var pathName = pathNames[i]; |
2328 path += pathName + '/'; | 2452 path += pathName; |
2329 | 2453 |
2330 var div = this.document_.createElement('div'); | 2454 var div = this.document_.createElement('div'); |
2331 div.className = 'breadcrumb-path'; | 2455 div.className = 'breadcrumb-path'; |
2332 if (i <= 1) { | 2456 if (i == 0) { |
2333 // i == 0: root directory itself, i == 1: the files it contains. | 2457 div.textContent = this.getLabelForRootPath_(path); |
SeRya
2011/11/28 10:30:55
Remove braces.
dgozman
2011/11/28 11:45:53
Done.
| |
2334 div.textContent = this.getLabelForRootPath_(pathName); | |
2335 } else { | 2458 } else { |
2336 div.textContent = pathName; | 2459 div.textContent = pathName; |
2337 } | 2460 } |
2338 | 2461 |
2462 path = path + '/'; | |
2339 div.path = path; | 2463 div.path = path; |
2340 div.addEventListener('click', this.onBreadcrumbClick_.bind(this)); | 2464 div.addEventListener('click', this.onBreadcrumbClick_.bind(this)); |
2341 | 2465 |
2342 bc.appendChild(div); | 2466 bc.appendChild(div); |
2343 | 2467 |
2344 if (i == pathNames.length - 1) { | 2468 if (i == pathNames.length - 1) { |
2345 div.classList.add('breadcrumb-last'); | 2469 div.classList.add('breadcrumb-last'); |
2346 } else { | 2470 } else { |
2347 var spacer = this.document_.createElement('div'); | 2471 var spacer = this.document_.createElement('div'); |
2348 spacer.className = 'breadcrumb-spacer'; | 2472 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++) { | 2552 for (var i = 0; i < this.dataModel_.length; i++) { |
2429 if (this.dataModel_.item(i).name == name) { | 2553 if (this.dataModel_.item(i).name == name) { |
2430 this.currentList_.selectionModel.selectedIndex = i; | 2554 this.currentList_.selectionModel.selectedIndex = i; |
2431 this.currentList_.scrollIndexIntoView(i); | 2555 this.currentList_.scrollIndexIntoView(i); |
2432 this.currentList_.focus(); | 2556 this.currentList_.focus(); |
2433 return; | 2557 return; |
2434 } | 2558 } |
2435 } | 2559 } |
2436 }; | 2560 }; |
2437 | 2561 |
2562 FileManager.prototype.updateRootsListSelection_ = function() { | |
2563 if (!this.currentDirEntry_) return; | |
2564 var index = this.getRootForPath_(this.currentDirEntry_.fullPath); | |
2565 if (index == -1) { | |
2566 this.rootsList_.selectionModel.selectedIndex = 0; | |
2567 } else { | |
2568 if (this.rootsList_.selectionModel.selectedIndex != index) | |
2569 this.rootsList_.selectionModel.selectedIndex = index; | |
2570 } | |
2571 }; | |
2572 | |
2438 /** | 2573 /** |
2439 * Add the file/directory with given name to the current selection. | 2574 * Add the file/directory with given name to the current selection. |
2440 * | 2575 * |
2441 * @param {string} name The name of the entry to select. | 2576 * @param {string} name The name of the entry to select. |
2442 * @return {boolean} Whether entry exists. | 2577 * @return {boolean} Whether entry exists. |
2443 */ | 2578 */ |
2444 FileManager.prototype.addItemToSelection = function(name) { | 2579 FileManager.prototype.addItemToSelection = function(name) { |
2445 var entryExists = false; | 2580 var entryExists = false; |
2446 for (var i = 0; i < this.dataModel_.length; i++) { | 2581 for (var i = 0; i < this.dataModel_.length; i++) { |
2447 if (this.dataModel_.item(i).name == name) { | 2582 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, | 2678 FileManager.prototype.changeDirectoryEntry = function(dirEntry, |
2544 opt_saveHistory, | 2679 opt_saveHistory, |
2545 opt_selectedEntry, | 2680 opt_selectedEntry, |
2546 opt_callback) { | 2681 opt_callback) { |
2547 if (typeof opt_saveHistory == 'undefined') { | 2682 if (typeof opt_saveHistory == 'undefined') { |
2548 opt_saveHistory = true; | 2683 opt_saveHistory = true; |
2549 } else { | 2684 } else { |
2550 opt_saveHistory = !!opt_saveHistory; | 2685 opt_saveHistory = !!opt_saveHistory; |
2551 } | 2686 } |
2552 | 2687 |
2553 var location = '#' + encodeURI(dirEntry.fullPath); | 2688 // Some directories are above roots, so we instead show the first root. |
2689 // There may be request to change directory above the roots. For example, | |
2690 // when usb-dirve is removed, we try to change to the parent directory, | |
2691 // which is REMOVABLE_DIRECTORY. | |
2692 if (!dirEntry || dirEntry.fullPath == '/' || | |
2693 dirEntry.fullPath == REMOVABLE_DIRECTORY || | |
2694 dirEntry.fullPath == ARCHIVE_DIRECTORY) { | |
2695 dirEntry = this.rootEntries_[0] || dirEntry; | |
2696 } | |
2697 | |
2698 /* var location = '#' + encodeURI(dirEntry.fullPath); | |
SeRya
2011/11/28 10:30:55
Uncomment.
dgozman
2011/11/28 11:45:53
Done.
| |
2554 if (opt_saveHistory) { | 2699 if (opt_saveHistory) { |
2555 history.pushState(undefined, dirEntry.fullPath, location); | 2700 history.pushState(undefined, dirEntry.fullPath, location); |
2556 } else if (window.location.hash != location) { | 2701 } else if (window.location.hash != location) { |
2557 // If the user typed URL manually that is not canonical it would be fixed | 2702 // 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 | 2703 // here. However it seems history.replaceState doesn't work properly |
2559 // with rewritable URLs (while does with history.pushState). It changes | 2704 // with rewritable URLs (while does with history.pushState). It changes |
2560 // window.location but doesn't change content of the ombibox. | 2705 // window.location but doesn't change content of the ombibox. |
2561 history.replaceState(undefined, dirEntry.fullPath, location); | 2706 history.replaceState(undefined, dirEntry.fullPath, location); |
2562 } | 2707 } |
2563 | 2708 */ |
2564 if (this.currentDirEntry_ && | 2709 if (this.currentDirEntry_ && |
2565 this.currentDirEntry_.fullPath == dirEntry.fullPath) { | 2710 this.currentDirEntry_.fullPath == dirEntry.fullPath) { |
2566 // Directory didn't actually change. | 2711 // Directory didn't actually change. |
2567 if (opt_selectedEntry) | 2712 if (opt_selectedEntry) |
2568 this.selectEntry(opt_selectedEntry); | 2713 this.selectEntry(opt_selectedEntry); |
2569 return; | 2714 return; |
2570 } | 2715 } |
2571 | 2716 |
2572 var e = new cr.Event('directory-changed'); | 2717 var e = new cr.Event('directory-changed'); |
2573 e.previousDirEntry = this.currentDirEntry_; | 2718 e.previousDirEntry = this.currentDirEntry_; |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2779 // then the default action of this click event fires and toggles the | 2924 // then the default action of this click event fires and toggles the |
2780 // checkbox back off. | 2925 // checkbox back off. |
2781 // | 2926 // |
2782 // Since we're going to force checkboxes into the correct state for any | 2927 // 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 | 2928 // multi-selection, we can prevent this shift click from toggling the |
2784 // checkbox and avoid the trouble. | 2929 // checkbox and avoid the trouble. |
2785 event.preventDefault(); | 2930 event.preventDefault(); |
2786 } | 2931 } |
2787 }; | 2932 }; |
2788 | 2933 |
2934 FileManager.prototype.onRootsSelectionChanged_ = function(event) { | |
2935 var root = this.rootEntries_[this.rootsList_.selectionModel.selectedIndex]; | |
2936 this.changeDirectoryEntry(root); | |
2937 }; | |
2938 | |
2939 FileManager.prototype.selectDefaultPathInFilenameInput_ = function() { | |
2940 var input = this.filenameInput_; | |
2941 input.focus(); | |
2942 var selectionEnd = input.value.lastIndexOf('.'); | |
2943 if (selectionEnd == -1) { | |
2944 input.select(); | |
2945 } else { | |
2946 input.selectionStart = 0; | |
2947 input.selectionEnd = selectionEnd; | |
2948 } | |
2949 // Clear, so we never do this again. | |
2950 this.params_.defaultPath = ''; | |
2951 }; | |
2952 | |
2789 /** | 2953 /** |
2790 * Update the UI when the selection model changes. | 2954 * Update the UI when the selection model changes. |
2791 * | 2955 * |
2792 * @param {cr.Event} event The change event. | 2956 * @param {cr.Event} event The change event. |
2793 */ | 2957 */ |
2794 FileManager.prototype.onSelectionChanged_ = function(event) { | 2958 FileManager.prototype.onSelectionChanged_ = function(event) { |
2795 this.summarizeSelection_(); | 2959 this.summarizeSelection_(); |
2796 | 2960 |
2797 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { | 2961 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { |
2798 // If this is a save-as dialog, copy the selected file into the filename | 2962 // If this is a save-as dialog, copy the selected file into the filename |
2799 // input text box. | 2963 // input text box. |
2800 | 2964 |
2801 if (this.selection && | 2965 if (this.selection && |
2802 this.selection.totalCount == 1 && | 2966 this.selection.totalCount == 1 && |
2803 this.selection.entries[0].isFile) | 2967 this.selection.entries[0].isFile && |
2968 this.filenameInput_.value != this.selection.entries[0].name) { | |
2804 this.filenameInput_.value = this.selection.entries[0].name; | 2969 this.filenameInput_.value = this.selection.entries[0].name; |
2970 if (this.params_.defaultPath == this.selection.entries[0].fullPath) | |
2971 this.selectDefaultPathInFilenameInput_(); | |
2972 } | |
2805 } | 2973 } |
2806 | 2974 |
2807 this.updateOkButton_(); | 2975 this.updateOkButton_(); |
2808 | 2976 |
2809 var self = this; | 2977 var self = this; |
2810 setTimeout(function() { self.onSelectionChangeComplete_(event) }, 0); | 2978 setTimeout(function() { self.onSelectionChangeComplete_(event) }, 0); |
2811 }; | 2979 }; |
2812 | 2980 |
2813 /** | 2981 /** |
2814 * Handle selection change related tasks that won't run properly during | 2982 * 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. | 3115 * Update the UI when the current directory changes. |
2948 * | 3116 * |
2949 * @param {cr.Event} event The directory-changed event. | 3117 * @param {cr.Event} event The directory-changed event. |
2950 */ | 3118 */ |
2951 FileManager.prototype.onDirectoryChanged_ = function(event) { | 3119 FileManager.prototype.onDirectoryChanged_ = function(event) { |
2952 this.updateCommands_(); | 3120 this.updateCommands_(); |
2953 this.updateOkButton_(); | 3121 this.updateOkButton_(); |
2954 | 3122 |
2955 this.checkFreeSpace_(this.currentDirEntry_.fullPath); | 3123 this.checkFreeSpace_(this.currentDirEntry_.fullPath); |
2956 | 3124 |
2957 // New folder should never be enabled in the root or media/ directories. | 3125 // TODO(dgozman): title may be better than this. |
2958 this.newFolderButton_.disabled = isSystemDirEntry(this.currentDirEntry_); | |
2959 | |
2960 this.document_.title = this.currentDirEntry_.fullPath; | 3126 this.document_.title = this.currentDirEntry_.fullPath; |
2961 | 3127 |
2962 var self = this; | 3128 var self = this; |
2963 | 3129 |
2964 if (this.subscribedOnDirectoryChanges_) { | 3130 if (this.subscribedOnDirectoryChanges_) { |
2965 chrome.fileBrowserPrivate.removeFileWatch(event.previousDirEntry.toURL(), | 3131 chrome.fileBrowserPrivate.removeFileWatch(event.previousDirEntry.toURL(), |
2966 function(result) { | 3132 function(result) { |
2967 if (!result) { | 3133 if (!result) { |
2968 console.log('Failed to remove file watch'); | 3134 console.log('Failed to remove file watch'); |
2969 } | 3135 } |
(...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 | 3211 // 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 | 3212 // when a click is eligible to trigger a rename. Can be null, or |
3047 // an object with 'path' and 'date' properties. | 3213 // an object with 'path' and 'date' properties. |
3048 this.lastLabelClick_ = null; | 3214 this.lastLabelClick_ = null; |
3049 | 3215 |
3050 // Clear the table first. | 3216 // Clear the table first. |
3051 this.dataModel_.splice(0, this.dataModel_.length); | 3217 this.dataModel_.splice(0, this.dataModel_.length); |
3052 this.currentList_.selectionModel.clear(); | 3218 this.currentList_.selectionModel.clear(); |
3053 | 3219 |
3054 this.updateBreadcrumbs_(); | 3220 this.updateBreadcrumbs_(); |
3221 this.updateRootsListSelection_(); | |
3055 | 3222 |
3056 if (this.currentDirEntry_.fullPath != '/') { | 3223 // Add current request to pending result list |
3057 // Add current request to pending result list | 3224 this.pendingRescanQueue_.push({ |
3058 this.pendingRescanQueue_.push({ | 3225 onSuccess:opt_callback, |
3059 onSuccess:opt_callback, | 3226 onError:opt_onError |
3060 onError:opt_onError | 3227 }); |
3061 }); | |
3062 | 3228 |
3063 if (this.rescanRunning_) | 3229 if (this.rescanRunning_) |
3064 return; | 3230 return; |
3065 | 3231 |
3066 this.rescanRunning_ = true; | 3232 this.rescanRunning_ = true; |
3067 | 3233 |
3068 // The current list of callbacks is saved and reset. Subsequent | 3234 // The current list of callbacks is saved and reset. Subsequent |
3069 // calls to rescanDirectory_ while we're still pending will be | 3235 // calls to rescanDirectory_ while we're still pending will be |
3070 // saved and will cause an additional rescan to happen after a delay. | 3236 // saved and will cause an additional rescan to happen after a delay. |
3071 var callbacks = this.pendingRescanQueue_; | 3237 var callbacks = this.pendingRescanQueue_; |
3072 | 3238 |
3073 this.pendingRescanQueue_ = []; | 3239 this.pendingRescanQueue_ = []; |
3074 | 3240 |
3075 var self = this; | 3241 var self = this; |
3076 var reader; | 3242 var reader; |
3077 | 3243 |
3078 function onError() { | 3244 function onError() { |
3245 if (self.pendingRescanQueue_.length > 0) { | |
3246 setTimeout(self.rescanDirectory_.bind(self), | |
3247 SIMULTANEOUS_RESCAN_INTERVAL); | |
3248 } | |
3249 | |
3250 self.rescanRunning_ = false; | |
3251 | |
3252 for (var i= 0; i < callbacks.length; i++) { | |
3253 if (callbacks[i].onError) | |
3254 try { | |
3255 callbacks[i].onError(); | |
3256 } catch (ex) { | |
3257 console.error('Caught exception while notifying about error: ' + | |
3258 name, ex); | |
3259 } | |
3260 } | |
3261 } | |
3262 | |
3263 function onReadSome(entries) { | |
3264 if (entries.length == 0) { | |
3265 metrics.recordTime('DirectoryScan'); | |
3266 if (self.currentDirEntry_.fullPath == DOWNLOADS_DIRECTORY) { | |
3267 metrics.reportCount("DownloadsCount", self.dataModel_.length); | |
3268 } | |
3269 | |
3079 if (self.pendingRescanQueue_.length > 0) { | 3270 if (self.pendingRescanQueue_.length > 0) { |
3080 setTimeout(self.rescanDirectory_.bind(self), | 3271 setTimeout(self.rescanDirectory_.bind(self), |
3081 SIMULTANEOUS_RESCAN_INTERVAL); | 3272 SIMULTANEOUS_RESCAN_INTERVAL); |
3082 } | 3273 } |
3083 | 3274 |
3084 self.rescanRunning_ = false; | 3275 self.rescanRunning_ = false; |
3085 | |
3086 for (var i= 0; i < callbacks.length; i++) { | 3276 for (var i= 0; i < callbacks.length; i++) { |
3087 if (callbacks[i].onError) | 3277 if (callbacks[i].onSuccess) |
3088 try { | 3278 try { |
3089 callbacks[i].onError(); | 3279 callbacks[i].onSuccess(); |
3090 } catch (ex) { | 3280 } catch (ex) { |
3091 console.error('Caught exception while notifying about error: ' + | 3281 console.error('Caught exception while notifying about error: ' + |
3092 name, ex); | 3282 name, ex); |
3093 } | 3283 } |
3094 } | 3284 } |
3285 | |
3286 return; | |
3095 } | 3287 } |
3096 | 3288 |
3097 function onReadSome(entries) { | 3289 // Splice takes the to-be-spliced-in array as individual parameters, |
3098 if (entries.length == 0) { | 3290 // rather than as an array, so we need to perform some acrobatics... |
3099 metrics.recordTime('DirectoryScan'); | 3291 var spliceArgs = [].slice.call(entries); |
3100 if (self.currentDirEntry_.fullPath == DOWNLOADS_DIRECTORY) { | |
3101 metrics.reportCount("DownloadsCount", self.dataModel_.length); | |
3102 } | |
3103 | 3292 |
3104 if (self.pendingRescanQueue_.length > 0) { | 3293 // Hide files that start with a dot ('.'). |
3105 setTimeout(self.rescanDirectory_.bind(self), | 3294 // TODO(rginda): User should be able to override this. Support for other |
3106 SIMULTANEOUS_RESCAN_INTERVAL); | 3295 // commonly hidden patterns might be nice too. |
3107 } | 3296 if (self.filterFiles_) { |
3297 spliceArgs = spliceArgs.filter(function(e) { | |
3298 return e.name.substr(0, 1) != '.'; | |
3299 }); | |
3300 } | |
3108 | 3301 |
3109 self.rescanRunning_ = false; | 3302 spliceArgs.unshift(0, 0); // index, deleteCount |
3110 for (var i= 0; i < callbacks.length; i++) { | 3303 self.dataModel_.splice.apply(self.dataModel_, spliceArgs); |
3111 if (callbacks[i].onSuccess) | |
3112 try { | |
3113 callbacks[i].onSuccess(); | |
3114 } catch (ex) { | |
3115 console.error('Caught exception while notifying about error: ' + | |
3116 name, ex); | |
3117 } | |
3118 } | |
3119 | 3304 |
3120 return; | 3305 // Keep reading until entries.length is 0. |
3121 } | 3306 reader.readEntries(onReadSome, onError); |
3307 }; | |
3122 | 3308 |
3123 // Splice takes the to-be-spliced-in array as individual parameters, | 3309 metrics.startInterval('DirectoryScan'); |
3124 // rather than as an array, so we need to perform some acrobatics... | |
3125 var spliceArgs = [].slice.call(entries); | |
3126 | 3310 |
3127 // Hide files that start with a dot ('.'). | 3311 // If not the root directory, just read the contents. |
3128 // TODO(rginda): User should be able to override this. Support for other | 3312 reader = this.currentDirEntry_.createReader(); |
3129 // commonly hidden patterns might be nice too. | 3313 reader.readEntries(onReadSome, onError); |
3130 if (self.filterFiles_) { | |
3131 spliceArgs = spliceArgs.filter(function(e) { | |
3132 return e.name.substr(0, 1) != '.'; | |
3133 }); | |
3134 } | |
3135 | |
3136 spliceArgs.unshift(0, 0); // index, deleteCount | |
3137 self.dataModel_.splice.apply(self.dataModel_, spliceArgs); | |
3138 | |
3139 metrics.startInterval('DirectoryScan'); | |
3140 | |
3141 // Keep reading until entries.length is 0. | |
3142 reader.readEntries(onReadSome, onError); | |
3143 }; | |
3144 | |
3145 // If not the root directory, just read the contents. | |
3146 reader = this.currentDirEntry_.createReader(); | |
3147 reader.readEntries(onReadSome, onError); | |
3148 return; | |
3149 } | |
3150 | |
3151 // Otherwise, use the provided list of root subdirectories, since the | |
3152 // real local filesystem root directory (the one we use outside the | |
3153 // harness) can't be enumerated yet. | |
3154 var spliceArgs = [].slice.call(this.rootEntries_); | |
3155 spliceArgs.unshift(0, 0); // index, deleteCount | |
3156 this.dataModel_.splice.apply(this.dataModel_, spliceArgs); | |
3157 | |
3158 if (opt_callback) | |
3159 opt_callback(); | |
3160 }; | 3314 }; |
3161 | 3315 |
3162 FileManager.prototype.findListItem_ = function(event) { | 3316 FileManager.prototype.findListItem_ = function(event) { |
3163 var node = event.srcElement; | 3317 var node = event.srcElement; |
3164 while (node) { | 3318 while (node) { |
3165 if (node.tagName == 'LI') | 3319 if (node.tagName == 'LI') |
3166 break; | 3320 break; |
3167 node = node.parentNode; | 3321 node = node.parentNode; |
3168 } | 3322 } |
3169 | 3323 |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3393 var selectionEnd = input.value.lastIndexOf('.'); | 3547 var selectionEnd = input.value.lastIndexOf('.'); |
3394 if (selectionEnd == -1) { | 3548 if (selectionEnd == -1) { |
3395 input.select(); | 3549 input.select(); |
3396 } else { | 3550 } else { |
3397 input.selectionStart = 0; | 3551 input.selectionStart = 0; |
3398 input.selectionEnd = selectionEnd; | 3552 input.selectionEnd = selectionEnd; |
3399 } | 3553 } |
3400 }, 0); | 3554 }, 0); |
3401 }; | 3555 }; |
3402 | 3556 |
3403 FileManager.prototype.onNewFolderButtonClick_ = function(event) { | 3557 FileManager.prototype.onToggleSidebar_ = function(event) { |
3558 if (this.dialogContainer_.hasAttribute('sidebar')) { | |
SeRya
2011/11/28 10:30:55
Now we have 3 attributes that does essentially the
dgozman
2011/11/28 11:45:53
I've filed a bug: crosbug.com/23455.
| |
3559 this.dialogContainer_.removeAttribute('sidebar'); | |
3560 } else { | |
3561 this.dialogContainer_.setAttribute('sidebar', 'sidebar'); | |
3562 } | |
3563 setTimeout(this.onResize_.bind(this), 300); | |
3564 }; | |
3565 | |
3566 FileManager.prototype.onNewFolderCommand_ = function(event) { | |
3404 var self = this; | 3567 var self = this; |
3405 | 3568 |
3406 function onNameSelected(name) { | 3569 function onNameSelected(name) { |
3407 var valid = self.validateFileName_(name, function() { | 3570 var valid = self.validateFileName_(name, function() { |
3408 promptForName(name); | 3571 promptForName(name); |
3409 }); | 3572 }); |
3410 | 3573 |
3411 if (!valid) { | 3574 if (!valid) { |
3412 // Validation failed. User will be prompted for a new name after they | 3575 // Validation failed. User will be prompted for a new name after they |
3413 // dismiss the validation error dialog. | 3576 // dismiss the validation error dialog. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3522 this.dialogType_ != FileManager.SELECT_FOLDER) { | 3685 this.dialogType_ != FileManager.SELECT_FOLDER) { |
3523 event.preventDefault(); | 3686 event.preventDefault(); |
3524 this.onDirectoryAction(this.selection.entries[0]); | 3687 this.onDirectoryAction(this.selection.entries[0]); |
3525 } else if (!this.okButton_.disabled) { | 3688 } else if (!this.okButton_.disabled) { |
3526 event.preventDefault(); | 3689 event.preventDefault(); |
3527 this.onOk_(); | 3690 this.onOk_(); |
3528 } | 3691 } |
3529 break; | 3692 break; |
3530 | 3693 |
3531 case 32: // Ctrl-Space => New Folder. | 3694 case 32: // Ctrl-Space => New Folder. |
3532 if (this.newFolderButton_.style.display != 'none' && event.ctrlKey) { | 3695 if ((this.dialogType_ == 'saveas-file' || |
3696 this.dialogType_ == 'full-page') && event.ctrlKey) { | |
3533 event.preventDefault(); | 3697 event.preventDefault(); |
3534 this.onNewFolderButtonClick_(); | 3698 this.onNewFolderCommand_(); |
3535 } | 3699 } |
3536 break; | 3700 break; |
3537 | 3701 |
3538 case 88: // Ctrl-X => Cut. | 3702 case 88: // Ctrl-X => Cut. |
3539 this.updateCommands_(); | 3703 this.updateCommands_(); |
3540 if (!this.commands_['cut'].disabled) { | 3704 if (!this.commands_['cut'].disabled) { |
3541 event.preventDefault(); | 3705 event.preventDefault(); |
3542 this.commands_['cut'].execute(); | 3706 this.commands_['cut'].execute(); |
3543 } | 3707 } |
3544 break; | 3708 break; |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3853 }); | 4017 }); |
3854 }, onError); | 4018 }, onError); |
3855 | 4019 |
3856 function onError(err) { | 4020 function onError(err) { |
3857 console.log('Error while checking free space: ' + err); | 4021 console.log('Error while checking free space: ' + err); |
3858 setTimeout(doCheck, 1000 * 60); | 4022 setTimeout(doCheck, 1000 * 60); |
3859 } | 4023 } |
3860 } | 4024 } |
3861 } | 4025 } |
3862 })(); | 4026 })(); |
OLD | NEW |