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 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2509 | 2614 |
2510 if (selection.tasksList.length > 0) { | 2615 if (selection.tasksList.length > 0) { |
2511 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls); | 2616 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls); |
2512 return; | 2617 return; |
2513 } | 2618 } |
2514 | 2619 |
2515 if (selection.urls.length == 1) { | 2620 if (selection.urls.length == 1) { |
2516 // We don't have tasks, so try the default browser action. | 2621 // We don't have tasks, so try the default browser action. |
2517 // We only do that for single selection to avoid confusion. | 2622 // We only do that for single selection to avoid confusion. |
2518 | 2623 |
2519 function callback(success) { | 2624 var callback = function(success) { |
2520 if (!success && selection.entries.length == 1) | 2625 if (!success && selection.entries.length == 1) |
2521 this.alert.showHtml( | 2626 this.alert.showHtml( |
2522 unescape(selection.entries[0].name), | 2627 unescape(selection.entries[0].name), |
2523 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL), | 2628 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL), |
2524 function() {}); | 2629 function() {}); |
2525 } | 2630 }.bind(this); |
2526 | 2631 |
2527 this.executeIfAvailable_(selection.urls, function(urls) { | 2632 this.executeIfAvailable_(selection.urls, function(urls) { |
2528 chrome.fileBrowserPrivate.viewFiles(urls, 'default', | 2633 chrome.fileBrowserPrivate.viewFiles(urls, 'default', callback); |
2529 callback.bind(this)); | |
2530 }); | 2634 }); |
2531 } | 2635 } |
2532 }; | 2636 }; |
2533 | 2637 |
2534 FileManager.prototype.dispatchInternalTask_ = function(task, urls) { | 2638 FileManager.prototype.dispatchInternalTask_ = function(task, urls) { |
2535 this.dispatchFileTask_(this.getExtensionId_() + '|' + task, urls); | 2639 this.dispatchFileTask_(this.getExtensionId_() + '|' + task, urls); |
2536 }; | 2640 }; |
2537 | 2641 |
2538 FileManager.prototype.dispatchFileTask_ = function(taskId, urls) { | 2642 FileManager.prototype.dispatchFileTask_ = function(taskId, urls) { |
2539 this.executeIfAvailable_(urls, function(urls) { | 2643 this.executeIfAvailable_(urls, function(urls) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2591 /** | 2695 /** |
2592 * Event handler called when some volume was mounted or unmouted. | 2696 * Event handler called when some volume was mounted or unmouted. |
2593 */ | 2697 */ |
2594 FileManager.prototype.onMountCompleted_ = function(event) { | 2698 FileManager.prototype.onMountCompleted_ = function(event) { |
2595 var self = this; | 2699 var self = this; |
2596 | 2700 |
2597 var changeDirectoryTo = null; | 2701 var changeDirectoryTo = null; |
2598 | 2702 |
2599 if (event && event.mountType == 'gdata') { | 2703 if (event && event.mountType == 'gdata') { |
2600 metrics.recordInterval('Load.GData'); | 2704 metrics.recordInterval('Load.GData'); |
2601 if (this.gdataMountTimer_) { | 2705 console.log("GData mounted"); |
2602 clearTimeout(this.gdataMountTimer_); | |
2603 this.gdataMountTimer_ = null; | |
2604 } | |
2605 if (event.status == 'success') { | 2706 if (event.status == 'success') { |
2606 this.gdataMounted_ = true; | 2707 this.gdataMounted_ = true; |
2607 this.gdataMountInfo_ = { | 2708 this.gdataMountInfo_ = { |
2608 "mountPath": event.mountPath, | 2709 "mountPath": event.mountPath, |
2609 "sourceUrl": event.sourceUrl, | 2710 "sourceUrl": event.sourceUrl, |
2610 "mountType": event.mountType, | 2711 "mountType": event.mountType, |
2611 "mountCondition": event.status | 2712 "mountCondition": event.status |
2612 }; | 2713 }; |
2613 if (this.isOnGData()) { | 2714 // Not calling clearGDataLoadingTimer_ here because we want to keep |
| 2715 // "Loading Google Docs" message until the directory loads. It is OK if |
| 2716 // the timer fires after the mount because onDirectoryChanged_ will hide |
| 2717 // the unmounted panel. |
| 2718 if (this.setupCurrentDirectoryPostponed_) { |
| 2719 this.setupCurrentDirectoryPostponed_(false /* execute */); |
| 2720 } else if (this.isOnGData() && |
| 2721 this.directoryModel_.currentEntry.unmounted) { |
2614 // We are currently on an unmounted GData directory, force a rescan. | 2722 // We are currently on an unmounted GData directory, force a rescan. |
2615 changeDirectoryTo = this.directoryModel_.rootPath; | 2723 changeDirectoryTo = this.directoryModel_.rootPath; |
2616 } | 2724 } |
2617 } else { | 2725 } else { |
2618 this.gdataMounted_ = false; | 2726 this.gdataMounted_ = false; |
2619 this.gdataMountInfo_ = null; | 2727 this.gdataMountInfo_ = null; |
| 2728 this.clearGDataLoadingTimer_(); |
| 2729 this.onGDataUnreachable_('GData mount failed: ' + event.status); |
| 2730 if (this.setupCurrentDirectoryPostponed_) { |
| 2731 this.setupCurrentDirectoryPostponed_(true /* cancel */); |
| 2732 // Change to unmounted GData root. |
| 2733 changeDirectoryTo = '/' + DirectoryModel.GDATA_DIRECTORY; |
| 2734 } |
2620 } | 2735 } |
2621 } | 2736 } |
2622 | 2737 |
2623 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { | 2738 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { |
2624 self.setMountPoints_(mountPoints); | 2739 self.setMountPoints_(mountPoints); |
2625 if (event.eventType == 'mount') { | 2740 if (event.eventType == 'mount') { |
2626 // Mount request finished - remove it. | 2741 // Mount request finished - remove it. |
2627 var index = self.mountRequests_.indexOf(event.sourceUrl); | 2742 var index = self.mountRequests_.indexOf(event.sourceUrl); |
2628 if (index != -1) { | 2743 if (index != -1) { |
2629 self.mountRequests_.splice(index, 1); | 2744 self.mountRequests_.splice(index, 1); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2665 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY; | 2780 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY; |
2666 } | 2781 } |
2667 | 2782 |
2668 // Even if something failed root list should be rescanned. | 2783 // Even if something failed root list should be rescanned. |
2669 // Failed mounts can "give" us new devices which might be formatted, | 2784 // Failed mounts can "give" us new devices which might be formatted, |
2670 // so we have to refresh root list then. | 2785 // so we have to refresh root list then. |
2671 self.directoryModel_.updateRoots(function() { | 2786 self.directoryModel_.updateRoots(function() { |
2672 if (changeDirectoryTo) { | 2787 if (changeDirectoryTo) { |
2673 self.directoryModel_.changeDirectory(changeDirectoryTo); | 2788 self.directoryModel_.changeDirectory(changeDirectoryTo); |
2674 } | 2789 } |
2675 }); | 2790 }, self.gdataMounted_); |
2676 }); | 2791 }); |
2677 }; | 2792 }; |
2678 | 2793 |
2679 /** | 2794 /** |
2680 * Event handler called when some internal task should be executed. | 2795 * Event handler called when some internal task should be executed. |
2681 */ | 2796 */ |
2682 FileManager.prototype.onFileTaskExecute_ = function(id, urls) { | 2797 FileManager.prototype.onFileTaskExecute_ = function(id, urls) { |
2683 if (id == 'play') { | 2798 if (id == 'play') { |
2684 var position = 0; | 2799 var position = 0; |
2685 if (urls.length == 1) { | 2800 if (urls.length == 1) { |
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3555 } | 3670 } |
3556 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, | 3671 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, |
3557 function(result) { | 3672 function(result) { |
3558 if (!result) { | 3673 if (!result) { |
3559 console.log('Failed to remove file watch'); | 3674 console.log('Failed to remove file watch'); |
3560 } | 3675 } |
3561 }); | 3676 }); |
3562 this.watchedDirectoryUrl_ = null; | 3677 this.watchedDirectoryUrl_ = null; |
3563 } | 3678 } |
3564 | 3679 |
3565 if (event.newDirEntry.fullPath != '/') { | 3680 if (event.newDirEntry.fullPath != '/' && !event.newDirEntry.unmounted) { |
3566 this.watchedDirectoryUrl_ = event.newDirEntry.toURL(); | 3681 this.watchedDirectoryUrl_ = event.newDirEntry.toURL(); |
3567 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_, | 3682 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_, |
3568 function(result) { | 3683 function(result) { |
3569 if (!result) { | 3684 if (!result) { |
3570 console.log('Failed to add file watch'); | 3685 console.log('Failed to add file watch'); |
3571 this.watchedDirectoryUrl_ = null; | 3686 this.watchedDirectoryUrl_ = null; |
3572 } | 3687 } |
3573 }.bind(this)); | 3688 }.bind(this)); |
3574 } | 3689 } |
3575 | 3690 |
3576 this.updateVolumeMetadata_(); | 3691 this.updateVolumeMetadata_(); |
3577 | 3692 |
| 3693 if (event.newDirEntry.unmounted) |
| 3694 this.dialogContainer_.setAttribute('unmounted', true); |
| 3695 else |
| 3696 this.dialogContainer_.removeAttribute('unmounted'); |
| 3697 |
3578 if (this.isOnGData()) { | 3698 if (this.isOnGData()) { |
3579 this.dialogContainer_.setAttribute('gdata', true); | 3699 this.dialogContainer_.setAttribute('gdata', true); |
3580 if (!this.requestedGDataMount_) { // Request GData mount only once. | 3700 if (event.newDirEntry.unmounted) { |
3581 this.requestedGDataMount_ = true; | 3701 this.initGData_(true /* directory changed */); |
3582 this.initGData_(); | |
3583 } | 3702 } |
3584 } else { | 3703 } else { |
3585 this.dialogContainer_.removeAttribute('gdata'); | 3704 this.dialogContainer_.removeAttribute('gdata'); |
3586 } | 3705 } |
3587 }; | 3706 }; |
3588 | 3707 |
3589 FileManager.prototype.updateVolumeMetadata_ = function() { | 3708 FileManager.prototype.updateVolumeMetadata_ = function() { |
3590 var dm = this.directoryModel_; | 3709 var dm = this.directoryModel_; |
3591 if (!dm) return; | 3710 if (!dm) return; |
3592 | 3711 |
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4437 }); | 4556 }); |
4438 }, onError); | 4557 }, onError); |
4439 | 4558 |
4440 function onError(err) { | 4559 function onError(err) { |
4441 console.log('Error while checking free space: ' + err); | 4560 console.log('Error while checking free space: ' + err); |
4442 setTimeout(doCheck, 1000 * 60); | 4561 setTimeout(doCheck, 1000 * 60); |
4443 } | 4562 } |
4444 } | 4563 } |
4445 } | 4564 } |
4446 })(); | 4565 })(); |
OLD | NEW |