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 // Will be nulled out if a directory change happens before it fires. | |
565 this.setupGDataDirectoryAfterMount_ = function() { | |
dgozman
2012/03/28 10:28:30
Can we do the same trick as in DirectoryModel: add
Vladislav Kaznacheev
2012/03/28 14:00:57
Done.
| |
566 this.setupGDataDirectoryAfterMount_ = null; | |
567 this.setupCurrentDirectory_(false /* blankWhileLoading */); | |
568 }.bind(this); | |
569 } else { | |
570 this.setupCurrentDirectory_(true /* blankWhileLoading */); | |
571 } | |
558 | 572 |
559 this.summarizeSelection_(); | 573 this.summarizeSelection_(); |
560 | 574 |
561 var sortField = | 575 var sortField = |
562 window.localStorage['sort-field-' + this.dialogType_] || 'cachedMtime_'; | 576 window.localStorage['sort-field-' + this.dialogType_] || 'cachedMtime_'; |
563 var sortDirection = | 577 var sortDirection = |
564 window.localStorage['sort-direction-' + this.dialogType_] || 'desc'; | 578 window.localStorage['sort-direction-' + this.dialogType_] || 'desc'; |
565 this.directoryModel_.fileList.sort(sortField, sortDirection); | 579 this.directoryModel_.fileList.sort(sortField, sortDirection); |
566 | 580 |
567 this.refocus(); | 581 this.refocus(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
630 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input'); | 644 this.filenameInput_ = this.dialogDom_.querySelector('.filename-input'); |
631 this.taskItems_ = this.dialogDom_.querySelector('.tasks'); | 645 this.taskItems_ = this.dialogDom_.querySelector('.tasks'); |
632 this.okButton_ = this.dialogDom_.querySelector('.ok'); | 646 this.okButton_ = this.dialogDom_.querySelector('.ok'); |
633 this.cancelButton_ = this.dialogDom_.querySelector('.cancel'); | 647 this.cancelButton_ = this.dialogDom_.querySelector('.cancel'); |
634 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button'); | 648 this.deleteButton_ = this.dialogDom_.querySelector('.delete-button'); |
635 this.table_ = this.dialogDom_.querySelector('.detail-table'); | 649 this.table_ = this.dialogDom_.querySelector('.detail-table'); |
636 this.grid_ = this.dialogDom_.querySelector('.thumbnail-grid'); | 650 this.grid_ = this.dialogDom_.querySelector('.thumbnail-grid'); |
637 this.spinner_ = this.dialogDom_.querySelector('.spinner'); | 651 this.spinner_ = this.dialogDom_.querySelector('.spinner'); |
638 this.showSpinner_(false); | 652 this.showSpinner_(false); |
639 this.butter_ = this.dialogDom_.querySelector('.butter-bar'); | 653 this.butter_ = this.dialogDom_.querySelector('.butter-bar'); |
654 this.unmountedPanel_ = this.dialogDom_.querySelector('.unmounted-panel'); | |
640 | 655 |
641 cr.ui.Table.decorate(this.table_); | 656 cr.ui.Table.decorate(this.table_); |
642 cr.ui.Grid.decorate(this.grid_); | 657 cr.ui.Grid.decorate(this.grid_); |
643 | 658 |
644 this.downloadsWarning_ = | 659 this.downloadsWarning_ = |
645 this.dialogDom_.querySelector('.downloads-warning'); | 660 this.dialogDom_.querySelector('.downloads-warning'); |
646 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); | 661 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); |
647 this.downloadsWarning_.lastElementChild.innerHTML = html; | 662 this.downloadsWarning_.lastElementChild.innerHTML = html; |
648 var link = this.downloadsWarning_.querySelector('a'); | 663 var link = this.downloadsWarning_.querySelector('a'); |
649 link.addEventListener('click', this.onDownloadsWarningClick_.bind(this)); | 664 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) { | 810 this.rootsList_.itemConstructor = function(entry) { |
796 return self.renderRoot_(entry); | 811 return self.renderRoot_(entry); |
797 }; | 812 }; |
798 | 813 |
799 this.rootsList_.selectionModel = this.directoryModel_.rootsListSelection; | 814 this.rootsList_.selectionModel = this.directoryModel_.rootsListSelection; |
800 | 815 |
801 // TODO(dgozman): add "Add a drive" item. | 816 // TODO(dgozman): add "Add a drive" item. |
802 this.rootsList_.dataModel = this.directoryModel_.rootsList; | 817 this.rootsList_.dataModel = this.directoryModel_.rootsList; |
803 this.directoryModel_.updateRoots(function() { | 818 this.directoryModel_.updateRoots(function() { |
804 self.rootsList_.endBatchUpdates(); | 819 self.rootsList_.endBatchUpdates(); |
805 }); | 820 }, 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 }; | 821 }; |
822 | 822 |
823 /** | 823 /** |
824 * @param {boolean} dirChanged True if we just changed to GData directory, | |
825 * False if "Retry" button clicked. | |
826 */ | |
827 FileManager.prototype.initGData_ = function(dirChanged) { | |
828 this.initGDataUnmountedPanel_(); | |
829 | |
830 this.unmountedPanel_.removeAttribute('error'); | |
831 if (dirChanged) { | |
832 // When changing to GData directory we want to see a clear panel. | |
833 this.unmountedPanel_.removeAttribute('retry'); | |
834 this.unmountedPanel_.removeAttribute('loading'); | |
835 setTimeout(function() { | |
836 if (this.gdataLoadingTimer_) { // Still loading. | |
837 this.unmountedPanel_.setAttribute('loading', true); | |
838 } | |
839 }.bind(this), 500); // Avoid flicker if the mount is quick. | |
840 } else { | |
841 // When retrying we do not hide "Retry" and "Learn more". | |
842 this.unmountedPanel_.setAttribute('loading', true); | |
843 } | |
844 | |
845 if (this.gdataLoadingTimer_) | |
dgozman
2012/03/28 10:28:30
How is this possible?
Vladislav Kaznacheev
2012/03/28 14:00:57
Added a comment:
If the user changed to another di
| |
846 return; | |
847 | |
848 metrics.startInterval('Load.GData'); | |
849 chrome.fileBrowserPrivate.addMount('', 'gdata', {}); | |
850 | |
851 this.gdataLoadingTimer_ = setTimeout(function() { | |
852 this.gdataLoadingTimer_ = null; | |
853 this.onGDataUnreachable_('GData load timeout'); | |
854 }.bind(this), | |
855 10 * 1000) ; | |
856 }; | |
857 | |
858 FileManager.prototype.clearGDataLoadingTimer_ = function(message) { | |
859 if (this.gdataLoadingTimer_) { | |
860 clearTimeout(this.gdataLoadingTimer_); | |
861 this.gdataLoadingTimer_ = null; | |
862 } | |
863 }; | |
864 | |
865 FileManager.prototype.onGDataUnreachable_ = function(message) { | |
866 console.warn(message); | |
867 if (this.isOnGData()) { | |
868 this.unmountedPanel_.removeAttribute('loading'); | |
869 this.unmountedPanel_.setAttribute('error', true); | |
870 this.unmountedPanel_.setAttribute('retry', true); | |
871 } | |
872 }; | |
873 | |
874 FileManager.prototype.initGDataUnmountedPanel_ = function() { | |
875 if (this.unmountedPanel_.firstElementChild) | |
876 return; | |
877 | |
878 var loading = this.document_.createElement('div'); | |
879 loading.className = 'gdata loading'; | |
880 loading.textContent = strf('GDATA_LOADING', str('GDATA_PRODUCT_NAME')); | |
881 this.unmountedPanel_.appendChild(loading); | |
882 | |
883 var error = this.document_.createElement('div'); | |
884 error.className = 'gdata error'; | |
885 error.textContent = strf('GDATA_CANNOT_REACH', str('GDATA_PRODUCT_NAME')); | |
886 this.unmountedPanel_.appendChild(error); | |
887 | |
888 var retry = this.document_.createElement('button'); | |
889 retry.className = 'gdata retry'; | |
890 retry.textContent = str('GDATA_RETRY'); | |
891 retry.onclick = this.initGData_.bind(this, false /* retry */); | |
892 this.unmountedPanel_.appendChild(retry); | |
893 | |
894 var learnMore = this.document_.createElement('div'); | |
895 learnMore.className = 'gdata learn-more'; | |
896 this.unmountedPanel_.appendChild(learnMore); | |
897 | |
898 var learnMoreLink = this.document_.createElement('a'); | |
899 learnMoreLink.textContent = str('GDATA_LEARN_MORE'); | |
900 learnMoreLink.href = 'javascript://'; // TODO: Set a proper link URL. | |
901 learnMoreLink.className = 'gdata learn-more'; | |
902 learnMore.appendChild(learnMoreLink); | |
903 }; | |
904 | |
905 /** | |
824 * Get the icon type for a given Entry. | 906 * Get the icon type for a given Entry. |
825 * | 907 * |
826 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). | 908 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). |
827 * @return {string} | 909 * @return {string} |
828 */ | 910 */ |
829 FileManager.prototype.getIconType = function(entry) { | 911 FileManager.prototype.getIconType = function(entry) { |
830 if (!('cachedIconType_' in entry)) | 912 if (!('cachedIconType_' in entry)) |
831 entry.cachedIconType_ = this.computeIconType_(entry); | 913 entry.cachedIconType_ = this.computeIconType_(entry); |
832 return entry.cachedIconType_; | 914 return entry.cachedIconType_; |
833 }; | 915 }; |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1511 this.rootsList_.redraw(); | 1593 this.rootsList_.redraw(); |
1512 this.truncateBreadcrumbs_(); | 1594 this.truncateBreadcrumbs_(); |
1513 }; | 1595 }; |
1514 | 1596 |
1515 FileManager.prototype.resolvePath = function( | 1597 FileManager.prototype.resolvePath = function( |
1516 path, resultCallback, errorCallback) { | 1598 path, resultCallback, errorCallback) { |
1517 return util.resolvePath(this.filesystem_.root, path, resultCallback, | 1599 return util.resolvePath(this.filesystem_.root, path, resultCallback, |
1518 errorCallback); | 1600 errorCallback); |
1519 }; | 1601 }; |
1520 | 1602 |
1603 FileManager.prototype.getPathFromUrlOrParams_ = function() { | |
1604 return location.hash ? // Location hash has the highest priority. | |
1605 decodeURI(location.hash.substr(1)) : | |
1606 this.params_.defaultPath; | |
1607 }; | |
1608 | |
1521 /** | 1609 /** |
1522 * Restores current directory and may be a selected item after page load (or | 1610 * 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 | 1611 * 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 | 1612 * 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. | 1613 * will be restored. defaultPath primarily is used with save/open dialogs. |
1526 * Default path may also contain a file name. Freshly opened file manager | 1614 * Default path may also contain a file name. Freshly opened file manager |
1527 * window has neither. | 1615 * window has neither. |
1616 * | |
1617 * @param {boolean} blankWhileLoading | |
1528 */ | 1618 */ |
1529 FileManager.prototype.setupCurrentDirectory_ = function() { | 1619 FileManager.prototype.setupCurrentDirectory_ = function(blankWhileLoading) { |
1620 var path = this.getPathFromUrlOrParams_(); | |
1530 | 1621 |
1531 if (location.hash) { | 1622 if (!path) { |
1532 // Location hash has the highest priority. | 1623 this.directoryModel_.setupDefaultPath(); |
dgozman
2012/03/28 10:28:30
We ignore blankWhileLoading since default path is
Vladislav Kaznacheev
2012/03/28 14:00:57
It only affects the case when we (think that we) a
| |
1533 var path = decodeURI(location.hash.substr(1)); | 1624 return; |
1625 } | |
1534 | 1626 |
1535 // In the FULL_PAGE mode if the path points to a file we might have | 1627 // In the FULL_PAGE mode if the hash path points to a file we might have |
1536 // to invoke a task after selecting it. | 1628 // to invoke a task after selecting it. |
1537 if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { | 1629 // 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 | 1630 if (location.hash && |
1539 // is executed we hide it under a white div. | 1631 this.dialogType_ == FileManager.DialogType.FULL_PAGE) { |
1540 var shade = this.document_.createElement('div'); | 1632 // To prevent the file list flickering for a moment before the action |
1633 // is executed we hide it under a white div. | |
1634 var shade; | |
1635 if (blankWhileLoading) { | |
1636 shade = this.document_.createElement('div'); | |
1541 shade.className = 'overlay-pane'; | 1637 shade.className = 'overlay-pane'; |
1542 shade.style.backgroundColor = 'white'; | 1638 shade.style.backgroundColor = 'white'; |
1543 this.document_.body.appendChild(shade); | 1639 this.document_.body.appendChild(shade); |
1544 function removeShade() { shade.parentNode.removeChild(shade) } | 1640 } |
1545 | 1641 function removeShade() { |
1546 // Keep track of whether the path is identified as an existing leaf | 1642 if (shade) |
1547 // node. Note that onResolve is guaranteed to be called (exactly once) | 1643 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 } | 1644 } |
1585 | 1645 |
1586 this.directoryModel_.setupPath(path); | 1646 // Keep track of whether the path is identified as an existing leaf |
1647 // node. Note that onResolve is guaranteed to be called (exactly once) | |
1648 // before onLoadedActivateLeaf. | |
1649 var foundLeaf = true; | |
1650 function onResolve(baseName, leafName, exists) { | |
1651 if (!exists || leafName == '') { | |
1652 // Non-existent file or a directory. Remove the shade immediately. | |
1653 removeShade(); | |
1654 foundLeaf = false; | |
1655 } | |
1656 } | |
1657 | |
1658 // TODO(kaznacheev): refactor dispatchDefaultTask to accept an array | |
1659 // of urls instead of a selection. This will remove the need to wait | |
1660 // until the selection is done. | |
1661 var self = this; | |
1662 function onLoadedActivateLeaf() { | |
1663 if (foundLeaf) { | |
1664 // There are 3 ways we can get here: | |
1665 // 1. Invoked from file_manager_util::ViewFile. This can only | |
1666 // happen for 'gallery' and 'mount-archive' actions. | |
1667 // 2. Reloading a Gallery page. Must be an image or a video file. | |
1668 // 3. A user manually entered a URL pointing to a file. | |
1669 if (FileType.isImageOrVideo(path)) { | |
1670 self.dispatchInternalTask_('gallery', self.selection.urls); | |
1671 } else if (FileType.getMediaType(path) == 'archive') { | |
1672 self.dispatchInternalTask_('mount-archive', self.selection.urls); | |
1673 } else { | |
1674 // Manually entered path, do nothing, remove the shade ASAP. | |
1675 removeShade(); | |
1676 return; | |
1677 } | |
1678 setTimeout(removeShade, 1000); | |
1679 } | |
1680 } | |
1681 this.directoryModel_.setupPath(path, onLoadedActivateLeaf, onResolve); | |
1587 return; | 1682 return; |
1588 } | 1683 } |
1589 | 1684 |
1590 if (this.params_.defaultPath) { | 1685 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { |
1591 var path = this.params_.defaultPath; | 1686 this.directoryModel_.setupPath(path, undefined, |
1592 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { | 1687 function(basePath, leafName) { |
1593 this.directoryModel_.setupPath(path, undefined, | 1688 this.filenameInput_.value = leafName; |
1594 function(basePath, leafName) { | 1689 this.selectDefaultPathInFilenameInput_(); |
1595 this.filenameInput_.value = leafName; | 1690 }.bind(this)); |
1596 this.selectDefaultPathInFilenameInput_(); | |
1597 }.bind(this)); | |
1598 return; | |
1599 } | |
1600 | |
1601 this.directoryModel_.setupPath(path); | |
1602 return; | 1691 return; |
1603 } | 1692 } |
1604 | 1693 |
1605 this.directoryModel_.setupDefaultPath(); | 1694 this.directoryModel_.setupPath(path); |
1606 }; | 1695 }; |
1607 | 1696 |
1608 /** | 1697 /** |
1609 * Tweak the UI to become a particular kind of dialog, as determined by the | 1698 * Tweak the UI to become a particular kind of dialog, as determined by the |
1610 * dialog type parameter passed to the constructor. | 1699 * dialog type parameter passed to the constructor. |
1611 */ | 1700 */ |
1612 FileManager.prototype.initDialogType_ = function() { | 1701 FileManager.prototype.initDialogType_ = function() { |
1613 var defaultTitle; | 1702 var defaultTitle; |
1614 var okLabel = str('OPEN_LABEL'); | 1703 var okLabel = str('OPEN_LABEL'); |
1615 | 1704 |
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2504 | 2593 |
2505 if (selection.tasksList.length > 0) { | 2594 if (selection.tasksList.length > 0) { |
2506 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls); | 2595 this.dispatchFileTask_(selection.tasksList[0].taskId, selection.urls); |
2507 return; | 2596 return; |
2508 } | 2597 } |
2509 | 2598 |
2510 if (selection.urls.length == 1) { | 2599 if (selection.urls.length == 1) { |
2511 // We don't have tasks, so try the default browser action. | 2600 // We don't have tasks, so try the default browser action. |
2512 // We only do that for single selection to avoid confusion. | 2601 // We only do that for single selection to avoid confusion. |
2513 | 2602 |
2603 var self = this; | |
2514 function callback(success) { | 2604 function callback(success) { |
2515 if (!success && selection.entries.length == 1) | 2605 if (!success && selection.entries.length == 1) |
2516 this.alert.showHtml( | 2606 self.alert.showHtml( |
dgozman
2012/03/28 10:28:30
Callback is bound below.
Vladislav Kaznacheev
2012/03/28 14:00:57
It was not bound enough:) because the parameter to
| |
2517 unescape(selection.entries[0].name), | 2607 unescape(selection.entries[0].name), |
2518 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL), | 2608 strf('NO_ACTION_FOR_FILE', NO_ACTION_FOR_FILE_URL), |
2519 function() {}); | 2609 function() {}); |
2520 } | 2610 } |
2521 | 2611 |
2522 this.executeIfAvailable_(selection.urls, function(urls) { | 2612 this.executeIfAvailable_(selection.urls, function(urls) { |
2523 chrome.fileBrowserPrivate.viewFiles(urls, 'default', | 2613 chrome.fileBrowserPrivate.viewFiles(urls, 'default', |
2524 callback.bind(this)); | 2614 callback.bind(this)); |
2525 }); | 2615 }); |
2526 } | 2616 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2583 } | 2673 } |
2584 }; | 2674 }; |
2585 | 2675 |
2586 /** | 2676 /** |
2587 * Event handler called when some volume was mounted or unmouted. | 2677 * Event handler called when some volume was mounted or unmouted. |
2588 */ | 2678 */ |
2589 FileManager.prototype.onMountCompleted_ = function(event) { | 2679 FileManager.prototype.onMountCompleted_ = function(event) { |
2590 var self = this; | 2680 var self = this; |
2591 | 2681 |
2592 var changeDirectoryTo = null; | 2682 var changeDirectoryTo = null; |
2683 var setupInitialDirectory = false; | |
2593 | 2684 |
2594 if (event && event.mountType == 'gdata') { | 2685 if (event && event.mountType == 'gdata') { |
2595 metrics.recordInterval('Load.GData'); | 2686 metrics.recordInterval('Load.GData'); |
2596 if (this.gdataMountTimer_) { | 2687 console.log("GData mounted"); |
2597 clearTimeout(this.gdataMountTimer_); | 2688 // Not calling clearGDataLoadingTimer_ here because we want to keep |
dgozman
2012/03/28 10:28:30
Is the following possible?
- requesting gdata moun
Vladislav Kaznacheev
2012/03/28 14:00:57
Yes. This is intended (see http://code.google.com/
| |
2598 this.gdataMountTimer_ = null; | 2689 // "Loading Google Docs" message until the directory loads. It is OK if |
2599 } | 2690 // the timer fires after the mount because onDirectoryChanged_will hide |
dgozman
2012/03/28 10:28:30
typo: onDirectoryChanged_will
Vladislav Kaznacheev
2012/03/28 14:00:57
Done.
| |
2691 // the unmounted panel. | |
2600 if (event.status == 'success') { | 2692 if (event.status == 'success') { |
2601 this.gdataMounted_ = true; | 2693 this.gdataMounted_ = true; |
2602 this.gdataMountInfo_ = { | 2694 this.gdataMountInfo_ = { |
2603 "mountPath": event.mountPath, | 2695 "mountPath": event.mountPath, |
2604 "sourceUrl": event.sourceUrl, | 2696 "sourceUrl": event.sourceUrl, |
2605 "mountType": event.mountType, | 2697 "mountType": event.mountType, |
2606 "mountCondition": event.status | 2698 "mountCondition": event.status |
2607 }; | 2699 }; |
2608 if (this.isOnGData()) { | 2700 if (self.setupGDataDirectoryAfterMount_) { |
2701 setupInitialDirectory = true; | |
2702 } else if (this.isOnGData() && | |
2703 this.directoryModel_.currentEntry.unmounted) { | |
2609 // We are currently on an unmounted GData directory, force a rescan. | 2704 // We are currently on an unmounted GData directory, force a rescan. |
2610 changeDirectoryTo = this.directoryModel_.rootPath; | 2705 changeDirectoryTo = this.directoryModel_.rootPath; |
2611 } | 2706 } |
2612 } else { | 2707 } else { |
2708 this.clearGDataLoadingTimer_(); | |
2709 this.onGDataUnreachable_('GData mount failed: ' + event.status); | |
2613 this.gdataMounted_ = false; | 2710 this.gdataMounted_ = false; |
2614 this.gdataMountInfo_ = null; | 2711 this.gdataMountInfo_ = null; |
2615 } | 2712 } |
2616 } | 2713 } |
2617 | 2714 |
2618 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { | 2715 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { |
2619 self.setMountPoints_(mountPoints); | 2716 self.setMountPoints_(mountPoints); |
2620 if (event.eventType == 'mount') { | 2717 if (event.eventType == 'mount') { |
2621 // Mount request finished - remove it. | 2718 // Mount request finished - remove it. |
2622 var index = self.mountRequests_.indexOf(event.sourceUrl); | 2719 var index = self.mountRequests_.indexOf(event.sourceUrl); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2657 return; | 2754 return; |
2658 } | 2755 } |
2659 // Current durectory just unmounted. Move to the 'Downloads'. | 2756 // Current durectory just unmounted. Move to the 'Downloads'. |
2660 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY; | 2757 changeDirectoryTo = '/' + DirectoryModel.DOWNLOADS_DIRECTORY; |
2661 } | 2758 } |
2662 | 2759 |
2663 // Even if something failed root list should be rescanned. | 2760 // Even if something failed root list should be rescanned. |
2664 // Failed mounts can "give" us new devices which might be formatted, | 2761 // Failed mounts can "give" us new devices which might be formatted, |
2665 // so we have to refresh root list then. | 2762 // so we have to refresh root list then. |
2666 self.directoryModel_.updateRoots(function() { | 2763 self.directoryModel_.updateRoots(function() { |
2764 if (setupInitialDirectory && self.setupGDataDirectoryAfterMount_) { | |
dgozman
2012/03/28 10:28:30
I think, setupInitialDirectory is true if and only
Vladislav Kaznacheev
2012/03/28 14:00:57
I got rid of this variable completely.
On 2012/03
| |
2765 self.setupGDataDirectoryAfterMount_(); | |
2766 } | |
2667 if (changeDirectoryTo) { | 2767 if (changeDirectoryTo) { |
2668 self.directoryModel_.changeDirectory(changeDirectoryTo); | 2768 self.directoryModel_.changeDirectory(changeDirectoryTo); |
2669 } | 2769 } |
2670 }); | 2770 }, self.gdataMounted_); |
2671 }); | 2771 }); |
2672 }; | 2772 }; |
2673 | 2773 |
2674 /** | 2774 /** |
2675 * Event handler called when some internal task should be executed. | 2775 * Event handler called when some internal task should be executed. |
2676 */ | 2776 */ |
2677 FileManager.prototype.onFileTaskExecute_ = function(id, urls) { | 2777 FileManager.prototype.onFileTaskExecute_ = function(id, urls) { |
2678 if (id == 'play') { | 2778 if (id == 'play') { |
2679 var position = 0; | 2779 var position = 0; |
2680 if (urls.length == 1) { | 2780 if (urls.length == 1) { |
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3550 } | 3650 } |
3551 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, | 3651 chrome.fileBrowserPrivate.removeFileWatch(this.watchedDirectoryUrl_, |
3552 function(result) { | 3652 function(result) { |
3553 if (!result) { | 3653 if (!result) { |
3554 console.log('Failed to remove file watch'); | 3654 console.log('Failed to remove file watch'); |
3555 } | 3655 } |
3556 }); | 3656 }); |
3557 this.watchedDirectoryUrl_ = null; | 3657 this.watchedDirectoryUrl_ = null; |
3558 } | 3658 } |
3559 | 3659 |
3560 if (event.newDirEntry.fullPath != '/') { | 3660 if (event.newDirEntry.fullPath != '/' && !event.newDirEntry.unmounted) { |
3561 this.watchedDirectoryUrl_ = event.newDirEntry.toURL(); | 3661 this.watchedDirectoryUrl_ = event.newDirEntry.toURL(); |
3562 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_, | 3662 chrome.fileBrowserPrivate.addFileWatch(this.watchedDirectoryUrl_, |
3563 function(result) { | 3663 function(result) { |
3564 if (!result) { | 3664 if (!result) { |
3565 console.log('Failed to add file watch'); | 3665 console.log('Failed to add file watch'); |
3566 this.watchedDirectoryUrl_ = null; | 3666 this.watchedDirectoryUrl_ = null; |
3567 } | 3667 } |
3568 }.bind(this)); | 3668 }.bind(this)); |
3569 } | 3669 } |
3570 | 3670 |
3571 this.updateVolumeMetadata_(); | 3671 this.updateVolumeMetadata_(); |
3572 | 3672 |
3673 if (event.newDirEntry.unmounted) | |
3674 this.dialogContainer_.setAttribute('unmounted', true); | |
3675 else | |
3676 this.dialogContainer_.removeAttribute('unmounted'); | |
3677 | |
3573 if (this.isOnGData()) { | 3678 if (this.isOnGData()) { |
3574 this.dialogContainer_.setAttribute('gdata', true); | 3679 this.dialogContainer_.setAttribute('gdata', true); |
3575 if (!this.requestedGDataMount_) { // Request GData mount only once. | 3680 if (event.newDirEntry.unmounted) { |
3576 this.requestedGDataMount_ = true; | 3681 this.initGData_(true /* directory changed */); |
3577 this.initGData_(); | |
3578 } | 3682 } |
3579 } else { | 3683 } else { |
3580 this.dialogContainer_.removeAttribute('gdata'); | 3684 this.dialogContainer_.removeAttribute('gdata'); |
3581 } | 3685 } |
3686 | |
3687 // Manual directory change cancels the GData directory setup. | |
3688 this.setupGDataDirectoryAfterMount_ = null; | |
3582 }; | 3689 }; |
3583 | 3690 |
3584 FileManager.prototype.updateVolumeMetadata_ = function() { | 3691 FileManager.prototype.updateVolumeMetadata_ = function() { |
3585 var dm = this.directoryModel_; | 3692 var dm = this.directoryModel_; |
3586 if (!dm) return; | 3693 if (!dm) return; |
3587 | 3694 |
3588 // Only request metadata for removable devices and archives. | 3695 // Only request metadata for removable devices and archives. |
3589 var rootType = dm.rootType; | 3696 var rootType = dm.rootType; |
3590 if (rootType != DirectoryModel.RootType.REMOVABLE && | 3697 if (rootType != DirectoryModel.RootType.REMOVABLE && |
3591 rootType != DirectoryModel.RootType.ARCHIVE) | 3698 rootType != DirectoryModel.RootType.ARCHIVE) |
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4432 }); | 4539 }); |
4433 }, onError); | 4540 }, onError); |
4434 | 4541 |
4435 function onError(err) { | 4542 function onError(err) { |
4436 console.log('Error while checking free space: ' + err); | 4543 console.log('Error while checking free space: ' + err); |
4437 setTimeout(doCheck, 1000 * 60); | 4544 setTimeout(doCheck, 1000 * 60); |
4438 } | 4545 } |
4439 } | 4546 } |
4440 } | 4547 } |
4441 })(); | 4548 })(); |
OLD | NEW |