Skip to content

Commit d7b910f

Browse files
committed
Fix firefox bug and Issue #1
* Fix Bug in Firefox when dragging over nested elements. * Fix Issue #1: overClass (.dnd-over) stays after drag ended
1 parent e5748c6 commit d7b910f

File tree

5 files changed

+32
-20
lines changed

5 files changed

+32
-20
lines changed

example/html5_dnd_example.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ part 'codeblocks.dart';
1212

1313
main() {
1414
// Uncomment to enable logging.
15-
// Logger.root.onRecord.listen(new PrintHandler().call);
16-
// Logger.root.level = Level.FINEST;
15+
Logger.root.onRecord.listen(new PrintHandler().call);
16+
Logger.root.level = Level.FINEST;
1717

1818
// Drag and Drop
1919
sectionDraggableAndDropzone();

lib/draggable.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class DraggableGroup extends Group {
4040
* returns 'text' as type with an empty String as data.
4141
*/
4242
DragDataFunction dragDataFunction = (Element draggable) {
43-
return {'text': ''};
43+
return {'Text': ' '};
4444
};
4545

4646
/**
@@ -400,10 +400,11 @@ class DragImage {
400400
// Make sure that mouse events are forwarded to the layer below.
401401
if (html5.supportsPointerEvents) {
402402
_polyfill = image;
403-
_polyfill.style.pointerEvents = 'none';
404403
} else {
404+
// IE9 and IE10 support pointer-events on SVGs only.
405405
_polyfill = _createSvgElement();
406406
}
407+
_polyfill.style.pointerEvents = 'none';
407408

408409
// Add some transparency.
409410
_polyfill.style.opacity = polyfillOpacity;
@@ -429,8 +430,6 @@ class DragImage {
429430
height="${image.height}"
430431
/>
431432
</svg>
432-
""")
433-
// Event IE9 and IE10 support pointer-events on SVGs.
434-
..style.pointerEvents = 'none';
433+
""");
435434
}
436435
}

lib/dropzone.dart

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,21 +96,31 @@ class DropzoneGroup extends Group {
9696
return; // Return here as drop is not accepted.
9797
}
9898

99-
_logger.finest('onDragEnter {dragOverElements.length before adding: ${currentDragOverElements.length}}');
100-
currentDragOverElements.add(mouseEvent.target);
101-
10299
// Only handle dropzone element itself and not any of its children.
103-
if (currentDragOverElements.length == 1) {
100+
if (currentDragOverElements.isEmpty) {
104101
_logger.finest('firing onDragEnter');
105102
if (currentDraggableGroup.overClass != null) {
106-
element.classes.add(currentDraggableGroup.overClass);
103+
String overClass = currentDraggableGroup.overClass;
104+
element.classes.add(overClass);
105+
106+
// Make sure overClass is removed when drag ended. Is necessary
107+
// because if drag is aborted (e.g. with esc-key), no dragLeave or
108+
// drop event is fired on the dropzone.
109+
StreamSubscription dragEndSub;
110+
dragEndSub = currentDraggable.onDragEnd.listen((_) {
111+
element.classes.remove(overClass);
112+
dragEndSub.cancel();
113+
});
107114
}
108115

109116
if (_onDragEnter != null) {
110117
_onDragEnter.add(new DropzoneEvent(currentDraggable,
111118
element, mouseEvent));
112119
}
113120
}
121+
122+
_logger.finest('onDragEnter {dragOverElements.length before adding: ${currentDragOverElements.length}}');
123+
currentDragOverElements.add(mouseEvent.target);
114124
}));
115125

116126
// Drag Over.
@@ -141,8 +151,8 @@ class DropzoneGroup extends Group {
141151

142152
// Firefox fires too many onDragLeave events. This condition fixes it.
143153
if (mouseEvent.target != mouseEvent.relatedTarget) {
144-
_logger.finest('onDragLeave {dragOverElements.length before removing: ${currentDragOverElements.length}}');
145154
currentDragOverElements.remove(mouseEvent.target);
155+
_logger.finest('onDragLeave {dragOverElements.length after removing: ${currentDragOverElements.length}}');
146156
}
147157

148158
// Only handle on dropzone element and not on any of its children.
@@ -167,10 +177,6 @@ class DropzoneGroup extends Group {
167177
// Stops browsers from redirecting.
168178
mouseEvent.preventDefault();
169179

170-
if (currentDraggableGroup.overClass != null) {
171-
element.classes.remove(currentDraggableGroup.overClass);
172-
}
173-
174180
if (_onDrop != null) {
175181
_onDrop.add(new DropzoneEvent(currentDraggable, element,
176182
mouseEvent));

lib/html5_dnd.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ DraggableGroup currentDraggableGroup;
3333
/// was fired on the real [dropzoneElement] and not on its children.
3434
Set<Element> currentDragOverElements = new Set<Element>();
3535

36+
/**
37+
* Abstract superclass for all groups containing drag and drop elements.
38+
*/
3639
abstract class Group {
3740
/// Map of all installed elements inside this group with their subscriptions.
3841
Map<Element, List<StreamSubscription>> installedElements =
@@ -70,5 +73,4 @@ abstract class Group {
7073
void uninstallAll(List<Element> elements) {
7174
elements.forEach((Element e) => uninstall(e));
7275
}
73-
7476
}

lib/sortable.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,13 @@ class SortableGroup extends DraggableGroup {
7676
*/
7777
SortableGroup({String handle}) :
7878
_dropzoneGroup = new DropzoneGroup(),
79-
super(handle: handle);
80-
79+
super(handle: handle) {
80+
// Disable overClass by default for sortable as we're usually only over the
81+
// placeholder and not over a dropzone. Same for draggingClass as the
82+
// dragged element is replaced by the placeholder and thus not visible.
83+
overClass = null;
84+
draggingClass = null;
85+
}
8186

8287
/**
8388
* Installs sortable behaviour on [element] and registers it in this group.

0 commit comments

Comments
 (0)