From c19450e7aa5f28e455d7ba8ff0f83da3571fce3e Mon Sep 17 00:00:00 2001 From: ryoh Date: Fri, 11 Mar 2016 00:27:25 -0800 Subject: Create a details panel that displays informations for a single file. It currently shows just a filename of selected file. I will make this panel display more information later. BUG=274045 TEST=ninja -j200 -C out/Release chrome chrome_sandbox browser_tests && out/Release/browser_tests --gtest_filter=DetailsPanel/FileManagerBrowserTest.Test/\* --enable-pixel-output-in-tests '--remote-debugging-port=8080' --enable-files-details-panel Review URL: https://codereview.chromium.org/1774093002 Cr-Commit-Position: refs/heads/master@{#380580} --- .../file_manager/foreground/css/file_manager.css | 18 +++ .../foreground/js/compiled_resources.gyp | 1 + .../file_manager/foreground/js/file_manager.js | 5 + .../file_manager/foreground/js/main_scripts.js | 1 + .../foreground/js/ui/details_container.js | 22 +++- .../foreground/js/ui/file_manager_ui.js | 11 +- .../foreground/js/ui/single_file_details.js | 130 +++++++++++++++++++++ ui/file_manager/file_manager/main.html | 4 + .../file_manager/details_panel.js | 59 ++++++++++ .../file_manager_test_manifest.json | 1 + 10 files changed, 247 insertions(+), 5 deletions(-) create mode 100644 ui/file_manager/file_manager/foreground/js/ui/single_file_details.js create mode 100644 ui/file_manager/integration_tests/file_manager/details_panel.js (limited to 'ui/file_manager') diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index f83f14f..c05be9d 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css @@ -127,11 +127,13 @@ a:focus { /* Details pane */ .details-container { background-color: rgb(250, 250, 250); + display: flex; flex: none; max-width: 30%; min-width: 100px; overflow: hidden; position: relative; + width: 240px; } #list-details-splitter:not([activated]) { @@ -142,6 +144,22 @@ a:focus { display: none; } +.details-container > div:not([activated]) { + display: none !important; +} + +.details-container > #single-file-details { + display: flex; + flex: auto; + flex-direction: row; + width: 100%; +} + +#single-file-details > .details-list { + flex: auto; + width: 100%; +} + /* Directory tree at the left. */ .dialog-navigation-list { -webkit-border-end: 1px solid rgba(0, 0, 0, 0.15); diff --git a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp index 9b9a5da..e000c3d 100644 --- a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp +++ b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp @@ -147,6 +147,7 @@ './ui/scrollbar.js', './ui/search_box.js', './ui/share_dialog.js', + './ui/single_file_details.js', './ui/suggest_apps_dialog.js', './main_window_component.js', './volume_manager_wrapper.js', diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index 811a998..e808134 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js @@ -833,12 +833,17 @@ FileManager.prototype = /** @struct */ { this.metadataModel_, this.volumeManager_, this.historyLoader_); + var singlePanel = queryRequiredElement('#single-file-details', dom); + SingleFileDetailsPanel.decorate( + assertInstanceof(singlePanel, HTMLDivElement), + this.metadataModel_); this.addHistoryObserver_(); this.ui_.initAdditionalUI( assertInstanceof(table, FileTable), assertInstanceof(grid, FileGrid), + assertInstanceof(singlePanel, SingleFileDetailsPanel), new LocationLine( queryRequiredElement('#location-breadcrumbs', dom), this.volumeManager_)); diff --git a/ui/file_manager/file_manager/foreground/js/main_scripts.js b/ui/file_manager/file_manager/foreground/js/main_scripts.js index c7c905a..7a053ab 100644 --- a/ui/file_manager/file_manager/foreground/js/main_scripts.js +++ b/ui/file_manager/file_manager/foreground/js/main_scripts.js @@ -163,6 +163,7 @@ // // // +// // // // diff --git a/ui/file_manager/file_manager/foreground/js/ui/details_container.js b/ui/file_manager/file_manager/foreground/js/ui/details_container.js index 1d54bad..298f607 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/details_container.js +++ b/ui/file_manager/file_manager/foreground/js/ui/details_container.js @@ -4,13 +4,15 @@ /** * @param {!HTMLElement} element + * @param {!SingleFileDetailsPanel} singlePanel * @param {!Element} splitter * @param {!Element} button * @param {!FilesToggleRipple} toggleRipple * @constructor * @struct */ -function DetailsContainer(element, splitter, button, toggleRipple) { +function DetailsContainer(element, singlePanel, splitter, button, + toggleRipple) { /** * Container element. * @private {!HTMLElement} @@ -36,6 +38,12 @@ function DetailsContainer(element, splitter, button, toggleRipple) { */ this.toggleRipple_ = toggleRipple; /** + * Details panel for a single file. + * @private {!SingleFileDetailsPanel} + * @const + */ + this.singlePanel_ = singlePanel; + /** * @type {boolean} */ this.visible = false; @@ -43,7 +51,17 @@ function DetailsContainer(element, splitter, button, toggleRipple) { } DetailsContainer.prototype.onFileSelectionChanged = function(event) { - var selection = event.target.selection; + var entries = event.target.selection.entries; + if (entries.length === 0) { + this.singlePanel_.removeAttribute('activated'); + this.singlePanel_.classList.toggle('activated', false); + // TODO(ryoh): make a panel for empty selection + } else if (entries.length === 1) { + this.singlePanel_.setAttribute('activated', ''); + this.singlePanel_.onFileSelectionChanged(entries[0]); + } else { + // TODO(ryoh): make a panel for multiple selection + } }; /** diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js index 4c04632..4459932 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js +++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js @@ -338,10 +338,11 @@ function FileManagerUI(providersModel, element, launchParam) { * * @param {!FileTable} table * @param {!FileGrid} grid + * @param {!SingleFileDetailsPanel} singlePanel * @param {!LocationLine} locationLine */ FileManagerUI.prototype.initAdditionalUI = function( - table, grid, locationLine) { + table, grid, singlePanel, locationLine) { // List container. this.listContainer = new ListContainer( queryRequiredElement('#list-container', this.element), table, grid); @@ -357,9 +358,10 @@ FileManagerUI.prototype.initAdditionalUI = function( this.detailsButton.style.display = 'block'; var listDetailsSplitter = queryRequiredElement('#list-details-splitter', this.element); - this.decorateSplitter_(listDetailsSplitter); + this.decorateSplitter_(listDetailsSplitter, true); this.detailsContainer = new DetailsContainer( queryRequiredElement('#details-container', this.element), + singlePanel, listDetailsSplitter, this.detailsButton, this.detailsButtonToggleRipple_); @@ -515,9 +517,11 @@ FileManagerUI.prototype.onExternalLinkClick_ = function(event) { /** * Decorates the given splitter element. * @param {!HTMLElement} splitterElement + * @param {boolean=} opt_resizeNextElement * @private */ -FileManagerUI.prototype.decorateSplitter_ = function(splitterElement) { +FileManagerUI.prototype.decorateSplitter_ = function(splitterElement, + opt_resizeNextElement) { var self = this; var Splitter = cr.ui.Splitter; var customSplitter = cr.ui.define('div'); @@ -542,4 +546,5 @@ FileManagerUI.prototype.decorateSplitter_ = function(splitterElement) { }; customSplitter.decorate(splitterElement); + splitterElement.resizeNextElement = !!opt_resizeNextElement; }; diff --git a/ui/file_manager/file_manager/foreground/js/ui/single_file_details.js b/ui/file_manager/file_manager/foreground/js/ui/single_file_details.js new file mode 100644 index 0000000..5329e1c --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/ui/single_file_details.js @@ -0,0 +1,130 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + + +/** + * SingleFileDetailsPanel constructor. + * + * Represents grid for the details panel for a single file in Files app. + * @constructor + * @extends {HTMLDivElement} + */ +function SingleFileDetailsPanel() { + throw new Error('Use SingleFileDetailsList.decorate'); +} + +/** + * Inherits from cr.ui.List. + */ +SingleFileDetailsPanel.prototype = { + __proto__: HTMLDivElement.prototype, + onFileSelectionChanged: function(entry) { + this.filename_.textContent = entry.name; + } +}; + +/** + * Decorates an HTML element to be a SingleFileDetailsList. + * @param {!HTMLDivElement} self The grid to decorate. + * @param {!MetadataModel} metadataModel File system metadata. + */ +SingleFileDetailsPanel.decorate = function(self, metadataModel) { + self.__proto__ = SingleFileDetailsPanel.prototype; + self.metadataModel = metadataModel; + /** + * Data model of detail infos. + * @private {!SingleFileDetailsDataModel} + * @const + */ + self.model_ = new SingleFileDetailsDataModel(); + self.filename_ = assertInstanceof(queryRequiredElement('.filename', self), + HTMLDivElement); + var list = queryRequiredElement('.details-list', self); + SingleFileDetailsList.decorate(list, metadataModel); + self.list_ = assertInstanceof(list, SingleFileDetailsList); + self.list_.dataModel = self.model_; + self.list_.autoExpands = true; +}; + +/** + * SingleFileDetailsList constructor. + * + * Represents grid for the details list for a single file in Files app. + * @constructor + * @extends {cr.ui.List} + */ +function SingleFileDetailsList() { + throw new Error('Use SingleFileDetailsList.decorate'); +} + +/** + * Inherits from cr.ui.List. + */ +SingleFileDetailsList.prototype = { + __proto__: cr.ui.List.prototype, + onFileSelectionChanged: function(entry) { + console.log(entry); + } +}; + +/** + * Decorates an HTML element to be a SingleFileDetailsList. + * @param {!Element} self The grid to decorate. + * @param {!MetadataModel} metadataModel File system metadata. + */ +SingleFileDetailsList.decorate = function(self, metadataModel) { + cr.ui.Grid.decorate(self); + self.__proto__ = SingleFileDetailsList.prototype; + self.metadataModel_ = metadataModel; + + self.scrollBar_ = new ScrollBar(); + self.scrollBar_.initialize(self.parentElement, self); + + self.itemConstructor = function(entry) { + var item = self.ownerDocument.createElement('li'); + SingleFileDetailsList.Item.decorate( + item, + entry, + /** @type {FileGrid} */ (self)); + return item; + }; +}; + +/** + * Item for the Grid View. + * @constructor + * @extends {cr.ui.ListItem} + */ +SingleFileDetailsList.Item = function() { + throw new Error(); +}; + +/** + * Inherits from cr.ui.DetailsItem. + */ +SingleFileDetailsList.Item.prototype.__proto__ = cr.ui.ListItem.prototype; + +/** + * @param {Element} li List item element. + * @param {!Entry} entry File entry. + * @param {FileGrid} grid Owner. + */ +SingleFileDetailsList.Item.decorate = function(li, entry, grid) { + li.__proto__ = SingleFileDetailsList.Item.prototype; +}; + +/** + * Data model for details panel. + * + * @constructor + * @extends {cr.ui.ArrayDataModel} + */ +function SingleFileDetailsDataModel() { + cr.ui.ArrayDataModel.call(this, []); +} + +SingleFileDetailsDataModel.prototype = { + __proto__: cr.ui.ArrayDataModel.prototype, + +}; diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index 3639d5a..bc66610 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html @@ -411,6 +411,10 @@
+
+
+
    +