Skip to content

Commit

Permalink
FilesApp set crostini Linux Files root from fileManager
Browse files Browse the repository at this point in the history
Set NavigationListModel.linuxFilesItems async from FileManager
to allow directoryTree redraw which is required to show the item
when FilesApp first launches.

Remove specialized SFTPMountItem class and combine Recent and
Linux Files to use NavigationModelFakeItem and
DirectoryTree/FakeItem.

Bug: 834103
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: Ie840c8826368df5c63b608dcc5be59601f6452cb
Reviewed-on: https://chromium-review.googlesource.com/1059368
Commit-Queue: Joel Hockey <joelhockey@chromium.org>
Reviewed-by: Noel Gordon <noel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#558665}
  • Loading branch information
Joel Hockey authored and Commit Bot committed May 15, 2018
1 parent 269fa69 commit c4ce38e
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 149 deletions.
8 changes: 4 additions & 4 deletions ui/file_manager/file_manager/foreground/css/file_types.css
Original file line number Diff line number Diff line change
Expand Up @@ -431,16 +431,16 @@ cr-menu-item[command='#install-new-extension'] .icon.start {
url(../images/volumes/2x/recent_active.png) 2x);
}

[sftp-mount-icon='linux-files'],
[volume-subtype='crostini'] {
[root-type-icon='crostini'],
[volume-type-icon='crostini'] {
/* Need !important to override inline style applied to provided volumes. */
background-image: -webkit-image-set(
url(../images/volumes/linux_files.png) 1x,
url(../images/volumes/2x/linux_files.png) 2x) !important;
}

.tree-row[selected] [sftp-mount-icon='linux-files'],
.tree-row[selected] [volume-subtype='crostini'] {
.tree-row[selected] [root-type-icon='crostini'],
.tree-row[selected] [volume-type-icon='crostini'] {
/* Need !important to override inline style applied to provided volumes. */
background-image: -webkit-image-set(
url(../images/volumes/linux_files_active.png) 1x,
Expand Down
16 changes: 15 additions & 1 deletion ui/file_manager/file_manager/foreground/js/file_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ FileManager.prototype = /** @struct */ {
assert(this.volumeManager_), assert(this.folderShortcutsModel_),
fakeEntriesVisible &&
!DialogType.isFolderDialog(this.launchParams_.type) ?
new NavigationModelRecentItem(str('RECENT_ROOT_LABEL'), {
new NavigationModelFakeItem(str('RECENT_ROOT_LABEL'), {
isDirectory: true,
rootType: VolumeManagerCommon.RootType.RECENT,
toURL: function() {
Expand All @@ -1182,6 +1182,20 @@ FileManager.prototype = /** @struct */ {
str('ADD_NEW_SERVICES_BUTTON_LABEL'), '#add-new-services-menu',
'add-new-services') :
null);
// Check if crostini is enabled to create linuxFilesItem.
chrome.fileManagerPrivate.isCrostiniEnabled((enabled) => {
if (!enabled)
return;
this.directoryTree.dataModel.linuxFilesItem =
new NavigationModelFakeItem(str('LINUX_FILES_ROOT_LABEL'), {
isDirectory: true,
rootType: VolumeManagerCommon.RootType.CROSTINI,
toURL: function() {
return 'fake-entry://linux-files';
},
});
this.directoryTree.redraw(false);
});
this.ui_.initDirectoryTree(directoryTree);
};

Expand Down
90 changes: 24 additions & 66 deletions ui/file_manager/file_manager/foreground/js/navigation_list_model.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ var NavigationModelItemType = {
VOLUME: 'volume',
MENU: 'menu',
RECENT: 'recent',
SFTP_MOUNT: 'sftp_mount',
CROSTINI: 'crostini',
};

/**
Expand Down Expand Up @@ -111,70 +111,32 @@ NavigationModelMenuItem.prototype = /** @struct */ {
};

/**
* Item of NavigationListModel for a Recent view.
* Item of NavigationListModel for a fake item such as Recent or Linux Files.
*
* @param {string} label Label on the menu button.
* @param {!FakeEntry} entry Fake entry for the Recent root folder.
* @param {!FakeEntry} entry Fake entry for the root folder.
* @constructor
* @extends {NavigationModelItem}
* @struct
*/
function NavigationModelRecentItem(label, entry) {
function NavigationModelFakeItem(label, entry) {
NavigationModelItem.call(this, label, NavigationModelItemType.RECENT);
this.entry_ = entry;
}

NavigationModelRecentItem.prototype = /** @struct */ {
NavigationModelFakeItem.prototype = /** @struct */ {
__proto__: NavigationModelItem.prototype,
get entry() {
return this.entry_;
}
};

/**
* Item of NavigationListModel for an SFTP Mount as used by Linux files.
*
* @param {string} label Label on the item.
* @param {!FakeEntry} entry Fake entry for the SFTP Mount root folder.
* @param {string} icon CSS icon.
* @constructor
* @extends {NavigationModelItem}
* @struct
*/
function NavigationModelSFTPMountItem(label, entry, icon) {
NavigationModelItem.call(this, label, NavigationModelItemType.SFTP_MOUNT);
this.entry_ = entry;
this.icon_ = icon;
}

NavigationModelSFTPMountItem.prototype = /** @struct */ {
__proto__: NavigationModelItem.prototype,
get entry() {
return this.entry_;
},
get icon() {
return this.icon_;
},
/**
* Start crostini container and mount it.
*/
mount: function() {
chrome.fileManagerPrivate.mountCrostiniContainer(() => {
// TODO(crbug.com/834103): implement crostini error handling.
if (chrome.runtime.lastError) {
console.error(
'mountCrostiniContainer error: ', chrome.runtime.lastError.message);
}
});
},
};

/**
* A navigation list model. This model combines multiple models.
* @param {!VolumeManagerWrapper} volumeManager VolumeManagerWrapper instance.
* @param {(!cr.ui.ArrayDataModel|!FolderShortcutsDataModel)} shortcutListModel
* The list of folder shortcut.
* @param {NavigationModelRecentItem} recentModelItem Recent folder.
* @param {NavigationModelFakeItem} recentModelItem Recent folder.
* @param {NavigationModelMenuItem} addNewServicesItem Add new services item.
* @constructor
* @extends {cr.EventTarget}
Expand All @@ -196,7 +158,7 @@ function NavigationListModel(
this.shortcutListModel_ = shortcutListModel;

/**
* @private {NavigationModelRecentItem}
* @private {NavigationModelFakeItem}
* @const
*/
this.recentModelItem_ = recentModelItem;
Expand All @@ -205,7 +167,7 @@ function NavigationListModel(
* Root folder for crostini Linux Files.
* This field will be set asynchronously after calling
* chrome.fileManagerPrivate.isCrostiniEnabled.
* @private {NavigationModelSFTPMountItem}
* @private {NavigationModelFakeItem}
*/
this.linuxFilesItem_ = null;

Expand Down Expand Up @@ -256,24 +218,6 @@ function NavigationListModel(
this.shortcutList_.push(entryToModelItem(shortcutEntry));
}

// Check if crostini is enabled to create linuxFilesItem_.
chrome.fileManagerPrivate.isCrostiniEnabled((enabled) => {
if (!enabled)
return;

this.linuxFilesItem_ = new NavigationModelSFTPMountItem(
str('LINUX_FILES_ROOT_LABEL'), {
isDirectory: true,
rootType: VolumeManagerCommon.RootType.CROSTINI,
toURL: function() {
return 'fake-entry://linux-files';
},
},
'linux-files');
// Reorder items to ensure Linux Files is shown.
this.reorderNavigationItems_();
});

// Reorder volumes, shortcuts, and optional items for initial display.
this.reorderNavigationItems_();

Expand Down Expand Up @@ -388,8 +332,22 @@ function NavigationListModel(
*/
NavigationListModel.prototype = {
__proto__: cr.EventTarget.prototype,
get length() { return this.length_(); },
get folderShortcutList() { return this.shortcutList_; }
get length() {
return this.length_();
},
get folderShortcutList() {
return this.shortcutList_;
},
/**
* Set the crostini Linux Files root and reorder items.
* This setter is provided separate to the constructor since
* this field is set async after calling fileManagerPrivate.isCrostiniEnabled.
* @param {NavigationModelFakeItem} item Linux Files root.
*/
set linuxFilesItem(item) {
this.linuxFilesItem_ = item;
this.reorderNavigationItems_();
},
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,7 @@ function setUp() {
// Override VolumeInfo.prototype.resolveDisplayRoot.
VolumeInfoImpl.prototype.resolveDisplayRoot = function() {};

// Mock chrome.fileManagerPrivate.isCrostiniEnabled.
// TODO(crbug.com/834103): Add integration test for Crostini.
chrome.fileManagerPrivate = {
crostiniEnabled: false,
isCrostiniEnabled: function(callback) {
callback(this.crostiniEnabled);
},
};

drive = new MockFileSystem('drive');
hoge = new MockFileSystem('removable:hoge');
}
Expand All @@ -37,17 +29,14 @@ function testModel() {
var volumeManager = new MockVolumeManagerWrapper();
var shortcutListModel = new MockFolderShortcutDataModel(
[new MockFileEntry(drive, '/root/shortcut')]);
var fakeEntry = {
toURL: function() {
return 'fake-entry://recent';
}
};
var recentItem = new NavigationModelRecentItem('recent-label', fakeEntry);
chrome.fileManagerPrivate.crostiniEnabled = true;
var recentItem = new NavigationModelFakeItem(
'recent-label', {toURL: () => 'fake-entry://recent'});
var addNewServicesItem = new NavigationModelMenuItem(
'menu-button-label', '#add-new-services', 'menu-button-icon');
var model = new NavigationListModel(
volumeManager, shortcutListModel, recentItem, addNewServicesItem);
model.linuxFilesItem = new NavigationModelFakeItem(
'linux-files-label', {toURL: () => 'fake-entry://linux-files'});

assertEquals(6, model.length);
assertEquals('drive', model.item(0).volumeInfo.volumeId);
Expand Down
86 changes: 23 additions & 63 deletions ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -1116,21 +1116,24 @@ MenuItem.prototype.activate = function() {
};

////////////////////////////////////////////////////////////////////////////////
// RecentItem
// FakeItem

/**
* @param {!NavigationModelRecentItem} modelItem
* FakeItem is used by Recent and Linux Files.
* @param {!VolumeManagerCommon.RootType} rootType root type.
* @param {!NavigationModelFakeItem} modelItem
* @param {!DirectoryTree} tree Current tree, which contains this item.
* @extends {cr.ui.TreeItem}
* @constructor
*/
function RecentItem(modelItem, tree) {
function FakeItem(rootType, modelItem, tree) {
var item = new cr.ui.TreeItem();
// Get the original label id defined by TreeItem, before overwriting
// prototype.
var labelId = item.labelElement.id;
item.__proto__ = RecentItem.prototype;
item.__proto__ = FakeItem.prototype;

item.rootType_ = rootType;
item.parentTree_ = tree;
item.modelItem_ = modelItem;
item.dirEntry_ = modelItem.entry;
Expand All @@ -1140,12 +1143,12 @@ function RecentItem(modelItem, tree) {

var icon = queryRequiredElement('.icon', item);
icon.classList.add('item-icon');
icon.setAttribute('root-type-icon', 'recent');
icon.setAttribute('root-type-icon', rootType);

return item;
}

RecentItem.prototype = {
FakeItem.prototype = {
__proto__: cr.ui.TreeItem.prototype,
get entry() {
return this.dirEntry_;
Expand All @@ -1162,84 +1165,35 @@ RecentItem.prototype = {
* @param {!DirectoryEntry|!FakeEntry} entry
* @return {boolean} True if the parent item is found.
*/
RecentItem.prototype.searchAndSelectByEntry = function(entry) {
FakeItem.prototype.searchAndSelectByEntry = function(entry) {
return false;
};

/**
* @override
*/
RecentItem.prototype.handleClick = function(e) {
FakeItem.prototype.handleClick = function(e) {
this.activate();

DirectoryItemTreeBaseMethods.recordUMASelectedEntry.call(
this, e, VolumeManagerCommon.RootType.RECENT, true);
this, e, this.rootType_, true);
};

/**
* @param {!DirectoryEntry} entry
*/
RecentItem.prototype.selectByEntry = function(entry) {
FakeItem.prototype.selectByEntry = function(entry) {
if (util.isSameEntry(entry, this.entry))
this.selected = true;
};

/**
* Executes the command.
*/
RecentItem.prototype.activate = function() {
FakeItem.prototype.activate = function() {
this.parentTree_.directoryModel.activateDirectoryEntry(this.entry);
};

////////////////////////////////////////////////////////////////////////////////
// SFTPMountItem

/**
* A TreeItem which represents a directory to be mounted using SFTP.
*
* @param {!NavigationModelSFTPMountItem} modelItem
* @param {!DirectoryTree} tree Current tree, which contains this item.
* @extends {cr.ui.TreeItem}
* @constructor
*/
function SFTPMountItem(modelItem, tree) {
var item = new cr.ui.TreeItem();
item.__proto__ = SFTPMountItem.prototype;

item.parentTree_ = tree;
item.modelItem_ = modelItem;
item.innerHTML = TREE_ITEM_INNER_HTML;
item.label = modelItem.label;

var icon = queryRequiredElement('.icon', item);
icon.classList.add('item-icon');
icon.setAttribute('sftp-mount-icon', item.modelItem_.icon);

return item;
}

SFTPMountItem.prototype = {
__proto__: cr.ui.TreeItem.prototype,
get entry() {
return null;
},
get modelItem() {
return this.modelItem_;
},
get labelElement() {
return this.firstElementChild.querySelector('.label');
}
};

/**
* @override
*/
SFTPMountItem.prototype.handleClick = function(e) {
this.selected = true;
this.modelItem_.mount();
};


////////////////////////////////////////////////////////////////////////////////
// DirectoryTree

Expand Down Expand Up @@ -1426,10 +1380,16 @@ DirectoryTree.prototype.updateSubElementsFromList = function(recursive) {
this.addAt(new MenuItem(modelItem, this), itemIndex);
break;
case NavigationModelItemType.RECENT:
this.addAt(new RecentItem(modelItem, this), itemIndex);
this.addAt(
new FakeItem(
VolumeManagerCommon.RootType.RECENT, modelItem, this),
itemIndex);
break;
case NavigationModelItemType.SFTP_MOUNT:
this.addAt(new SFTPMountItem(modelItem, this), itemIndex);
case NavigationModelItemType.CROSTINI:
this.addAt(
new FakeItem(
VolumeManagerCommon.RootType.CROSTINI, modelItem, this),
itemIndex);
break;
}
}
Expand Down

0 comments on commit c4ce38e

Please sign in to comment.