Failure trigger event when providing data files

Question

How could I, when creating a file, raise a drop event for a field on which I do not have access at boot time.

More details

There is a page with a field on which the drop listener is connected, which processes the image when it is deleted. I would like to be able to use this process by inserting an image. I know how to get a file from an insert, but I don’t know how to send a drop event that will contain this same file.

The obstacles are as follows:

  • The code is confusing, I cannot access the function associated with the listener by name.
  • Unable to get drop listener after attaching to element. There seems to be some way to do this in the console, but not from the script.
  • I do not control the rendering of pages; that is, I cannot intercept the addition of an event listener.
  • Vanilla Javascript and can only work in Chrome (extension).
  • This page is embedded in vanilla; those. no jQuery or anything else.

Does anyone have an idea on how to solve this problem?

I look at DragEvent , but "although this interface has a constructor, it is not possible to create a useful DataTransfer object from a script, because DataTransfer objects have a handling and security model that is coordinated by the browser during drag and drop.

I have seen a possible approach to https://stackoverflow.com/a/3129609/2129 , but I want to emulate the real drop event with its data, that is, transfer the file that I received through clipboardData.items[0].getAsFile(); instead of just text.

+2
source share
1 answer

You can fake the drop event and fake almost everything there. You will have a problem with triggering a default event, for example, opening a file in a tab by deleting it. The reason lies not only in the fact that the dataTransfer object is protected, but the event is not trusted. With a trusted event and protected dataTransfer, you can be sure that you will not send data to a trusted event and that you will not trigger a default event with unwanted data.

But depending on how the drop function has access to the file to be deleted, you can trick it with a fake drop event and a fake dataTransfer object . See this script for a general idea of ​​how it can work:

 var a = document.getElementById('link'); var dropZone1 = document.getElementById('dropZone1'); var dropZone2 = document.getElementById('dropZone2'); var fakeDropBtn = document.getElementById('fakeDropBtn'); dropZone1.addEventListener('dragover', function(e) { e.preventDefault(); }); dropZone2.addEventListener('dragover', function(e) { e.preventDefault(); }); dropZone1.addEventListener('drop', function(e) { // This first drop zone is simply to get access to a file. // In your case the file would come from the clipboard // but you need to work with an extension to have access // to paste data, so here I use a drop event e.preventDefault(); fakeDropBtn.classList.remove('disabled'); dropZone2.classList.remove('disabled'); var fileToDrop = e.dataTransfer.files[0]; // You create a drop event var fakeDropEvent = new DragEvent('drop'); // You override dataTransfer with whichever property // and method the drop function needs Object.defineProperty(fakeDropEvent, 'dataTransfer', { value: new FakeDataTransfer(fileToDrop) }); fakeDropBtn.addEventListener('click', function(e) { e.preventDefault(); // the fake event will be called on the button click dropZone2.dispatchEvent(fakeDropEvent); }); }); dropZone2.addEventListener('drop', function(e) { e.preventDefault(); // this is the fake event being called. In this case for // example, the function gets access to dataTransfer files. // You'll see the result will be the same with a real // drop event or with a fake drop event. The only thing // that matters is to override the specific property this function // is using. var url = window.URL.createObjectURL(e.dataTransfer.files[0]); a.href = url; a.click(); window.URL.revokeObjectURL(url); }); function FakeDataTransfer(file) { this.dropEffect = 'all'; this.effectAllowed = 'all'; this.items = []; this.types = ['Files']; this.getData = function() { return file; }; this.files = [file]; }; 

https://jsfiddle.net/5m2u0tux/6/

+1
source

All Articles