Commit 6b02fa35 authored by Jérémie Boulic's avatar Jérémie Boulic Committed by Chromium LUCI CQ

Files app: Generate JS module for foreground page

Convert JS files for directory_model.js and dependencies.

In //ui/file_manager/file_manager/foreground/js/:
- constants.js
- directory_contents.js
- directory_contents_unittest.m.js
- directory_model.js
- file_list_model.js
- file_list_model_unittest.m.js
- file_watcher.js

In //ui/file_manager/file_manager/foreground/js/ui/:
- file_list_selection_model.js
- file_list_selection_model_unittest.m.js

In //ui/file_manager/externs/:
- entries_changed_event.js

To avoid the circular dependency where directory_contents.js depends on
directoryModel and directory_model.js depends on DirectoryContents, the
constant `DirectoryModel.CROSTINI_CONNECT_ERR` in
//u/f/f/f/j/directory_model.js has been moved to
`constants.CROSTINI_CONNECT_ERR` in //u/f/f/f/j/constants.js.

Remove `DriveMetadataSearchContentScanner.SearchType`, which is a copy
of chrome.fileManagerPrivate.SearchType. This makes mocking easier in
directory_contents_unittest.m.js.

Bug: 1133186
Change-Id: I819da19a9f9c0ab380e4c35c7d6ca3672b2b3556
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2610413
Commit-Queue: Jeremie Boulic <jboulic@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#840482}
parent 7f695dd2
...@@ -46,7 +46,7 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DeviceHandlerTest) { ...@@ -46,7 +46,7 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DeviceHandlerTest) {
} }
IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DirectoryContentsTest) { IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DirectoryContentsTest) {
RunTestURL("foreground/js/directory_contents_unittest_gen.html"); RunTestURL("foreground/js/directory_contents_unittest.m_gen.html");
} }
IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DirectoryTreeTest) { IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DirectoryTreeTest) {
...@@ -71,11 +71,11 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ExternalMetadataProvider) { ...@@ -71,11 +71,11 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ExternalMetadataProvider) {
} }
IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileListModel) { IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileListModel) {
RunTestURL("foreground/js/file_list_model_unittest_gen.html"); RunTestURL("foreground/js/file_list_model_unittest.m_gen.html");
} }
IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileListSelectionModelTest) { IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileListSelectionModelTest) {
RunTestURL("foreground/js/ui/file_list_selection_model_unittest_gen.html"); RunTestURL("foreground/js/ui/file_list_selection_model_unittest.m_gen.html");
} }
IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileManagerCommandsTest) { IN_PROC_BROWSER_TEST_F(FileManagerJsTest, FileManagerCommandsTest) {
......
...@@ -66,6 +66,7 @@ group("unit_test_data") { ...@@ -66,6 +66,7 @@ group("unit_test_data") {
"file_manager/foreground/js:js_test_gen_html_modules", "file_manager/foreground/js:js_test_gen_html_modules",
"file_manager/foreground/js/metadata:js_test_gen_html_modules", "file_manager/foreground/js/metadata:js_test_gen_html_modules",
"file_manager/foreground/js/ui:js_test_gen_html", "file_manager/foreground/js/ui:js_test_gen_html",
"file_manager/foreground/js/ui:js_test_gen_html_modules",
"gallery/js:js_test_gen_html", "gallery/js:js_test_gen_html",
"gallery/js/image_editor:js_test_gen_html", "gallery/js/image_editor:js_test_gen_html",
"gallery/js/image_editor:js_test_gen_html_modules", "gallery/js/image_editor:js_test_gen_html_modules",
......
...@@ -26,6 +26,15 @@ js_library("background_window.m") { ...@@ -26,6 +26,15 @@ js_library("background_window.m") {
extra_deps = [ ":modulize" ] extra_deps = [ ":modulize" ]
} }
js_library("entries_changed_event.m") {
sources =
[ "$root_gen_dir/ui/file_manager/externs/entries_changed_event.m.js" ]
deps = [ "//ui/file_manager/file_manager/common/js:util.m" ]
extra_deps = [ ":modulize" ]
}
js_library("entry_location.m") { js_library("entry_location.m") {
sources = [ "$root_gen_dir/ui/file_manager/externs/entry_location.m.js" ] sources = [ "$root_gen_dir/ui/file_manager/externs/entry_location.m.js" ]
...@@ -122,6 +131,7 @@ js_library("volume_info_list.m") { ...@@ -122,6 +131,7 @@ js_library("volume_info_list.m") {
js_modulizer("modulize") { js_modulizer("modulize") {
input_files = [ input_files = [
"background_window.js", "background_window.js",
"entries_changed_event.js",
"entry_location.js", "entry_location.js",
"exif_entry.js", "exif_entry.js",
"files_app_entry_interfaces.js", "files_app_entry_interfaces.js",
......
...@@ -2,8 +2,21 @@ ...@@ -2,8 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
class EntriesChangedEvent extends Event { /**
constructor() { * @fileoverview
* @suppress {externsValidation} this file is used as externs and also
* as JS module, Closure fails to compile as JS module.
*/
// clang-format off
// #import {util} from '../file_manager/common/js/util.m.js';
// clang-format on
/* #export */ class EntriesChangedEvent extends Event {
/** @param {string} eventName */
constructor(eventName) {
super(eventName);
/** @type {util.EntryChangedKind} */ /** @type {util.EntryChangedKind} */
this.kind; this.kind;
......
...@@ -29,6 +29,11 @@ js_type_check("closure_compile_jsmodules") { ...@@ -29,6 +29,11 @@ js_type_check("closure_compile_jsmodules") {
uses_js_modules = true uses_js_modules = true
deps = [ deps = [
":android_app_list_model.m", ":android_app_list_model.m",
":constants.m",
":directory_contents.m",
":directory_model.m",
":file_list_model.m",
":file_watcher.m",
":thumbnail_loader.m", ":thumbnail_loader.m",
] ]
} }
...@@ -254,6 +259,14 @@ js_library("column_visibility_controller") { ...@@ -254,6 +259,14 @@ js_library("column_visibility_controller") {
js_library("constants") { js_library("constants") {
} }
js_library("constants.m") {
sources = [
"$root_gen_dir/ui/file_manager/file_manager/foreground/js/constants.m.js",
]
extra_deps = [ ":modulize" ]
}
js_library("crossover_search_utils") { js_library("crossover_search_utils") {
} }
...@@ -299,13 +312,33 @@ js_library("directory_contents") { ...@@ -299,13 +312,33 @@ js_library("directory_contents") {
] ]
} }
js_unittest("directory_contents_unittest") { js_library("directory_contents.m") {
sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/directory_contents.m.js" ]
deps = [ deps = [
":directory_contents", ":constants.m",
":directory_model", ":file_list_model.m",
"//ui/file_manager/base/js:test_error_reporting", "metadata:metadata_model.m",
"//ui/file_manager/base/js:volume_manager_types", "//ui/file_manager/base/js:volume_manager_types.m",
"//ui/file_manager/externs:volume_manager", "//ui/file_manager/externs:files_app_entry_interfaces.m",
"//ui/file_manager/externs:volume_manager.m",
"//ui/file_manager/file_manager/common/js:async_util.m",
"//ui/file_manager/file_manager/common/js:metrics.m",
"//ui/file_manager/file_manager/common/js:util.m",
"//ui/webui/resources/js:assert.m",
"//ui/webui/resources/js:cr.m",
"//ui/webui/resources/js/cr:event_target.m",
]
extra_deps = [ ":modulize" ]
}
js_unittest("directory_contents_unittest.m") {
deps = [
":directory_contents.m",
"//chrome/test/data/webui:chai_assert",
"//ui/file_manager/base/js:volume_manager_types.m",
"//ui/file_manager/externs:entry_location.m",
"//ui/file_manager/externs:volume_manager.m",
] ]
} }
...@@ -322,6 +355,34 @@ js_library("directory_model") { ...@@ -322,6 +355,34 @@ js_library("directory_model") {
] ]
} }
js_library("directory_model.m") {
sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/directory_model.m.js" ]
deps = [
":constants.m",
":directory_contents.m",
":file_list_model.m",
":file_watcher.m",
"metadata:metadata_model.m",
"ui:file_list_selection_model.m",
"//ui/file_manager/base/js:volume_manager_types.m",
"//ui/file_manager/externs:entries_changed_event.m",
"//ui/file_manager/externs:files_app_entry_interfaces.m",
"//ui/file_manager/externs:volume_info.m",
"//ui/file_manager/externs:volume_manager.m",
"//ui/file_manager/externs/background:file_operation_manager.m",
"//ui/file_manager/file_manager/common/js:async_util.m",
"//ui/file_manager/file_manager/common/js:metrics.m",
"//ui/file_manager/file_manager/common/js:util.m",
"//ui/webui/resources/js:assert.m",
"//ui/webui/resources/js:cr.m",
"//ui/webui/resources/js/cr:event_target.m",
"//ui/webui/resources/js/cr/ui:list_selection_model.m",
"//ui/webui/resources/js/cr/ui:list_single_selection_model.m",
]
extra_deps = [ ":modulize" ]
}
js_library("navigation_uma") { js_library("navigation_uma") {
deps = [ deps = [
":dialog_type", ":dialog_type",
...@@ -361,10 +422,25 @@ js_library("file_list_model") { ...@@ -361,10 +422,25 @@ js_library("file_list_model") {
] ]
} }
js_unittest("file_list_model_unittest") { js_library("file_list_model.m") {
sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/file_list_model.m.js" ]
deps = [ deps = [
":file_list_model", "metadata:metadata_model.m",
"//ui/webui/resources/js:webui_resource_test", "//ui/file_manager/externs:entry_location.m",
"//ui/file_manager/externs:volume_manager.m",
"//ui/file_manager/file_manager/common/js:file_type.m",
"//ui/file_manager/file_manager/common/js:util.m",
"//ui/webui/resources/js/cr/ui:array_data_model.m",
]
extra_deps = [ ":modulize" ]
}
js_unittest("file_list_model_unittest.m") {
deps = [
":file_list_model.m",
"metadata:metadata_model.m",
"//chrome/test/data/webui:chai_assert",
] ]
} }
...@@ -539,6 +615,19 @@ js_library("file_watcher") { ...@@ -539,6 +615,19 @@ js_library("file_watcher") {
] ]
} }
js_library("file_watcher.m") {
sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/file_watcher.m.js" ]
deps = [
"//ui/file_manager/externs:files_app_entry_interfaces.m",
"//ui/file_manager/file_manager/common/js:async_util.m",
"//ui/file_manager/file_manager/common/js:util.m",
"//ui/webui/resources/js:assert.m",
"//ui/webui/resources/js/cr:event_target.m",
]
extra_deps = [ ":modulize" ]
}
js_library("folder_shortcuts_data_model") { js_library("folder_shortcuts_data_model") {
deps = [ deps = [
"//ui/file_manager/base/js:filtered_volume_manager", "//ui/file_manager/base/js:filtered_volume_manager",
...@@ -884,7 +973,11 @@ js_library("webui_command_extender") { ...@@ -884,7 +973,11 @@ js_library("webui_command_extender") {
} }
js_test_gen_html("js_test_gen_html_modules") { js_test_gen_html("js_test_gen_html_modules") {
deps = [ ":thumbnail_loader_unittest.m" ] deps = [
":directory_contents_unittest.m",
":file_list_model_unittest.m",
":thumbnail_loader_unittest.m",
]
js_module = true js_module = true
closure_flags = closure_flags =
...@@ -899,8 +992,6 @@ js_test_gen_html("js_test_gen_html_modules") { ...@@ -899,8 +992,6 @@ js_test_gen_html("js_test_gen_html_modules") {
js_test_gen_html("js_test_gen_html") { js_test_gen_html("js_test_gen_html") {
deps = [ deps = [
":actions_model_unittest", ":actions_model_unittest",
":directory_contents_unittest",
":file_list_model_unittest",
":file_manager_commands_unittest", ":file_manager_commands_unittest",
":file_tasks_unittest", ":file_tasks_unittest",
":file_transfer_controller_unittest", ":file_transfer_controller_unittest",
...@@ -919,6 +1010,11 @@ js_modulizer("modulize") { ...@@ -919,6 +1010,11 @@ js_modulizer("modulize") {
input_files = [ input_files = [
"android_app_list_model.js", "android_app_list_model.js",
"thumbnail_loader.js", "thumbnail_loader.js",
"constants.js",
"directory_model.js",
"directory_contents.js",
"file_list_model.js",
"file_watcher.js",
] ]
namespace_rewrites = cr_namespace_rewrites namespace_rewrites = cr_namespace_rewrites
......
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/**
* @fileoverview
* @suppress {uselessCode} Temporary suppress because of the line exporting.
*/
/** /**
* Namespace for common constnats used in Files app. * Namespace for common constnats used in Files app.
* @namespace * @namespace
...@@ -97,3 +102,12 @@ constants.DEFAULT_CROSTINI_VM = 'termina'; ...@@ -97,3 +102,12 @@ constants.DEFAULT_CROSTINI_VM = 'termina';
* @const * @const
*/ */
constants.PLUGIN_VM = 'PvmDefault'; constants.PLUGIN_VM = 'PvmDefault';
/**
* DOMError type for crostini connection failure.
* @const {string}
*/
constants.CROSTINI_CONNECT_ERR = 'CrostiniConnectErr';
// eslint-disable-next-line semi,no-extra-semi
/* #export */ {constants};
...@@ -2,10 +2,25 @@ ...@@ -2,10 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// clang-format off
// #import {MetadataModel} from './metadata/metadata_model.m.js';
// #import {VolumeManager} from '../../../externs/volume_manager.m.js';
// #import {FilesAppDirEntry, FakeEntry} from '../../../externs/files_app_entry_interfaces.m.js';
// #import {FileListModel} from './file_list_model.m.js';
// #import {AsyncUtil} from '../../common/js/async_util.m.js';
// #import {constants} from './constants.m.js';
// #import {VolumeManagerCommon} from '../../../base/js/volume_manager_types.m.js';
// #import {assert} from 'chrome://resources/js/assert.m.js';
// #import {util} from '../../common/js/util.m.js';
// #import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
// #import {dispatchSimpleEvent} from 'chrome://resources/js/cr.m.js';
// #import {metrics} from '../../common/js/metrics.m.js';
// clang-format on
/** /**
* Scanner of the entries. * Scanner of the entries.
*/ */
class ContentScanner { /* #export */ class ContentScanner {
constructor() { constructor() {
this.cancelled_ = false; this.cancelled_ = false;
} }
...@@ -36,7 +51,7 @@ class ContentScanner { ...@@ -36,7 +51,7 @@ class ContentScanner {
/** /**
* Scanner of the entries in a directory. * Scanner of the entries in a directory.
*/ */
class DirectoryContentScanner extends ContentScanner { /* #export */ class DirectoryContentScanner extends ContentScanner {
/** /**
* @param {DirectoryEntry|FilesAppDirEntry} entry The directory to be read. * @param {DirectoryEntry|FilesAppDirEntry} entry The directory to be read.
*/ */
...@@ -85,7 +100,7 @@ class DirectoryContentScanner extends ContentScanner { ...@@ -85,7 +100,7 @@ class DirectoryContentScanner extends ContentScanner {
/** /**
* Scanner of the entries for the search results on Drive File System. * Scanner of the entries for the search results on Drive File System.
*/ */
class DriveSearchContentScanner extends ContentScanner { /* #export */ class DriveSearchContentScanner extends ContentScanner {
/** @param {string} query The query string. */ /** @param {string} query The query string. */
constructor(query) { constructor(query) {
super(); super();
...@@ -160,7 +175,7 @@ DriveSearchContentScanner.MAX_RESULTS_ = 100; ...@@ -160,7 +175,7 @@ DriveSearchContentScanner.MAX_RESULTS_ = 100;
* Scanner of the entries of the file name search on the directory tree, whose * Scanner of the entries of the file name search on the directory tree, whose
* root is entry. * root is entry.
*/ */
class LocalSearchContentScanner extends ContentScanner { /* #export */ class LocalSearchContentScanner extends ContentScanner {
/** /**
* @param {DirectoryEntry} entry The root of the search target directory tree. * @param {DirectoryEntry} entry The root of the search target directory tree.
* @param {string} query The query of the search. * @param {string} query The query of the search.
...@@ -189,9 +204,9 @@ class LocalSearchContentScanner extends ContentScanner { ...@@ -189,9 +204,9 @@ class LocalSearchContentScanner extends ContentScanner {
/** /**
* Scanner of the entries for the metadata search on Drive File System. * Scanner of the entries for the metadata search on Drive File System.
*/ */
class DriveMetadataSearchContentScanner extends ContentScanner { /* #export */ class DriveMetadataSearchContentScanner extends ContentScanner {
/** /**
* @param {!DriveMetadataSearchContentScanner.SearchType} searchType The * @param {!chrome.fileManagerPrivate.SearchType} searchType The
* option of the search. * option of the search.
*/ */
constructor(searchType) { constructor(searchType) {
...@@ -232,19 +247,7 @@ class DriveMetadataSearchContentScanner extends ContentScanner { ...@@ -232,19 +247,7 @@ class DriveMetadataSearchContentScanner extends ContentScanner {
} }
} }
/** /* #export */ class RecentContentScanner extends ContentScanner {
* The search types on the Drive File System.
* @enum {!chrome.fileManagerPrivate.SearchType}
*/
DriveMetadataSearchContentScanner.SearchType = {
SEARCH_ALL: chrome.fileManagerPrivate.SearchType.ALL,
SEARCH_SHARED_WITH_ME: chrome.fileManagerPrivate.SearchType.SHARED_WITH_ME,
SEARCH_RECENT_FILES: chrome.fileManagerPrivate.SearchType.EXCLUDE_DIRECTORIES,
SEARCH_OFFLINE: chrome.fileManagerPrivate.SearchType.OFFLINE,
};
Object.freeze(DriveMetadataSearchContentScanner.SearchType);
class RecentContentScanner extends ContentScanner {
/** /**
* @param {string} query Search query. * @param {string} query Search query.
* @param {chrome.fileManagerPrivate.SourceRestriction=} opt_sourceRestriction * @param {chrome.fileManagerPrivate.SourceRestriction=} opt_sourceRestriction
...@@ -295,7 +298,7 @@ class RecentContentScanner extends ContentScanner { ...@@ -295,7 +298,7 @@ class RecentContentScanner extends ContentScanner {
/** /**
* Scanner of media-view volumes. * Scanner of media-view volumes.
*/ */
class MediaViewContentScanner extends ContentScanner { /* #export */ class MediaViewContentScanner extends ContentScanner {
/** /**
* @param {!DirectoryEntry} rootEntry The root entry of the media-view volume. * @param {!DirectoryEntry} rootEntry The root entry of the media-view volume.
*/ */
...@@ -338,7 +341,7 @@ class MediaViewContentScanner extends ContentScanner { ...@@ -338,7 +341,7 @@ class MediaViewContentScanner extends ContentScanner {
* is mounted as a disk volume and hide the fake root item while the * is mounted as a disk volume and hide the fake root item while the
* disk volume exists. * disk volume exists.
*/ */
class CrostiniMounter extends ContentScanner { /* #export */ class CrostiniMounter extends ContentScanner {
/** /**
* @override * @override
*/ */
...@@ -348,8 +351,7 @@ class CrostiniMounter extends ContentScanner { ...@@ -348,8 +351,7 @@ class CrostiniMounter extends ContentScanner {
console.error( console.error(
'mountCrostini error: ', chrome.runtime.lastError.message); 'mountCrostini error: ', chrome.runtime.lastError.message);
errorCallback(util.createDOMError( errorCallback(util.createDOMError(
DirectoryModel.CROSTINI_CONNECT_ERR, constants.CROSTINI_CONNECT_ERR, chrome.runtime.lastError.message));
chrome.runtime.lastError.message));
return; return;
} }
successCallback(); successCallback();
...@@ -361,7 +363,7 @@ class CrostiniMounter extends ContentScanner { ...@@ -361,7 +363,7 @@ class CrostiniMounter extends ContentScanner {
* This class manages filters and determines a file should be shown or not. * This class manages filters and determines a file should be shown or not.
* When filters are changed, a 'changed' event is fired. * When filters are changed, a 'changed' event is fired.
*/ */
class FileFilter extends cr.EventTarget { /* #export */ class FileFilter extends cr.EventTarget {
/** @param {!VolumeManager} volumeManager */ /** @param {!VolumeManager} volumeManager */
constructor(volumeManager) { constructor(volumeManager) {
super(); super();
...@@ -519,7 +521,7 @@ FileFilter.WINDOWS_HIDDEN = ['$RECYCLE.BIN']; ...@@ -519,7 +521,7 @@ FileFilter.WINDOWS_HIDDEN = ['$RECYCLE.BIN'];
* A context of DirectoryContents. * A context of DirectoryContents.
* TODO(yoshiki): remove this. crbug.com/224869. * TODO(yoshiki): remove this. crbug.com/224869.
*/ */
class FileListContext { /* #export */ class FileListContext {
/** /**
* @param {FileFilter} fileFilter The file-filter context. * @param {FileFilter} fileFilter The file-filter context.
* @param {!MetadataModel} metadataModel * @param {!MetadataModel} metadataModel
...@@ -584,7 +586,7 @@ class FileListContext { ...@@ -584,7 +586,7 @@ class FileListContext {
* results. * results.
* TODO(hidehiko): Remove EventTarget from this. * TODO(hidehiko): Remove EventTarget from this.
*/ */
class DirectoryContents extends cr.EventTarget { /* #export */ class DirectoryContents extends cr.EventTarget {
/** /**
* *
* @param {FileListContext} context The file list context. * @param {FileListContext} context The file list context.
......
...@@ -2,10 +2,40 @@ ...@@ -2,10 +2,40 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import {assertEquals, assertFalse} from 'chrome://test/chai_assert.js';
import {installMockChrome} from '../../../base/js/mock_chrome.m.js';
import {VolumeManagerCommon} from '../../../base/js/volume_manager_types.m.js';
import {EntryLocation} from '../../../externs/entry_location.m.js';
import {VolumeManager} from '../../../externs/volume_manager.m.js';
import {FileFilter} from './directory_contents.m.js';
/**
* Mock chrome APIs.
* @type {Object}
*/
const mockChrome = {
fileManagerPrivate: {
SearchType: {
ALL: 'ALL',
SHARED_WITH_ME: 'SHARED_WITH_ME',
EXCLUDE_DIRECTORIES: 'EXCLUDE_DIRECTORIES',
OFFLINE: 'OFFLINE',
},
},
};
/**
* Initializes the test environment.
*/
export function setUp() {
// Install mock chrome APIs.
installMockChrome(mockChrome);
}
/** /**
* Check that files are shown or hidden correctly. * Check that files are shown or hidden correctly.
*/ */
function testHiddenFiles() { export function testHiddenFiles() {
let volumeManagerRootType = VolumeManagerCommon.RootType.DOWNLOADS; let volumeManagerRootType = VolumeManagerCommon.RootType.DOWNLOADS;
// Create a fake volume manager that provides entry location info. // Create a fake volume manager that provides entry location info.
const volumeManager = /** @type {!VolumeManager} */ ({ const volumeManager = /** @type {!VolumeManager} */ ({
......
...@@ -2,6 +2,29 @@ ...@@ -2,6 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// clang-format off
// #import {EntriesChangedEvent} from '../../../externs/entries_changed_event.m.js';
// #import {ListSingleSelectionModel} from 'chrome://resources/js/cr/ui/list_single_selection_model.m.js';
// #import {ListSelectionModel} from 'chrome://resources/js/cr/ui/list_selection_model.m.js';
// #import {VolumeInfo} from '../../../externs/volume_info.m.js';
// #import {FilesAppDirEntry, FakeEntry, FilesAppEntry} from '../../../externs/files_app_entry_interfaces.m.js';
// #import {FileOperationManager} from '../../../externs/background/file_operation_manager.m.js';
// #import {VolumeManager} from '../../../externs/volume_manager.m.js';
// #import {MetadataModel} from './metadata/metadata_model.m.js';
// #import {FileListSingleSelectionModel, FileListSelectionModel} from './ui/file_list_selection_model.m.js';
// #import {FileWatcher} from './file_watcher.m.js';
// #import {FileListModel} from './file_list_model.m.js';
// #import {FileListContext, DirectoryContents, DirectoryContentScanner, RecentContentScanner, CrostiniMounter, DriveSearchContentScanner, LocalSearchContentScanner, MediaViewContentScanner, DriveMetadataSearchContentScanner, ContentScanner, FileFilter} from './directory_contents.m.js';
// #import {constants} from './constants.m.js';
// #import {assert} from 'chrome://resources/js/assert.m.js';
// #import {VolumeManagerCommon} from '../../../base/js/volume_manager_types.m.js';
// #import {util} from '../../common/js/util.m.js';
// #import {AsyncUtil} from '../../common/js/async_util.m.js';
// #import {dispatchSimpleEvent} from 'chrome://resources/js/cr.m.js';
// #import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
// #import {metrics} from '../../common/js/metrics.m.js';
// clang-format on
// If directory files changes too often, don't rescan directory more than once // If directory files changes too often, don't rescan directory more than once
// per specified interval // per specified interval
const SIMULTANEOUS_RESCAN_INTERVAL = 500; const SIMULTANEOUS_RESCAN_INTERVAL = 500;
...@@ -11,7 +34,7 @@ const SHORT_RESCAN_INTERVAL = 100; ...@@ -11,7 +34,7 @@ const SHORT_RESCAN_INTERVAL = 100;
/** /**
* Data model of the file manager. * Data model of the file manager.
*/ */
class DirectoryModel extends cr.EventTarget { /* #export */ class DirectoryModel extends cr.EventTarget {
/** /**
* @param {boolean} singleSelection True if only one file could be selected * @param {boolean} singleSelection True if only one file could be selected
* at the time. * at the time.
...@@ -770,7 +793,7 @@ class DirectoryModel extends cr.EventTarget { ...@@ -770,7 +793,7 @@ class DirectoryModel extends cr.EventTarget {
} }
// Do not rescan for crostini errors. // Do not rescan for crostini errors.
if (event.error.name === DirectoryModel.CROSTINI_CONNECT_ERR) { if (event.error.name === constants.CROSTINI_CONNECT_ERR) {
return; return;
} }
...@@ -1403,16 +1426,13 @@ class DirectoryModel extends cr.EventTarget { ...@@ -1403,16 +1426,13 @@ class DirectoryModel extends cr.EventTarget {
let searchType; let searchType;
switch (locationInfo.rootType) { switch (locationInfo.rootType) {
case VolumeManagerCommon.RootType.DRIVE_OFFLINE: case VolumeManagerCommon.RootType.DRIVE_OFFLINE:
searchType = searchType = chrome.fileManagerPrivate.SearchType.OFFLINE;
DriveMetadataSearchContentScanner.SearchType.SEARCH_OFFLINE;
break; break;
case VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME: case VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME:
searchType = DriveMetadataSearchContentScanner.SearchType searchType = chrome.fileManagerPrivate.SearchType.SHARED_WITH_ME;
.SEARCH_SHARED_WITH_ME;
break; break;
case VolumeManagerCommon.RootType.DRIVE_RECENT: case VolumeManagerCommon.RootType.DRIVE_RECENT:
searchType = searchType = chrome.fileManagerPrivate.SearchType.EXCLUDE_DIRECTORIES;
DriveMetadataSearchContentScanner.SearchType.SEARCH_RECENT_FILES;
break; break;
default: default:
// Unknown special search entry. // Unknown special search entry.
...@@ -1534,9 +1554,3 @@ class DirectoryModel extends cr.EventTarget { ...@@ -1534,9 +1554,3 @@ class DirectoryModel extends cr.EventTarget {
} }
} }
} }
/**
* DOMError type for crostini connection failure.
* @const {string}
*/
DirectoryModel.CROSTINI_CONNECT_ERR = 'CrostiniConnectErr';
...@@ -77,7 +77,7 @@ class EmptyFolderController { ...@@ -77,7 +77,7 @@ class EmptyFolderController {
onScanFailed_(event) { onScanFailed_(event) {
this.isScanning_ = false; this.isScanning_ = false;
// Show alert for crostini connection error. // Show alert for crostini connection error.
if (event.error.name == DirectoryModel.CROSTINI_CONNECT_ERR) { if (event.error.name == constants.CROSTINI_CONNECT_ERR) {
this.alertDialog_.showWithTitle( this.alertDialog_.showWithTitle(
str('ERROR_LINUX_FILES_CONNECTION'), event.error.message); str('ERROR_LINUX_FILES_CONNECTION'), event.error.message);
} }
......
...@@ -2,10 +2,19 @@ ...@@ -2,10 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// clang-format off
// #import {EntryLocation} from '../../../externs/entry_location.m.js';
// #import {VolumeManager} from '../../../externs/volume_manager.m.js';
// #import {MetadataModel} from './metadata/metadata_model.m.js';
// #import {FileType} from '../../common/js/file_type.m.js';
// #import {strf, str, util} from '../../common/js/util.m.js';
// #import {ArrayDataModel} from 'chrome://resources/js/cr/ui/array_data_model.m.js';
// clang-format on
/** /**
* File list. * File list.
*/ */
class FileListModel extends cr.ui.ArrayDataModel { /* #export */ class FileListModel extends cr.ui.ArrayDataModel {
/** @param {!MetadataModel} metadataModel */ /** @param {!MetadataModel} metadataModel */
constructor(metadataModel) { constructor(metadataModel) {
super([]); super([]);
...@@ -254,8 +263,8 @@ class FileListModel extends cr.ui.ArrayDataModel { ...@@ -254,8 +263,8 @@ class FileListModel extends cr.ui.ArrayDataModel {
* @override * @override
*/ */
replaceItem(oldItem, newItem) { replaceItem(oldItem, newItem) {
this.onRemoveEntryFromList_(oldItem); this.onRemoveEntryFromList_(/** @type {?Entry} */ (oldItem));
this.onAddEntryToList_(newItem); this.onAddEntryToList_(/** @type {?Entry} */ (newItem));
cr.ui.ArrayDataModel.prototype.replaceItem.apply(this, arguments); cr.ui.ArrayDataModel.prototype.replaceItem.apply(this, arguments);
} }
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import {assertArrayEquals, assertEquals} from 'chrome://test/chai_assert.js';
import {FileListModel} from './file_list_model.m.js';
import {MetadataModel} from './metadata/metadata_model.m.js';
const TEST_METADATA = { const TEST_METADATA = {
'a.txt': { 'a.txt': {
contentMimeType: 'text/plain', contentMimeType: 'text/plain',
...@@ -64,7 +68,7 @@ function createFakeMetadataModel(data) { ...@@ -64,7 +68,7 @@ function createFakeMetadataModel(data) {
}); });
} }
function testIsImageDominant() { export function testIsImageDominant() {
const fileListModel = const fileListModel =
new FileListModel(createFakeMetadataModel(TEST_METADATA)); new FileListModel(createFakeMetadataModel(TEST_METADATA));
...@@ -92,7 +96,7 @@ function testIsImageDominant() { ...@@ -92,7 +96,7 @@ function testIsImageDominant() {
assertEquals(fileListModel.isImageDominant(), true); assertEquals(fileListModel.isImageDominant(), true);
} }
function testSortWithFolders() { export function testSortWithFolders() {
const fileListModel = const fileListModel =
new FileListModel(createFakeMetadataModel(TEST_METADATA)); new FileListModel(createFakeMetadataModel(TEST_METADATA));
fileListModel.push({name: 'dirA', isDirectory: true}); fileListModel.push({name: 'dirA', isDirectory: true});
...@@ -124,7 +128,7 @@ function testSortWithFolders() { ...@@ -124,7 +128,7 @@ function testSortWithFolders() {
fileListModel, ['dirB', 'dirA', 'a.txt', 'b.html', 'c.jpg']); fileListModel, ['dirB', 'dirA', 'a.txt', 'b.html', 'c.jpg']);
} }
function testSplice() { export function testSplice() {
const fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']); const fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']);
fileListModel.sort('name', 'asc'); fileListModel.sort('name', 'asc');
...@@ -145,7 +149,7 @@ function testSplice() { ...@@ -145,7 +149,7 @@ function testSplice() {
assertFileListModelElementNames(fileListModel, ['a', 'b', 'd', 'p', 'x']); assertFileListModelElementNames(fileListModel, ['a', 'b', 'd', 'p', 'x']);
} }
function testSpliceWithoutSortStatus() { export function testSpliceWithoutSortStatus() {
const fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']); const fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']);
fileListModel.addEventListener('splice', event => { fileListModel.addEventListener('splice', event => {
...@@ -168,7 +172,7 @@ function testSpliceWithoutSortStatus() { ...@@ -168,7 +172,7 @@ function testSpliceWithoutSortStatus() {
assertFileListModelElementNames(fileListModel, ['d', 'a', 'p', 'b', 'n']); assertFileListModelElementNames(fileListModel, ['d', 'a', 'p', 'b', 'n']);
} }
function testSpliceWithoutAddingNewItems() { export function testSpliceWithoutAddingNewItems() {
const fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']); const fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']);
fileListModel.sort('name', 'asc'); fileListModel.sort('name', 'asc');
...@@ -189,7 +193,7 @@ function testSpliceWithoutAddingNewItems() { ...@@ -189,7 +193,7 @@ function testSpliceWithoutAddingNewItems() {
assertFileListModelElementNames(fileListModel, ['a', 'd', 'x']); assertFileListModelElementNames(fileListModel, ['a', 'd', 'x']);
} }
function testSpliceWithoutDeletingItems() { export function testSpliceWithoutDeletingItems() {
const fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']); const fileListModel = makeSimpleFileListModel(['d', 'a', 'x', 'n']);
fileListModel.sort('name', 'asc'); fileListModel.sort('name', 'asc');
......
...@@ -2,8 +2,16 @@ ...@@ -2,8 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// clang-format off
// #import {FilesAppEntry} from '../../../externs/files_app_entry_interfaces.m.js';
// #import {assert} from 'chrome://resources/js/assert.m.js';
// #import {util} from '../../common/js/util.m.js';
// #import {AsyncUtil} from '../../common/js/async_util.m.js';
// #import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
// clang-format on
/** Watches for changes in the tracked directory. */ /** Watches for changes in the tracked directory. */
class FileWatcher extends cr.EventTarget { /* #export */ class FileWatcher extends cr.EventTarget {
constructor() { constructor() {
super(); super();
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
import("//third_party/closure_compiler/compile_js.gni") import("//third_party/closure_compiler/compile_js.gni")
import("//third_party/closure_compiler/js_unit_tests.gni") import("//third_party/closure_compiler/js_unit_tests.gni")
import("//ui/file_manager/base/gn/js_test_gen_html.gni") import("//ui/file_manager/base/gn/js_test_gen_html.gni")
import("//ui/webui/resources/js/cr.gni")
import("//ui/webui/resources/tools/js_modulizer.gni")
visibility = [ "//ui/file_manager/file_manager/foreground/*" ] visibility = [ "//ui/file_manager/file_manager/foreground/*" ]
...@@ -12,11 +14,18 @@ group("closure_compile") { ...@@ -12,11 +14,18 @@ group("closure_compile") {
testonly = true testonly = true
visibility += [ "//ui/file_manager:closure_compile" ] visibility += [ "//ui/file_manager:closure_compile" ]
deps = [ deps = [
":closure_compile_jsmodules",
":closure_compile_module", ":closure_compile_module",
":js_test_gen_html_modules_type_check_auto",
":js_test_gen_html_type_check_auto", ":js_test_gen_html_type_check_auto",
] ]
} }
js_type_check("closure_compile_jsmodules") {
uses_js_modules = true
deps = [ ":file_list_selection_model.m" ]
}
js_type_check("closure_compile_module") { js_type_check("closure_compile_module") {
deps = [ deps = [
":action_model_ui", ":action_model_ui",
...@@ -232,10 +241,20 @@ js_library("file_list_selection_model") { ...@@ -232,10 +241,20 @@ js_library("file_list_selection_model") {
] ]
} }
js_unittest("file_list_selection_model_unittest") { js_library("file_list_selection_model.m") {
sources = [ "$root_gen_dir/ui/file_manager/file_manager/foreground/js/ui/file_list_selection_model.m.js" ]
deps = [ deps = [
":file_list_selection_model", "//ui/webui/resources/js/cr/ui:list_selection_model.m",
"//ui/webui/resources/js:webui_resource_test", "//ui/webui/resources/js/cr/ui:list_single_selection_model.m",
]
extra_deps = [ ":modulize" ]
}
js_unittest("file_list_selection_model_unittest.m") {
deps = [
":file_list_selection_model.m",
"//chrome/test/data/webui:chai_assert",
] ]
} }
...@@ -530,12 +549,23 @@ js_library("suggest_apps_dialog") { ...@@ -530,12 +549,23 @@ js_library("suggest_apps_dialog") {
[ "//ui/file_manager/externs/chrome_webstore_widget_private.js" ] [ "//ui/file_manager/externs/chrome_webstore_widget_private.js" ]
} }
js_test_gen_html("js_test_gen_html_modules") {
deps = [ ":file_list_selection_model_unittest.m" ]
js_module = true
closure_flags =
strict_error_checking_closure_args + [
"js_module_root=./gen/ui",
"js_module_root=../../ui",
"browser_resolver_prefix_replacements=\"chrome://test/=./\"",
]
}
js_test_gen_html("js_test_gen_html") { js_test_gen_html("js_test_gen_html") {
deps = [ deps = [
":actions_submenu_unittest", ":actions_submenu_unittest",
":breadcrumb_unittest", ":breadcrumb_unittest",
":directory_tree_unittest", ":directory_tree_unittest",
":file_list_selection_model_unittest",
":file_manager_dialog_base_unittest", ":file_manager_dialog_base_unittest",
":file_table_list_unittest", ":file_table_list_unittest",
":file_table_unittest", ":file_table_unittest",
...@@ -544,3 +574,9 @@ js_test_gen_html("js_test_gen_html") { ...@@ -544,3 +574,9 @@ js_test_gen_html("js_test_gen_html") {
":multi_menu_unittest", ":multi_menu_unittest",
] ]
} }
js_modulizer("modulize") {
input_files = [ "file_list_selection_model.js" ]
namespace_rewrites = cr_namespace_rewrites
}
...@@ -2,7 +2,12 @@ ...@@ -2,7 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
class FileListSelectionModel extends cr.ui.ListSelectionModel { // clang-format off
// #import {ListSingleSelectionModel} from 'chrome://resources/js/cr/ui/list_single_selection_model.m.js';
// #import {ListSelectionModel} from 'chrome://resources/js/cr/ui/list_selection_model.m.js';
// clang-format on
/* #export */ class FileListSelectionModel extends cr.ui.ListSelectionModel {
/** @param {number=} opt_length The number items in the selection. */ /** @param {number=} opt_length The number items in the selection. */
constructor(opt_length) { constructor(opt_length) {
super(opt_length); super(opt_length);
...@@ -92,7 +97,8 @@ class FileListSelectionModel extends cr.ui.ListSelectionModel { ...@@ -92,7 +97,8 @@ class FileListSelectionModel extends cr.ui.ListSelectionModel {
} }
} }
class FileListSingleSelectionModel extends cr.ui.ListSingleSelectionModel { /* #export */ class FileListSingleSelectionModel extends
cr.ui.ListSingleSelectionModel {
/** /**
* Updates the check-select mode. * Updates the check-select mode.
* @param {boolean} enabled True if check-select mode should be enabled. * @param {boolean} enabled True if check-select mode should be enabled.
......
...@@ -2,16 +2,19 @@ ...@@ -2,16 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import {assertArrayEquals, assertFalse, assertTrue} from 'chrome://test/chai_assert.js';
import {FileListSelectionModel} from './file_list_selection_model.m.js';
/** @type {!FileListSelectionModel} */ /** @type {!FileListSelectionModel} */
let selectionModel; let selectionModel;
function setUp() { export function setUp() {
selectionModel = new FileListSelectionModel(); selectionModel = new FileListSelectionModel();
} }
// Verify that all selection and focus is dropped if all selected files get // Verify that all selection and focus is dropped if all selected files get
// deleted. // deleted.
function testAdjustToReorderingAllAreDeleted() { export function testAdjustToReorderingAllAreDeleted() {
// Set initial selection. // Set initial selection.
selectionModel.selectedIndexes = [0, 1]; selectionModel.selectedIndexes = [0, 1];
// Delete the selected items. // Delete the selected items.
...@@ -23,7 +26,7 @@ function testAdjustToReorderingAllAreDeleted() { ...@@ -23,7 +26,7 @@ function testAdjustToReorderingAllAreDeleted() {
// Verify that all selection and focus is dropped only if all selected files get // Verify that all selection and focus is dropped only if all selected files get
// deleted. // deleted.
function testAdjustToReorderingSomeAreDeleted() { export function testAdjustToReorderingSomeAreDeleted() {
// Set initial selection. // Set initial selection.
selectionModel.selectedIndexes = [0, 1]; selectionModel.selectedIndexes = [0, 1];
// Delete the selected items. // Delete the selected items.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment