marcojakob / dart-dnd

Drag and Drop for Dart web apps with mouse and touch support.
https://code.makery.ch/library/dart-drag-and-drop/
MIT License
135 stars 86 forks source link

Dropzones don't work with Shadow DOM due to event retargeting #3

Closed friegger closed 9 years ago

friegger commented 10 years ago

The onMouseMove events setup in draggable.dart (https://github.com/marcojakob/dart-dnd/blob/master/lib/src/draggable.dart#L320) will never handle targets within Shadow DOM. Reason for this is, that events from within the Shadow DOM are retargeted to its host. For event handlers setup outside the host, the event target will always be the host and not potential drop targets within.

// Install mouseMove listener.
    _dragSubs.add(document.onMouseMove.listen((MouseEvent event) {

Also have a look here: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-301/#toc-events

A solution might be to also register mouseover handlers, when the dropzone is installed to elements and react properly.

marcojakob commented 10 years ago

Thanks @friegger for the hints.

I have done a few things with Polymer.dart but I'm not sure if I really understand the Event concept in Shadow DOM, yet. I'd have to dig into that.

Apart from that, I'm not sure at the moment if it is the right way to implement our own Mouse, Touch, and Pointer (IE) event handling mechanism for Shadow DOM while there is the PointerEvents library for Polymer.

I've lately come across a thread about PointerEvents with a discussion about PointerEvents beeing replaced by PolymerGestures. It talks about perfomance problems:

The big culprit was the gymnastics the PointerEvents polyfill had to make to be spec compliant and target the correct elements with ShadowDOM. In particular, the encapsulation mechanics of ShadowDOM made target finding for pointermove very expensive, requiring recursive elementFromPoint calls.

This seems to be a bigger problem and we would probably also run into the issue of recursive elementFromPoint calls when we want to detect dragEnter and dragLeave for drag and drop.

What do you think?

johnryan1982 commented 10 years ago

Hi both,

First off, thanks @marcojakob for a great library.

I'm curious as to whether there's been any resolution to this? I'm currently exploring the possibility of using this library for an upcoming project, however there'll be a heavy reliance on dnd and in particular handling drag/drop events within a view. In my initial tests, I'm able to trace events registered to the draggable elements, but nothing appears to be triggered for dropzone elements. Any suggestions...?

Any help would be appreciated thanks

Update: I've created a basic example to illustrate what I am trying to do (https://bitbucket.org/johnryanancoa/componentdecorator/src/). It currently prints messages to the console for the draggable events, but nothing for the droppable events. Am I missing something obvious? Thanks!

marcojakob commented 10 years ago

Hi John

I'm on vacation right now, so only a short answer: I didn't have the time to look into the issue with shadow dom as I didn't run into it with any of my projects, yet. But I would be glad to help with testing/reviewing, if someone could provide a pull request.

Maybe a place to start could be to look at how dnd is handled in the following Polymer library: https://github.com/Polymer/core-drag-drop

This conversation could also provide some hints: https://groups.google.com/forum/m/#!topic/polymer-dev/ba4aDyOozm8

LeonHeesterbeek commented 9 years ago

Dear Marco,

I'm trying to use the drag and drop library to create some polymer elements. When I try to wrap a list with items and drag a list item around, only the parent (wrapper) can handle the dropzone events. Is there a way to fix this problem using the current library?

marcojakob commented 9 years ago

@LeonHeesterbeek I currently don't have plans to support Polymer with this library but I'm happy to accept any pull requests if anyone can make it work.

marcojakob commented 9 years ago

I've tried to fix this library to work with Shadow DOM. It works like this:

_You must add a dnd-retarget attribute on all custom elements where you want events to be forwarded to it's Shadow DOM children. Forwarding happens in draggable_manager.dart (https://github.com/marcojakob/dart-dnd/blob/master/lib/src/draggable_manager.dart#L153)._

Before I release a new version: Could some of you verify that this works and is a good idea? What do you think about performance?

Here is a live example: http://marcojakob.github.io/dart-dnd/shadow-dom/ And here is the example code: https://github.com/marcojakob/dart-dnd/tree/master/example/shadow-dom

Thanks for all your feedback.

marcojakob commented 9 years ago

What do you think @Belsi? Does this fix your problem?

@friegger and @johnryan1982: What do you think about the fix? Is this a good solution (see previous post)? Should I make the new release?

marcojakob commented 9 years ago

I'm closing this for now and releasing it in v0.2.0.