@@ -18,8 +18,20 @@ function DropControl(gui, el, cb) {
1818 . on ( 'paste' , onpaste ) ;
1919 area . node ( ) . addEventListener ( 'paste' , onpaste ) ;
2020 function ondrop ( e ) {
21+ var files = e . dataTransfer . files ;
22+ var types = e . dataTransfer . types ;
2123 block ( e ) ;
22- cb ( e . dataTransfer . files ) ;
24+ if ( files . length ) {
25+ cb ( files ) ;
26+ } else if ( types . includes ( 'text/uri-list' ) ) {
27+ cb ( e . dataTransfer . getData ( 'text/uri-list' ) . split ( ',' ) ) ;
28+ } else if ( types . includes ( 'text/html' ) ) {
29+ // drag-dropping a highlighted link may pull in a chunk of html
30+ var urls = e . dataTransfer . getData ( 'text/html' ) . match ( / h t t p s ? : [ ^ " ' ] + / ) ;
31+ if ( urls . length ) {
32+ cb ( urls ) ;
33+ }
34+ }
2335 }
2436 function onpaste ( e ) {
2537 var types = Array . from ( e . clipboardData . types || [ ] ) . join ( ',' ) ;
@@ -36,15 +48,18 @@ function DropControl(gui, el, cb) {
3648 // Single files of all types are pasted as a string and an image/png
3749 // Multiple files are pasted as a string containing a list of file names
3850
39- // import text from the clipboard (could be csv, json, etc)
51+ // import text from the clipboard (could be csv, json, a url, etc)
4052 // formatted text can be available as both text/plain and text/html (e.g.
4153 // a JSON data object copied from a GitHub issue).
4254 //
4355 if ( types . includes ( 'text/plain' ) ) {
44- // if (types == 'text/plain') {
4556 // text from clipboard (supported by Chrome, FF, Safari)
4657 // TODO: handle FF case of string containing multiple file names.
47- files = [ pastedTextToFile ( e . clipboardData . getData ( 'text/plain' ) ) ] ;
58+ var str = e . clipboardData . getData ( 'text/plain' ) ;
59+ if ( isUrl ( str ) ) {
60+ return cb ( str . split ( ',' ) ) ;
61+ }
62+ files = [ pastedTextToFile ( str ) ] ;
4863 } else {
4964 files = items . map ( function ( item ) {
5065 return item . kind == 'file' && ! item . type . includes ( 'image' ) ?
@@ -78,6 +93,10 @@ function pastedTextToFile(str) {
7893 return new File ( [ blob ] , name ) ;
7994}
8095
96+ function isUrl ( str ) {
97+ return / ^ h t t p s ? : \/ \/ / . test ( str ) ;
98+ }
99+
81100// @el DOM element for select button
82101// @cb function(<FileList>)
83102function FileChooser ( el , cb ) {
@@ -121,7 +140,7 @@ export function ImportControl(gui, opts) {
121140
122141 var submitBtn = new SimpleButton ( '#import-options .submit-btn' ) . on ( 'click' , importQueuedFiles ) ;
123142 new SimpleButton ( '#import-options .cancel-btn' ) . on ( 'click' , gui . clearMode ) ;
124- new DropControl ( gui , 'body' , receiveFilesWithOption ) ;
143+ new DropControl ( gui , 'body' , receiveDroppedItems ) ;
125144 new FileChooser ( '#import-options .add-btn' , receiveFilesWithOption ) ;
126145 new FileChooser ( '#add-file-btn' , receiveFiles ) ;
127146 new SimpleButton ( '#add-empty-btn' ) . on ( 'click' , function ( ) {
@@ -137,7 +156,7 @@ export function ImportControl(gui, opts) {
137156
138157 function turnOn ( ) {
139158 if ( manifestFiles . length > 0 ) {
140- downloadFiles ( manifestFiles , true ) ;
159+ downloadFiles ( manifestFiles ) ;
141160 manifestFiles = [ ] ;
142161 } else if ( model . isEmpty ( ) ) {
143162 showImportMenu ( ) ;
@@ -238,6 +257,14 @@ export function ImportControl(gui, opts) {
238257 submitBtn . classed ( 'disabled' , queuedFiles . length === 0 ) ;
239258 }
240259
260+ function receiveDroppedItems ( arr ) {
261+ if ( utils . isString ( arr [ 0 ] ) ) { // assume array of URLs
262+ downloadFiles ( arr ) ;
263+ } else { // assume array of Files
264+ receiveFilesWithOption ( arr ) ;
265+ }
266+ }
267+
241268 function receiveFilesWithOption ( files ) {
242269 var quickView = ! El ( '.advanced-import-options' ) . node ( ) . checked ;
243270 receiveFiles ( files , quickView ) ;
@@ -393,9 +420,8 @@ export function ImportControl(gui, opts) {
393420
394421 function prepFilesForDownload ( names ) {
395422 var items = names . map ( function ( name ) {
396- var isUrl = / : \/ \/ / . test ( name ) ;
397423 var item = { name : name } ;
398- if ( isUrl ) {
424+ if ( isUrl ( name ) ) {
399425 item . url = name ;
400426 item . basename = GUI . getUrlFilename ( name ) ;
401427
0 commit comments