@@ -463,87 +463,128 @@ export class ComfyPage {
463463 await this . nextFrame ( )
464464 }
465465
466- async dragAndDropFile (
467- fileName : string ,
466+ async dragAndDropExternalResource (
468467 options : {
468+ fileName ?: string
469+ url ?: string
469470 dropPosition ?: Position
470471 } = { }
471472 ) {
472- const { dropPosition = { x : 100 , y : 100 } } = options
473-
474- const filePath = this . assetPath ( fileName )
475-
476- // Read the file content
477- const buffer = fs . readFileSync ( filePath )
473+ const { dropPosition = { x : 100 , y : 100 } , fileName, url } = options
474+
475+ if ( ! fileName && ! url )
476+ throw new Error ( 'Must provide either fileName or url' )
477+
478+ const evaluateParams : {
479+ dropPosition : Position
480+ fileName ?: string
481+ fileType ?: string
482+ buffer ?: Uint8Array | number [ ]
483+ url ?: string
484+ } = { dropPosition }
485+
486+ // Dropping a file from the filesystem
487+ if ( fileName ) {
488+ const filePath = this . assetPath ( fileName )
489+ const buffer = fs . readFileSync ( filePath )
490+
491+ const getFileType = ( fileName : string ) => {
492+ if ( fileName . endsWith ( '.png' ) ) return 'image/png'
493+ if ( fileName . endsWith ( '.webp' ) ) return 'image/webp'
494+ if ( fileName . endsWith ( '.webm' ) ) return 'video/webm'
495+ if ( fileName . endsWith ( '.json' ) ) return 'application/json'
496+ if ( fileName . endsWith ( '.glb' ) ) return 'model/gltf-binary'
497+ return 'application/octet-stream'
498+ }
478499
479- // Get file type
480- const getFileType = ( fileName : string ) => {
481- if ( fileName . endsWith ( '.png' ) ) return 'image/png'
482- if ( fileName . endsWith ( '.webp' ) ) return 'image/webp'
483- if ( fileName . endsWith ( '.webm' ) ) return 'video/webm'
484- if ( fileName . endsWith ( '.json' ) ) return 'application/json'
485- if ( fileName . endsWith ( '.glb' ) ) return 'model/gltf-binary'
486- return 'application/octet-stream'
500+ evaluateParams . fileName = fileName
501+ evaluateParams . fileType = getFileType ( fileName )
502+ evaluateParams . buffer = [ ...new Uint8Array ( buffer ) ]
487503 }
488504
489- const fileType = getFileType ( fileName )
505+ // Dropping a URL (e.g., dropping image across browser tabs in Firefox)
506+ if ( url ) evaluateParams . url = url
490507
491- await this . page . evaluate (
492- async ( { buffer, fileName, fileType, dropPosition } ) => {
493- const file = new File ( [ new Uint8Array ( buffer ) ] , fileName , {
494- type : fileType
495- } )
496- const dataTransfer = new DataTransfer ( )
497- dataTransfer . items . add ( file )
508+ // Execute the drag and drop in the browser
509+ await this . page . evaluate ( async ( params ) => {
510+ const dataTransfer = new DataTransfer ( )
498511
499- const targetElement = document . elementFromPoint (
500- dropPosition . x ,
501- dropPosition . y
512+ // Add file if provided
513+ if ( params . buffer && params . fileName && params . fileType ) {
514+ const file = new File (
515+ [ new Uint8Array ( params . buffer ) ] ,
516+ params . fileName ,
517+ {
518+ type : params . fileType
519+ }
502520 )
521+ dataTransfer . items . add ( file )
522+ }
503523
504- if ( ! targetElement ) {
505- console . error ( 'No element found at drop position:' , dropPosition )
506- return { success : false , error : 'No element at position' }
507- }
524+ // Add URL data if provided
525+ if ( params . url ) {
526+ dataTransfer . setData ( 'text/uri-list' , params . url )
527+ dataTransfer . setData ( 'text/x-moz-url' , params . url )
528+ }
508529
509- const eventOptions = {
510- bubbles : true ,
511- cancelable : true ,
512- dataTransfer,
513- clientX : dropPosition . x ,
514- clientY : dropPosition . y
515- }
530+ const targetElement = document . elementFromPoint (
531+ params . dropPosition . x ,
532+ params . dropPosition . y
533+ )
516534
517- const dragOverEvent = new DragEvent ( 'dragover' , eventOptions )
518- const dropEvent = new DragEvent ( 'drop' , eventOptions )
535+ if ( ! targetElement ) {
536+ console . error ( 'No element found at drop position:' , params . dropPosition )
537+ return { success : false , error : 'No element at position' }
538+ }
519539
520- Object . defineProperty ( dropEvent , 'preventDefault' , {
521- value : ( ) => { } ,
522- writable : false
523- } )
524- Object . defineProperty ( dropEvent , 'stopPropagation' , {
525- value : ( ) => { } ,
526- writable : false
527- } )
540+ const eventOptions = {
541+ bubbles : true ,
542+ cancelable : true ,
543+ dataTransfer,
544+ clientX : params . dropPosition . x ,
545+ clientY : params . dropPosition . y
546+ }
528547
529- targetElement . dispatchEvent ( dragOverEvent )
530- targetElement . dispatchEvent ( dropEvent )
548+ const dragOverEvent = new DragEvent ( 'dragover' , eventOptions )
549+ const dropEvent = new DragEvent ( 'drop' , eventOptions )
531550
532- return {
533- success : true ,
534- targetInfo : {
535- tagName : targetElement . tagName ,
536- id : targetElement . id ,
537- classList : Array . from ( targetElement . classList )
538- }
551+ Object . defineProperty ( dropEvent , 'preventDefault' , {
552+ value : ( ) => { } ,
553+ writable : false
554+ } )
555+
556+ Object . defineProperty ( dropEvent , 'stopPropagation' , {
557+ value : ( ) => { } ,
558+ writable : false
559+ } )
560+
561+ targetElement . dispatchEvent ( dragOverEvent )
562+ targetElement . dispatchEvent ( dropEvent )
563+
564+ return {
565+ success : true ,
566+ targetInfo : {
567+ tagName : targetElement . tagName ,
568+ id : targetElement . id ,
569+ classList : Array . from ( targetElement . classList )
539570 }
540- } ,
541- { buffer : [ ...new Uint8Array ( buffer ) ] , fileName, fileType, dropPosition }
542- )
571+ }
572+ } , evaluateParams )
543573
544574 await this . nextFrame ( )
545575 }
546576
577+ async dragAndDropFile (
578+ fileName : string ,
579+ options : { dropPosition ?: Position } = { }
580+ ) {
581+ return this . dragAndDropExternalResource ( { fileName, ...options } )
582+ }
583+
584+ async dragAndDropURL ( url : string , options : { dropPosition ?: Position } = { } ) {
585+ return this . dragAndDropExternalResource ( { url, ...options } )
586+ }
587+
547588 async dragNode2 ( ) {
548589 await this . dragAndDrop ( { x : 622 , y : 400 } , { x : 622 , y : 300 } )
549590 await this . nextFrame ( )
0 commit comments