From 71f53423854bdded3186d6a5ec6fdaf2a83b81e2 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Sun, 1 Mar 2020 16:38:03 -0800 Subject: [PATCH] Editor: Implemented DataTransferItemList support. --- editor/index.html | 12 +++++- editor/js/Loader.js | 31 +++++++------- editor/js/LoaderUtils.js | 88 ++++++++++++++++++++++++++++++++++++++++ editor/sw.js | 1 + 4 files changed, 114 insertions(+), 18 deletions(-) create mode 100644 editor/js/LoaderUtils.js diff --git a/editor/index.html b/editor/index.html index 4daae7dbf8..96e4e211f3 100644 --- a/editor/index.html +++ b/editor/index.html @@ -188,7 +188,17 @@ event.preventDefault(); - editor.loader.loadFiles( event.dataTransfer.files ); + // DataTransferItemList supports folders + + if ( event.dataTransfer.items ) { + + editor.loader.loadItemList( event.dataTransfer.items ); + + } else { + + editor.loader.loadFiles( event.dataTransfer.files ); + + } }, false ); diff --git a/editor/js/Loader.js b/editor/js/Loader.js index 0487ce01a0..bbca9ae794 100644 --- a/editor/js/Loader.js +++ b/editor/js/Loader.js @@ -23,17 +23,29 @@ import { VRMLLoader } from '../../examples/jsm/loaders/VRMLLoader.js'; import { AddObjectCommand } from './commands/AddObjectCommand.js'; import { SetSceneCommand } from './commands/SetSceneCommand.js'; +import { LoaderUtils } from './LoaderUtils.js'; + var Loader = function ( editor ) { var scope = this; this.texturePath = ''; - this.loadFiles = function ( files ) { + this.loadItemList = function ( items ) { + + LoaderUtils.getFilesFromItemList( items, function ( files, filesMap ) { + + scope.loadFiles( files, filesMap ); + + } ); + + }; + + this.loadFiles = function ( files, filesMap ) { if ( files.length > 0 ) { - var filesMap = createFileMap( files ); + var filesMap = filesMap || LoaderUtils.createFilesMap( files ); var manager = new THREE.LoadingManager(); manager.setURLModifier( function ( url ) { @@ -566,21 +578,6 @@ var Loader = function ( editor ) { } - function createFileMap( files ) { - - var map = {}; - - for ( var i = 0; i < files.length; i ++ ) { - - var file = files[ i ]; - map[ file.name ] = file; - - } - - return map; - - } - function handleZIP( contents ) { var zip = new JSZip( contents ); diff --git a/editor/js/LoaderUtils.js b/editor/js/LoaderUtils.js new file mode 100644 index 0000000000..4f08f25227 --- /dev/null +++ b/editor/js/LoaderUtils.js @@ -0,0 +1,88 @@ +/** + * @author mrdoob / http://mrdoob.com/ + */ + +var LoaderUtils = { + + createFilesMap: function ( files ) { + + var map = {}; + + for ( var i = 0; i < files.length; i ++ ) { + + var file = files[ i ]; + map[ file.name ] = file; + + } + + return map; + + }, + + getFilesFromItemList: function ( items, onDone ) { + + // TOFIX: setURLModifier() breaks when the file being loaded is not in root + + var itemsCount = 0; + var itemsTotal = 0; + + var files = []; + var filesMap = {}; + + function onEntryHandled() { + + itemsCount ++; + + if ( itemsCount === itemsTotal ) { + + onDone( files, filesMap ); + + } + + } + + function handleEntry( entry ) { + + if ( entry.isDirectory ) { + + var reader = entry.createReader(); + reader.readEntries( function ( entries ) { + + for ( var i = 0; i < entries.length; i ++ ) { + + handleEntry( entries[ i ] ); + + } + + onEntryHandled( entry ); + + } ); + + } else if ( entry.isFile ) { + + entry.file( function ( file ) { + + files.push( file ); + + filesMap[ entry.fullPath.substr( 1 ) ] = file; + onEntryHandled(); + + } ); + + } + + itemsTotal ++; + + } + + for ( var i = 0; i < items.length; i ++ ) { + + handleEntry( items[ i ].webkitGetAsEntry() ); + + } + + } + +}; + +export { LoaderUtils }; diff --git a/editor/sw.js b/editor/sw.js index 90146df2cc..62750d0813 100644 --- a/editor/sw.js +++ b/editor/sw.js @@ -101,6 +101,7 @@ const assets = [ './js/Config.js', './js/History.js', './js/Loader.js', + './js/LoaderUtils.js', './js/Menubar.js', './js/Menubar.File.js', './js/Menubar.Edit.js', -- GitLab