OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // 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 | 7 |
8 /** | 8 /** |
9 * FileManager constructor. | 9 * FileManager constructor. |
10 * | 10 * |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
547 chrome.fileBrowserPrivate.onMountCompleted.addListener( | 547 chrome.fileBrowserPrivate.onMountCompleted.addListener( |
548 this.onMountCompleted_.bind(this)); | 548 this.onMountCompleted_.bind(this)); |
549 | 549 |
550 chrome.fileBrowserPrivate.onFileChanged.addListener( | 550 chrome.fileBrowserPrivate.onFileChanged.addListener( |
551 this.onFileChanged_.bind(this)); | 551 this.onFileChanged_.bind(this)); |
552 | 552 |
553 // The list of callbacks to be invoked during the directory rescan after | 553 // The list of callbacks to be invoked during the directory rescan after |
554 // all paste tasks are complete. | 554 // all paste tasks are complete. |
555 this.pasteSuccessCallbacks_ = []; | 555 this.pasteSuccessCallbacks_ = []; |
556 | 556 |
557 this.setupCurrentDirectory_(); | 557 var path = this.getPathFromUrlOrParams_(); |
558 if (path && | |
559 DirectoryModel.getRootType(path) == DirectoryModel.RootType.GDATA) { | |
560 // We are opening on a GData path. Mount GData and show | |
561 // "Loading Google Docs" message until the directory content loads. | |
562 this.dialogContainer_.setAttribute('unmounted', true); | |
563 this.initGData_(true /* dirChanged */); | |
564 // This is a one-time handler (will be nulled out on the first call). | |
565 this.setupCurrentDirectoryPostponed_ = function(event) { | |
566 this.directoryModel_.removeEventListener('directory-changed', | |
567 this.setupCurrentDirectoryPostponed_); | |
568 this.setupCurrentDirectoryPostponed_ = null; | |
569 if (event) // If called as an event handler just exit silently. | |
570 return; | |
571 this.setupCurrentDirectory_(false /* blankWhileOpeningAFile */); | |
572 }.bind(this); | |
573 this.directoryModel_.addEventListener('directory-changed', | |
574 this.setupCurrentDirectoryPostponed_); | |
575 } else { | |
576 this.setupCurrentDirectory_(true /* blankWhileOpeningAFile */); | |
577 } | |
558 | 578 |
559 this.summarizeSelection_(); | 579 this.summarizeSelection_(); |
560 | 580 |
561 var sortField = | 581 var sortField = |
562 window.localStorage['sort-field-' + this.dialogType_] || 'cachedMtime_'; | 582 window.localStorage['sort-field-' + this.dialogType_] || 'cachedMtime_'; |
563 var sortDirection = | 583 var sortDirection = |
564 window.localStorage['sort-direction-' + this.dialogType_] || 'desc'; | 584 window.localStorage['sort-direction-' + this.dialogType_] || 'desc'; |
565 this.directoryModel_.fileList.sort(sortField, sortDirection); | 585 this.directoryModel_.fileList.sort(sortField, sortDirection); |
566 | 586 |
567 this.refocus(); | 587 this.refocus(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
630 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input'); | 650 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input'); |
631 this.taskItems_ = this.dialogDom_.querySelector('.tasks'); | 651 this.taskItems_ = this.dialogDom_.querySelector('.tasks'); |
632 this.okButton_ = this.dialogDom_.querySelector('.ok'); | 652 this.okButton_ = this.dialogDom_.querySelector('.ok'); |
633 this.cancelButton_ = this.dialogDom_.querySelector('.cancel'); | 653 this.cancelButton_ = this.dialogDom_.querySelector('.cancel'); |
634 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button'); | 654 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button'); |
635 this.table_ = this.dialogDom_.querySelector('.detail-table'); | 655 this.table_ = this.dialogDom_.querySelector('.detail-table'); |
636 this.grid_ = this.dialogDom_.querySelector('.thumbnail-grid'); | 656 this.grid_ = this.dialogDom_.querySelector('.thumbnail-grid'); |
637 this.spinner_ = this.dialogDom_.querySelector('.spinner'); | 657 this.spinner_ = this.dialogDom_.querySelector('.spinner'); |
638 this.showSpinner_(false); | 658 this.showSpinner_(false); |
639 this.butter_ = this.dialogDom_.querySelector('.butter-bar'); | 659 this.butter_ = this.dialogDom_.querySelector('.butter-bar'); |
660 this.unmountedPanel_ = this.dialogDom_.querySelector('.unmounted-panel'); | |
640 | 661 |
641 cr.ui.Table.decorate(this.table_); | 662 cr.ui.Table.decorate(this.table_); |
642 cr.ui.Grid.decorate(this.grid_); | 663 cr.ui.Grid.decorate(this.grid_); |
643 | 664 |
644 this.downloadsWarning_ = | 665 this.downloadsWarning_ = |
645 this.dialogDom_.querySelector('.downloads-warning'); | 666 this.dialogDom_.querySelector('.downloads-warning'); |
646 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); | 667 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); |
647 this.downloadsWarning_.lastElementChild.innerHTML = html; | 668 this.downloadsWarning_.lastElementChild.innerHTML = html; |
648 var link = this.downloadsWarning_.querySelector('a'); | 669 var link = this.downloadsWarning_.querySelector('a'); |
649 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this)); | 670 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this)); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
795 this.rootsList_.itemConstructor = function(entry) { | 816 this.rootsList_.itemConstructor = function(entry) { |
796 return self.renderRoot_(entry); | 817 return self.renderRoot_(entry); |
797 }; | 818 }; |
798 | 819 |
799 this.rootsList_.selectionModel = this.directoryModel_.rootsListSelection; | 820 this.rootsList_.selectionModel = this.directoryModel_.rootsListSelection; |
800 | 821 |
801 // TODO(dgozman): add "Add a drive" item. | 822 // TODO(dgozman): add "Add a drive" item. |
802 this.rootsList_.dataModel = this.directoryModel_.rootsList; | 823 this.rootsList_.dataModel = this.directoryModel_.rootsList; |
803 this.directoryModel_.updateRoots(function() { | 824 this.directoryModel_.updateRoots(function() { |
804 self.rootsList_.endBatchUpdates(); | 825 self.rootsList_.endBatchUpdates(); |
805 }); | 826 }, false); |
806 }; | |
807 | |
808 FileManager.prototype.initGData_ = function() { | |
809 metrics.startInterval('Load.GData'); | |
810 chrome.fileBrowserPrivate.addMount('', 'gdata', {}); | |
811 if (this.gdataMountTimer_) { | |
812 clearTimeout(this.gdataMountTimer_); | |
813 } | |
814 this.gdataMountTimer_ = setTimeout(function() { | |
815 this.gdataMountTimer_ = null; | |
816 if (this.isOnGData()) { | |
817 // TODO(kaznacheev): show the message in the file list space. | |
818 this.alert.show('Could not connect to GData'); | |
819 } | |
820 }.bind(this), 10 * 1000); | |
821 }; | 827 }; |
822 | 828 |
823 /** | 829 /** |
830 * @param {boolean} dirChanged True if we just changed to GData directory, | |
831 * False if "Retry" button clicked. | |
832 */ | |
833 FileManager.prototype.initGData_ = function(dirChanged) { | |
834 this.initGDataUnmountedPanel_(); | |
835 | |
836 this.unmountedPanel_.removeAttribute('error'); | |
837 if (dirChanged) { | |
838 // When changing to GData directory we want to see a clear panel. | |
839 this.unmountedPanel_.removeAttribute('retry'); | |
840 if (this.gdataLoadingTimer_ ) { // Show immediately if already loading. | |
841 this.unmountedPanel_.setAttribute('loading', true); | |
842 } else { | |
843 this.unmountedPanel_.removeAttribute('loading'); | |
844 setTimeout(function() { | |
845 if (this.gdataLoadingTimer_) { // Still loading. | |
846 this.unmountedPanel_.setAttribute('loading', true); | |
847 } | |
848 }.bind(this), 500); | |
849 } | |
850 } else { | |
851 // When retrying we do not hide "Retry" and "Learn more". | |
852 this.unmountedPanel_.setAttribute('loading', true); | |
853 } | |
854 | |
855 // If the user changed to another directory and then back to GData we | |
856 // re-enter this method while the timer is still active. In this case | |
857 // we only update the UI but do not request the mount again. | |
858 if (this.gdataLoadingTimer_) | |
859 return; | |
860 | |
861 metrics.startInterval('Load.GData'); | |
862 chrome.fileBrowserPrivate.addMount('', 'gdata', {}); | |
863 | |
864 // This timer could fire before the mount succeeds. We will silently | |
865 // replace the error message with the correct directory contents. | |
866 this.gdataLoadingTimer_ = setTimeout(function() { | |
867 this.gdataLoadingTimer_ = null; | |
868 this.onGDataUnreachable_('GData load timeout'); | |
869 }.bind(this), | |
870 10 * 1000) ; | |
871 }; | |
872 | |
873 FileManager.prototype.clearGDataLoadingTimer_ = function(message) { | |
874 if (this.gdataLoadingTimer_) { | |
875 clearTimeout(this.gdataLoadingTimer_); | |
876 this.gdataLoadingTimer_ = null; | |
877 } | |
878 }; | |
879 | |
880 FileManager.prototype.onGDataUnreachable_ = function(message) { | |
881 console.warn(message); | |
882 if (this.isOnGData()) { | |
883 this.unmountedPanel_.removeAttribute('loading'); | |
884 this.unmountedPanel_.setAttribute('error', true); | |
885 this.unmountedPanel_.setAttribute('retry', true); | |
886 } | |
887 }; | |
888 | |
889 FileManager.prototype.initGDataUnmountedPanel_ = function() { | |
890 if (this.unmountedPanel_.firstElementChild) | |
891 return; | |
892 | |
893 var loading = this.document_.createElement('div'); | |
894 loading.className = 'gdata loading'; | |
895 loading.textContent = strf('GDATA_LOADING', str('GDATA_PRODUCT_NAME')); | |
896 this.unmountedPanel_.appendChild(loading); | |
897 | |
898 var error = this.document_.createElement('div'); | |
899 error.className = 'gdata error'; | |
900 error.textContent = strf('GDATA_CANNOT_REACH', str('GDATA_PRODUCT_NAME')); | |
901 this.unmountedPanel_.appendChild(error); | |
902 | |
903 var retry = this.document_.createElement('button'); | |
904 retry.className = 'gdata retry'; | |
905 retry.textContent = str('GDATA_RETRY'); | |
906 retry.onclick = this.initGData_.bind(this, false /* retry */); | |
907 this.unmountedPanel_.appendChild(retry); | |
908 | |
909 var learnMore = this.document_.createElement('div'); | |
910 learnMore.className = 'gdata learn-more'; | |
911 this.unmountedPanel_.appendChild(learnMore); | |
912 | |
913 var learnMoreLink = this.document_.createElement('a'); | |
914 learnMoreLink.textContent = str('GDATA_LEARN_MORE'); | |
915 learnMoreLink.href = 'javascript://'; // TODO: Set a proper link URL. | |
916 learnMoreLink.className = 'gdata learn-more'; | |
917 learnMore.appendChild(learnMoreLink); | |
918 }; | |
919 | |
920 /** | |
824 * Get the icon type for a given Entry. | 921 * Get the icon type for a given Entry. |
825 * | 922 * |
826 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). | 923 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). |
827 * @return {string} | 924 * @return {string} |
828 */ | 925 */ |
829 FileManager.prototype.getIconType = function(entry) { | 926 FileManager.prototype.getIconType = function(entry) { |
830 if (!('cachedIconType_' in entry)) | 927 if (!('cachedIconType_' in entry)) |
831 entry.cachedIconType_ = this.computeIconType_(entry); | 928 entry.cachedIconType_ = this.computeIconType_(entry); |
832 return entry.cachedIconType_; | 929 return entry.cachedIconType_; |
833 }; | 930 }; |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1511 this.rootsList_.redraw(); | 1608 this.rootsList_.redraw(); |
1512 this.truncateBreadcrumbs_(); | 1609 this.truncateBreadcrumbs_(); |
1513 }; | 1610 }; |
1514 | 1611 |
1515 FileManager.prototype.resolvePath = function( | 1612 FileManager.prototype.resolvePath = function( |
1516 path, resultCallback, errorCallback) { | 1613 path, resultCallback, errorCallback) { |
1517 return util.resolvePath(this.filesystem_.root, path, resultCallback, | 1614 return util.resolvePath(this.filesystem_.root, path, resultCallback, |
1518 errorCallback); | 1615 errorCallback); |
1519 }; | 1616 }; |
1520 | 1617 |
1618 FileManager.prototype.getPathFromUrlOrParams_ = function() { | |
1619 return location.hash ? // Location hash has the highest priority. | |
1620 decodeURI(location.hash.substr(1)) : | |
1621 this.params_.defaultPath; | |
1622 }; | |
1623 | |
1521 /** | 1624 /** |
1522 * Restores current directory and may be a selected item after page load (or | 1625 * Restores current directory and may be a selected item after page load (or |
1523 * reload) or popping a state (after click on back/forward). If location.hash | 1626 * reload) or popping a state (after click on back/forward). If location.hash |
1524 * is present it means that the user has navigated somewhere and that place | 1627 * is present it means that the user has navigated somewhere and that place |
1525 * will be restored. defaultPath primarily is used with save/open dialogs. | 1628 * will be restored. defaultPath primarily is used with save/open dialogs. |
1526 * Default path may also contain a file name. Freshly opened file manager | 1629 * Default path may also contain a file name. Freshly opened file manager |
1527 * window has neither. | 1630 * window has neither. |
1631 * | |
1632 * @param {boolean} blankWhileOpeningAFile | |
1528 */ | 1633 */ |
1529 FileManager.prototype.setupCurrentDirectory_ = function() { | 1634 FileManager.prototype.setupCurrentDirectory_ = |
1635 function(blankWhileOpeningAFile) { | |
1636 var path = this.getPathFromUrlOrParams_(); | |
1530 | 1637 |
1531 if (location.hash) { | 1638 if (!path) { |
1532 // Location hash has the highest priority. | 1639 this.directoryModel_.setupDefaultPath(); |
1533 var path = decodeURI(location.hash.substr(1)); | 1640 return; |
1641 } | |
1534 | 1642 |
1535 // In the FULL_PAGE mode if the path points to a file we might have | 1643 // In the FULL_PAGE mode if the hash path points to a file we might have |
1536 // to invoke a task after selecting it. | 1644 // to invoke a task after selecting it. |
1537 if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { | 1645 // If the file path is in params_ we only want to select the file. |
1538 // To prevent the file list flickering for a moment before the action | 1646 if (location.hash && |
1539 // is executed we hide it under a white div. | 1647 this.dialogType_ == FileManager.DialogType.FULL_PAGE) { |
1540 var shade = this.document_.createElement('div'); | 1648 // To prevent the file list flickering for a moment before the action |
1649 // is executed we hide it under a white div. | |
1650 var shade; | |
1651 if (blankWhileOpeningAFile) { | |
1652 shade = this.document_.createElement('div'); | |
1541 shade.className = 'overlay-pane'; | 1653 shade.className = 'overlay-pane'; |
1542 shade.style.backgroundColor = 'white'; | 1654 shade.style.backgroundColor = 'white'; |
1543 this.document_.body.appendChild(shade); | 1655 this.document_.body.appendChild(shade); |
1544 function removeShade() { shade.parentNode.removeChild(shade) } | 1656 } |
1545 | 1657 function removeShade() { |
1546 // Keep track of whether the path is identified as an existing leaf | 1658 if (shade) |
1547 // node. Note that onResolve is guaranteed to be called (exactly once) | 1659 shade.parentNode.removeChild(shade); |
1548 // before onLoadedActivateLeaf. | |
1549 var foundLeaf = true; | |
1550 function onResolve(baseName, leafName, exists) { | |
1551 if (!exists || leafName == '') { | |
1552 // Non-existent file or a directory. Remove the shade immediately. | |
1553 removeShade(); | |
1554 foundLeaf = false; | |
1555 } | |
1556 } | |
1557 | |
1558 // TODO(kaznacheev): refactor dispatchDefaultTask to accept an array | |
1559 // of urls instead of a selection. This will remove the need to wait | |
1560 // until the selection is done. | |
1561 var self = this; | |
1562 function onLoadedActivateLeaf() { | |
1563 if (foundLeaf) { | |
1564 // There are 3 ways we can get here: | |
1565 // 1. Invoked from file_manager_util::ViewFile. This can only | |
1566 // happen for 'gallery' and 'mount-archive' actions. | |
1567 // 2. Reloading a Gallery page. Must be an image or a video file. | |
1568 // 3. A user manually entered a URL pointing to a file. | |
1569 if (FileType.isImageOrVideo(path)) { | |
1570 self.dispatchInternalTask_('gallery', self.selection.urls); | |
1571 } else if (FileType.getMediaType(path) == 'archive') { | |
1572 self.dispatchInternalTask_('mount-archive', self.selection.urls); | |
1573 } else { | |
1574 // Manually entered path, do nothing, remove the shade ASAP. | |
1575 removeShade(); | |
1576 return; | |
1577 } | |
1578 setTimeout(removeShade, 1000); | |
1579 } | |
1580 } | |
1581 this.directoryModel_.setupPath(path, onLoadedActivateLeaf, onResolve); | |
1582 | |
1583 return; | |
1584 } | 1660 } |
1585 | 1661 |
1586 this.directoryModel_.setupPath(path); | 1662 // Keep track of whether the path is identified as an existing leaf |
1663 // node. Note that onResolve is guaranteed to be called (exactly once) | |
1664 // before onLoadedActivateLeaf. | |
1665 var foundLeaf = true; | |
1666 function onResolve(baseName, leafName, exists) { | |
1667 if (!exists || leafName == '') { | |
1668 // Non-existent file or a directory. Remove the shade immediately. | |
1669 removeShade(); | |
1670 foundLeaf = false; | |
1671 } | |
1672 } | |
1673 | |
1674 // TODO(kaznacheev): refactor dispatchDefaultTask to accept an array | |
1675 // of urls instead of a selection. This will remove the need to wait | |
1676 // until the selection is done. | |
1677 var self = this; | |
1678 function onLoadedActivateLeaf() { | |
1679 if (foundLeaf) { | |
1680 // There are 3 ways we can get here: | |
1681 // 1. Invoked from file_manager_util::ViewFile. This can only | |
1682 // happen for 'gallery' and 'mount-archive' actions. | |
1683 // 2. Reloading a Gallery page. Must be an image or a video file. | |
1684 // 3. A user manually entered a URL pointing to a file. | |
1685 if (FileType.isImageOrVideo(path)) { | |
1686 self.dispatchInternalTask_('gallery', self.selection.urls); | |
1687 } else if (FileType.getMediaType(path) == 'archive') { | |
1688 self.dispatchInternalTask_('mount-archive', self.selection.urls); | |
1689 } else { | |
1690 // Manually entered path, do nothing, remove the shade ASAP. | |
1691 removeShade(); | |
1692 return; | |
1693 } | |
1694 setTimeout(removeShade, 1000); | |
1695 } | |
1696 } | |
1697 this.directoryModel_.setupPath(path, onLoadedActivateLeaf, onResolve); | |
1587 return; | 1698 return; |
1588 } | 1699 } |
1589 | 1700 |
1590 if (this.params_.defaultPath) { | 1701 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { |
1591 var path = this.params_.defaultPath; | 1702 this.directoryModel_.setupPath(path, undefined, |
1592 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { | 1703 function(basePath, leafName) { |
1593 this.directoryModel_.setupPath(path, undefined, | 1704 this.filenameInput_.value = leafName; |
1594 function(basePath, leafName) { | 1705 this.selectDefaultPathInFilenameInput_(); |
1595 this.filenameInput_.value = leafName; | 1706 }.bind(this)); |
1596 this.selectDefaultPathInFilenameInput_(); | |
1597 }.bind(this)); | |
1598 return; | |
1599 } | |
1600 | |
1601 this.directoryModel_.setupPath(path); | |
1602 return; | 1707 return; |
1603 } | 1708 } |
1604 | 1709 |
1605 this.directoryModel_.setupDefaultPath(); | 1710 this.directoryModel_.setupPath(path); |
1606 }; | 1711 }; |
1607 | 1712 |
1608 /** | 1713 /** |
1609 * Tweak the UI to become a particular kind of dialog, as determined by the | 1714 * Tweak the UI to become a particular kind of dialog, as determined by the |
1610 * dialog type parameter passed to the constructor. | 1715 * dialog type parameter passed to the constructor. |
1611 */ | 1716 */ |
1612 FileManager.prototype.initDialogType_ = function() { | 1717 FileManager.prototype.initDialogType_ = function() { |
1613 var defaultTitle; | 1718 var defaultTitle; |
1614 var okLabel = str('OPEN_LABEL'); | 1719 var okLabel = str('OPEN_LABEL'); |
1615 | 1720 |
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2504 | 2609 |
2505 if (selection.tasksList.length > 0) { | 2610 if (selection.tasksList.length > 0) { |
2506 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls); | 2611 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls); |
2507 return; | 2612 return; |
2508 } | 2613 } |
2509 | 2614 |
2510 if (selection.urls.length == 1) { | 2615 if (selection.urls.length == 1) { |
2511 // We don't have tasks, so try the default browser action. | 2616 // We don't have tasks, so try the default browser action. |
2512 // We only do that for single selection to avoid confusion. | 2617 // We only do that for single selection to avoid confusion. |
2513 | 2618 |
2514 function callback(success) { | 2619 var callback = function(success) { |
2515 if (!success && selection.entries.length == 1) | 2620 if (!success && selection.entries.length == 1) |
2516 this.alert.showHtml( | 2621 this.alert.showHtml( |
2517 unescape(selection.entries[0].name), | 2622 unescape(selection.entries[0].name), |
2518 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL), | 2623 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL), |
2519 function() {}); | 2624 function() {}); |
2520 } | 2625 }.bind(this); |
2521 | 2626 |
2522 this.executeIfAvailable_(selection.urls, function(urls) { | 2627 this.executeIfAvailable_(selection.urls, function(urls) { |
2523 chrome.fileBrowserPrivate.viewFiles(urls, 'default', | 2628 chrome.fileBrowserPrivate.viewFiles(urls, 'default', callback); |
2524 callback.bind(this)); | |
2525 }); | 2629 }); |
2526 } | 2630 } |
2527 }; | 2631 }; |
2528 | 2632 |
2529 FileManager.prototype.dispatchInternalTask_ = function(task, urls) { | 2633 FileManager.prototype.dispatchInternalTask_ = function(task, urls) { |
2530 this.dispatchFileTask_(this.getExtensionId_() + '|' + task, urls); | 2634 this.dispatchFileTask_(this.getExtensionId_() + '|' + task, urls); |
2531 }; | 2635 }; |
2532 | 2636 |
2533 FileManager.prototype.dispatchFileTask_ = function(taskId, urls) { | 2637 FileManager.prototype.dispatchFileTask_ = function(taskId, urls) { |
2534 this.executeIfAvailable_(urls, function(urls) { | 2638 this.executeIfAvailable_(urls, function(urls) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2586 /** | 2690 /** |
2587 * Event handler called when some volume was mounted or unmouted. | 2691 * Event handler called when some volume was mounted or unmouted. |
2588 */ | 2692 */ |
2589 FileManager.prototype.onMountCompleted_ = function(event) { | 2693 FileManager.prototype.onMountCompleted_ = function(event) { |
2590 var self = this; | 2694 var self = this; |
2591 | 2695 |
2592 var changeDirectoryTo = null; | 2696 var changeDirectoryTo = null; |
2593 | 2697 |
2594 if (event && event.mountType == 'gdata') { | 2698 if (event && event.mountType == 'gdata') { |
2595 metrics.recordInterval('Load.GData'); | 2699 metrics.recordInterval('Load.GData'); |
2596 if (this.gdataMountTimer_) { | 2700 console.log("GData mounted"); |
2597 clearTimeout(this.gdataMountTimer_); | |
2598 this.gdataMountTimer_ = null; | |
2599 } | |
2600 if (event.status == 'success') { | 2701 if (event.status == 'success') { |
2601 this.gdataMounted_ = true; | 2702 this.gdataMounted_ = true; |
2602 this.gdataMountInfo_ = { | 2703 this.gdataMountInfo_ = { |
2603 "mountPath": event.mountPath, | 2704 "mountPath": event.mountPath, |
2604 "sourceUrl": event.sourceUrl, | 2705 "sourceUrl": event.sourceUrl, |
2605 "mountType": event.mountType, | 2706 "mountType": event.mountType, |
2606 "mountCondition": event.status | 2707 "mountCondition": event.status |
2607 }; | 2708 }; |
2608 if (this.isOnGData()) { | 2709 // Not calling clearGDataLoadingTimer_ here because we want to keep |
2710 // "Loading Google Docs" message until the directory loads. It is OK if | |
2711 // the timer fires after the mount because onDirectoryChanged_ will hide | |
2712 // the unmounted panel. | |
2713 if (this.setupCurrentDirectoryPostponed_) { | |
2714 this.setupCurrentDirectoryPostponed_(false); | |
dgozman
2012/03/28 14:18:36
Comment about meaning of this |false|.
| |
2715 } else if (this.isOnGData() && | |
2716 this.directoryModel_.currentEntry.unmounted) { | |
2609 // We are currently on an unmounted GData directory, force a rescan. | 2717 // We are currently on an unmounted GData directory, force a rescan. |
2610 changeDirectoryTo = this.directoryModel_.rootPath; | 2718 changeDirectoryTo = this.directoryModel_.rootPath; |
2611 } | 2719 } |
2612 } else { | 2720 } else { |
2613 this.gdataMounted_ = false; | 2721 this.gdataMounted_ = false; |
2614 this.gdataMountInfo_ = null; | 2722 this.gdataMountInfo_ = null; |
2723 this.clearGDataLoadingTimer_(); | |
2724 this.onGDataUnreachable_('GData mount failed: ' + event.status); | |
2725 if (this.setupCurrentDirectoryPostponed_) { | |
2726 this.setupCurrentDirectoryPostponed_(true); // Cancel. | |
2727 // Change to unmounted GData root. | |
2728 changeDirectoryTo = '/' + DirectoryModel.GDATA_DIRECTORY; | |
2729 } | |
2615 } | 2730 } |
2616 } | 2731 } |
2617 | 2732 |
2618 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { | 2733 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { |
2619 self.setMountPoints_(mountPoints); | 2734 self.setMountPoints_(mountPoints); |
2620 if (event.eventType == 'mount') { | 2735 if (event.eventType == 'mount') { |
2621 // Mount request finished - remove it. | 2736 // Mount request finished - remove it. |
2622 var index = self.mountRequests_.indexOf(event.sourceUrl); | 2737 var index = self.mountRequests_.indexOf(event.sourceUrl); |
2623 if (index != -1) { | 2738 if (index != -1) { |
2624 self.mountRequests_.splice(index, 1); | 2739 self.mountRequests_.splice(index, 1); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2660 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY; | 2775 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY; |
2661 } | 2776 } |
2662 | 2777 |
2663 // Even if something failed root list should be rescanned. | 2778 // Even if something failed root list should be rescanned. |
2664 // Failed mounts can "give" us new devices which might be formatted, | 2779 // Failed mounts can "give" us new devices which might be formatted, |
2665 // so we have to refresh root list then. | 2780 // so we have to refresh root list then. |
2666 self.directoryModel_.updateRoots(function() { | 2781 self.directoryModel_.updateRoots(function() { |
2667 if (changeDirectoryTo) { | 2782 if (changeDirectoryTo) { |
2668 self.directoryModel_.changeDirectory(changeDirectoryTo); | 2783 self.directoryModel_.changeDirectory(changeDirectoryTo); |
2669 } | 2784 } |
2670 }); | 2785 }, self.gdataMounted_); |
2671 }); | 2786 }); |
2672 }; | 2787 }; |
2673 | 2788 |
2674 /** | 2789 /** |
2675 * Event handler called when some internal task should be executed. | 2790 * Event handler called when some internal task should be executed. |
2676 */ | 2791 */ |
2677 FileManager.prototype.onFileTaskExecute_ = function(id, urls) { | 2792 FileManager.prototype.onFileTaskExecute_ = function(id, urls) { |
2678 if (id == 'play') { | 2793 if (id == 'play') { |
2679 var position = 0; | 2794 var position = 0; |
2680 if (urls.length == 1) { | 2795 if (urls.length == 1) { |
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3550 } | 3665 } |
3551 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, | 3666 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, |
3552 function(result) { | 3667 function(result) { |
3553 if (!result) { | 3668 if (!result) { |
3554 console.log('Failed to remove file watch'); | 3669 console.log('Failed to remove file watch'); |
3555 } | 3670 } |
3556 }); | 3671 }); |
3557 this.watchedDirectoryUrl_ = null; | 3672 this.watchedDirectoryUrl_ = null; |
3558 } | 3673 } |
3559 | 3674 |
3560 if (event.newDirEntry.fullPath != '/') { | 3675 if (event.newDirEntry.fullPath != '/' && !event.newDirEntry.unmounted) { |
3561 this.watchedDirectoryUrl_ = event.newDirEntry.toURL(); | 3676 this.watchedDirectoryUrl_ = event.newDirEntry.toURL(); |
3562 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_, | 3677 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_, |
3563 function(result) { | 3678 function(result) { |
3564 if (!result) { | 3679 if (!result) { |
3565 console.log('Failed to add file watch'); | 3680 console.log('Failed to add file watch'); |
3566 this.watchedDirectoryUrl_ = null; | 3681 this.watchedDirectoryUrl_ = null; |
3567 } | 3682 } |
3568 }.bind(this)); | 3683 }.bind(this)); |
3569 } | 3684 } |
3570 | 3685 |
3571 this.updateVolumeMetadata_(); | 3686 this.updateVolumeMetadata_(); |
3572 | 3687 |
3688 if (event.newDirEntry.unmounted) | |
3689 this.dialogContainer_.setAttribute('unmounted', true); | |
3690 else | |
3691 this.dialogContainer_.removeAttribute('unmounted'); | |
3692 | |
3573 if (this.isOnGData()) { | 3693 if (this.isOnGData()) { |
3574 this.dialogContainer_.setAttribute('gdata', true); | 3694 this.dialogContainer_.setAttribute('gdata', true); |
3575 if (!this.requestedGDataMount_) { // Request GData mount only once. | 3695 if (event.newDirEntry.unmounted) { |
3576 this.requestedGDataMount_ = true; | 3696 this.initGData_(true /* directory changed */); |
3577 this.initGData_(); | |
3578 } | 3697 } |
3579 } else { | 3698 } else { |
3580 this.dialogContainer_.removeAttribute('gdata'); | 3699 this.dialogContainer_.removeAttribute('gdata'); |
3581 } | 3700 } |
3582 }; | 3701 }; |
3583 | 3702 |
3584 FileManager.prototype.updateVolumeMetadata_ = function() { | 3703 FileManager.prototype.updateVolumeMetadata_ = function() { |
3585 var dm = this.directoryModel_; | 3704 var dm = this.directoryModel_; |
3586 if (!dm) return; | 3705 if (!dm) return; |
3587 | 3706 |
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4432 }); | 4551 }); |
4433 }, onError); | 4552 }, onError); |
4434 | 4553 |
4435 function onError(err) { | 4554 function onError(err) { |
4436 console.log('Error while checking free space: ' + err); | 4555 console.log('Error while checking free space: ' + err); |
4437 setTimeout(doCheck, 1000 * 60); | 4556 setTimeout(doCheck, 1000 * 60); |
4438 } | 4557 } |
4439 } | 4558 } |
4440 } | 4559 } |
4441 })(); | 4560 })(); |
OLD | NEW |