I want to create an application where you can use drag and drop to transfer some short string data from one browser window to another (where either window can be a popup window). Code in the example is written in HTML and TypeScript, bundled with WebPack.
On the drop end we have:
<p class="drop-zone" >
Drop here.
</p>
const popupWindow = window.open("link-to-above-html-file", "popup")!
popupWindow.querySelector(".drop-zone")!.addEventListener("drop", async (e) => {
e.preventDefault();
(e as DragEvent).dataTransfer!.dropEffect = "copy";
console.log("DropEvent");
console.log(e);
console.log(e instanceof DragEvent);
console.log(e.constructor);
console.log(DragEvent);
console.log(DragEvent == e.constructor);
});
popupWindow.querySelector(".drop-zone")!.addEventListener("dragover", async (e) => {
e.preventDefault();
(e as DragEvent).dataTransfer!.dropEffect = "copy"; //not sure if this is needed, but the default here is "none" which some other people have mentioned can result in an empty DataTransfer object
});
On the drag end we have:
<p draggable="true" ondragstart="onDrag(event)">
Drag me.
</p>
(...)
<script>
function onDrag(e){
e.dataTransfer.items.add("some data", "text/plain")
}
</script>
Now, if we test this on Chrome (on Linux, not sure if the result is the same on other versions), dragging from a regular window into a separate popup window (where the event listener for "drop" and "dragover" are defined in another window which generated the popup, as in the example above) we don't get any errors, but we do notice something peculiar. chrome console output
The event received is a DragEvent, but the constructor in the popup is a different DragEvent then the one we have in the window which generated the popup.
The DataTransfer object and the items within are still accessible, so it isn't that big of a deal, but designing around it will be annoying.
But, if we test this on Firefox (Linux, specifically apt package version 140.6.0esr-1~deb12u1, which is currently latest stable) we encounter a bug which was reported and confirmed 8 years ago, unfixed and unaddressed for 2 years: the DataTransfer object is null. report on bugzilla
I really want this application to work in both browsers.
Is there any way to have elements transfer a simple short string to another element in another (hopefully popup) window, similar to a drag and drop? And yes, I know I could just provide the string data to the user and they can just manually copy-paste it into an input , but I would really like it if the string data wasn't completely transparent (it's fine if they want to see it, but they shouldn't have to).
And a small sub-question, is there any way to circumvent Chrome redefining all the class constructors in a popup window?
No. Native HTML5 drag-and-drop does not reliably work across browser windows/popups, and Firefox will keep returning null for DataTransfer. There is no fix.
Use window.postMessage() to pass the string between windows and simulate drag-and-drop with mouse events.
Chrome’s popup constructor redefinition cannot be avoided.