Chromium Code Reviews| 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 |