facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
228.82k stars 46.83k forks source link

DataTransfer's dropEffect not working on IE/Edge with not minified version react.js #5700

Open srayuws opened 8 years ago

srayuws commented 8 years ago

code exmaple: Non-minified version and Minified version

Both have the same code, html and js, the only difference is referenced to different version of react.js files.

There are three boxes. Dragging the "drag me" box will show a "start" at the top, then show a "over" if it is dragged over either "normal drop" or "drop react" box, and show a "end" with a drop to the two drop boxes.

Everything works fine on my Firefox(43.0.1), and the the Minified version works fine on my IE 11, and Edge(13).

The only thing dose not work is the Non-minified version on IE/Edge.

When dragging over the "drop react" box, there shows NO "over". In the F12 console, I can see lines of "SCRIPT16389: Unspecified error.". And with console.log(ev.dataTransfer), I get this result:

[object DataTransfer] {
   dropEffect: <Permission denied>,
   effectAllowed: "all",
   files: FileList {...}, 
   items: DataTransferItemList {...}, 
   types: DOMStringList {...}
}

I thought the dropEffect should also be accessible on IE/Edge with non-minified version react.js files?

p-jackson commented 8 years ago

The difference between minified and unminified is because React wraps event handlers inside other events in the development build to get better devtool integration. Problem is that Edge and IE don't allow access to the dropEffect property unless you're inside that original event handler I'm guessing. In the production build there are no wrapper events, it's just a function call, so dropEffect can be accessed normally.

Could be a bug in those browsers? Or perhaps Microsoft are just being extra cautious because of the kinds of security risks mentioned in the spec? https://html.spec.whatwg.org/multipage/interaction.html#security-risks-in-the-drag-and-drop-model

p-jackson commented 8 years ago

I'm working on a PR, but thought I would check the approach I'm taking.

Ideally event handlers should work the same way in dev and production. And React should retain it's good devtool integration, since removing it for a minority of cases doesn't seem right. So my approach is to detect if we're in an environment that works this way, and if we are, to skip wrapping the event handlers for drag events only.

It's too bad we can't detect whether an event handler will actually try and access the dropEffect property, since event handlers that don't try to access it work fine.

jimfb commented 8 years ago

@p-jackson Sounds like a reasonable approach to me.

zpao commented 8 years ago

Note: the original PR that fixed this was reverted so this bug still exists.

JohnWeisz commented 8 years ago

A workaround for when you only need the combination of effectAllowed and dropEffect to determine whether the drop should be enabled is checking the effectAllowed property, which is available in the dragover and drop events, and call preventDefault() when the value of effectAllowed is OK, effectively enabling the drop operation.

For example, to only allow finishing a drag-and-drop if it is a move operation:

dragStartHandler(e) {
    e.dataTransfer.effectAllowed = "move";
}

dragOverHandler(e) {
    if (e.dataTransfer.effectAllowed === "move") {
        e.preventDefault();
        // ...
    }
}

dropHandler(e) {
    if (e.dataTransfer.effectAllowed === "move") {
        e.preventDefault();
        // ...
    }
}

The reason this works is because without preventing the default event behavior the drag-and-drop operation will not be available. At least, not as such. This enables the possibility of real-time visual feedback for several distinct drag-modes per application.

AndyOGo commented 4 years ago

Trying to set dropEffect via nativeEvent attribute doesn't work either 🤔

If you find that you need the underlying browser event for some reason, simply use the nativeEvent attribute to get it. https://reactjs.org/docs/events.html#overview

PhilipJohnBasile commented 2 years ago

Since IE is not supported anymore we should close this.