Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: chrome/browser/resources/file_manager/js/file_manager.js

Issue 9855024: Postpone connecting to GData even more, provide progress indication. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Showing progress when opening File Manager on a GData path Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698