Skip to content

Commit d646edf

Browse files
committed
Move feature detection to html5_dnd.dart and utils to utils.dart
Also add the contains() helper method to utils.dart and use it whenever svg elements could be involved.
1 parent a07cb14 commit d646edf

File tree

10 files changed

+171
-163
lines changed

10 files changed

+171
-163
lines changed

lib/html5_dnd.dart

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,16 @@ library html5_dnd;
66

77
import 'dart:html';
88
import 'dart:async';
9-
import 'dart:collection';
109
import 'dart:math' as math;
1110
import 'dart:svg' as svg;
1211
import 'package:meta/meta.dart';
1312
import 'package:logging/logging.dart';
1413

15-
import 'src/css_utils.dart' as css;
16-
import 'src/html5_utils.dart' as html5;
14+
import 'src/utils.dart' as utils;
1715

1816
import 'src/sortable/sortable.dart';
1917
export 'src/sortable/sortable.dart';
2018

21-
2219
part 'src/dnd/group.dart';
2320
part 'src/dnd/draggable.dart';
2421
part 'src/dnd/draggable_emulated.dart';
@@ -28,7 +25,6 @@ part 'src/touch/touch.dart';
2825

2926
final _logger = new Logger("html5_dnd");
3027

31-
3228
/**
3329
* If this property is set to true, touch events are enabled on devices that
3430
* support it.
@@ -37,9 +33,65 @@ final _logger = new Logger("html5_dnd");
3733
*/
3834
bool enableTouchEvents = true;
3935

36+
37+
// -------------------
38+
// Feature Detection
39+
// -------------------
40+
bool _usesTouchEvents;
41+
bool _supportsDraggable;
42+
bool _supportsSetDragImage;
43+
bool _isInternetExplorer;
44+
4045
/**
41-
* Return true if touch events are enabled and the current device supports it.
46+
* Returns true if touch events are enabled and the current device supports it.
47+
*/
48+
bool usesTouchEvents() {
49+
if (_usesTouchEvents == null) {
50+
_usesTouchEvents = enableTouchEvents && TouchEvent.supported;
51+
_logger.finest('Using touch events: $_usesTouchEvents.');
52+
}
53+
return _usesTouchEvents;
54+
}
55+
56+
/**
57+
* Returns true if the HTML5 Draggable Element is supported.
58+
* IE9 will return false.
59+
*/
60+
bool get supportsDraggable {
61+
if (_supportsDraggable == null) {
62+
_supportsDraggable = new Element.tag('span').draggable != null;
63+
_logger.finest('Browser support for HTML5 draggable: $_supportsDraggable.');
64+
}
65+
return _supportsDraggable;
66+
}
67+
68+
/**
69+
* Returns true if the browser supports "setDragImage" of HTML5 Drag and Drop.
70+
* IE9 and IE10 will return false.
71+
*/
72+
bool get supportsSetDragImage {
73+
if (_supportsSetDragImage == null) {
74+
// TODO: We should do feature detection instead of browser detection here
75+
// but there currently is no way in Dart.
76+
// TODO: Keep an eye on IE11.
77+
78+
// Detect Internet Explorer (which does not support HTML5 setDragImage).
79+
if (isInternetExplorer) {
80+
_supportsSetDragImage = false;
81+
} else {
82+
_supportsSetDragImage = true;
83+
}
84+
_logger.finest('Browser support for HTML5 setDragImage: $_supportsSetDragImage.');
85+
}
86+
return _supportsSetDragImage;
87+
}
88+
89+
/**
90+
* Returns true if the current browser is Internet Explorer.
4291
*/
43-
bool _useTouchEvents() {
44-
return enableTouchEvents && TouchEvent.supported;
92+
bool get isInternetExplorer {
93+
if (_isInternetExplorer == null) {
94+
_isInternetExplorer = window.navigator.appName == 'Microsoft Internet Explorer';
95+
}
96+
return _isInternetExplorer;
4597
}

lib/src/css_utils.dart

Lines changed: 0 additions & 30 deletions
This file was deleted.

lib/src/dnd/draggable.dart

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class DraggableGroup extends Group {
111111
return _onDragEnd.stream;
112112
}
113113

114-
bool _emulateDraggable = false;
114+
bool _browserRequiresDraggableEmulation = false;
115115

116116
/**
117117
* Constructor to create a [DraggableGroup].
@@ -133,13 +133,13 @@ class DraggableGroup extends Group {
133133
// Must emulate if either browser does not support HTML5 draggable
134134
// (IE9) or there is a custom drag image and browser does not support
135135
// setDragImage (IE10).
136-
if(!html5.supportsDraggable
137-
|| (dragImageFunction != null && !html5.supportsSetDragImage)) {
136+
if(!supportsDraggable
137+
|| (dragImageFunction != null && !supportsSetDragImage)) {
138138
_logger.finest('Browser does not (completely) support HTML5 draggable.');
139-
_emulateDraggable = true;
139+
_browserRequiresDraggableEmulation = true;
140140
} else {
141141
_logger.finest('Browser does support HTML5 draggable.');
142-
_emulateDraggable = false;
142+
_browserRequiresDraggableEmulation = false;
143143
}
144144
}
145145

@@ -151,7 +151,7 @@ class DraggableGroup extends Group {
151151

152152
List<StreamSubscription> subs = new List<StreamSubscription>();
153153

154-
if (_emulateDraggable || element is svg.SvgElement) {
154+
if (_browserRequiresDraggableEmulation || element is svg.SvgElement) {
155155
_logger.finest('installing as emulated draggable');
156156
subs.addAll(_installEmulatedDraggable(element, this));
157157
} else {
@@ -160,7 +160,7 @@ class DraggableGroup extends Group {
160160
}
161161

162162
// Install touch events if enabled and supported.
163-
if (_useTouchEvents()) {
163+
if (usesTouchEvents()) {
164164
_logger.finest('installing touch support');
165165
subs.addAll(_installTouchEvents(element, this));
166166
}
@@ -254,7 +254,7 @@ List<StreamSubscription> _installDraggable(Element element, DraggableGroup group
254254

255255
// Remove all text selections. Selections can otherwise lead to strange
256256
// behaviour when present on dragStart.
257-
html5.clearTextSelections();
257+
utils.clearTextSelections();
258258

259259
// Remove draggable attribute on mouse up (anywhere on document).
260260
StreamSubscription upSub;
@@ -411,7 +411,7 @@ class DragImage {
411411
*/
412412
DragImage._forDraggable(Element draggable, Point mousePosition) {
413413
// Calc the mouse position relative to the draggable.
414-
Point draggableOffset = css.pageOffset(draggable);
414+
Point draggableOffset = utils.pageOffset(draggable);
415415
this.x = (mousePosition.x - draggableOffset.x).round();
416416
this.y = (mousePosition.y - draggableOffset.y).round();
417417

@@ -442,7 +442,7 @@ class DragImage {
442442
void _addEmulatedDragImage(Element draggable) {
443443
_logger.finest('Adding emulated drag image.');
444444

445-
var parent = draggable.parentNode;
445+
Node parent = draggable.parentNode;
446446

447447
// Walk parents until we find a non-SVG element. This is to handle cases
448448
// where we're dragging a node within an SVG document.
@@ -477,14 +477,4 @@ class DragImage {
477477
element.style.top = '${(newMousePagePosition.y - this.y)}px';
478478
element.style.visibility = 'visible';
479479
}
480-
481-
bool _contains(EventTarget target) {
482-
// If the drag image is an SvgElement, we need to do contains() differently.
483-
// IE9 does not support the contains() method on SVG elements.
484-
return element is svg.SvgElement ? _svgContains(element, target) : element.contains(target);
485-
}
486-
}
487-
488-
bool _svgContains(Element element, EventTarget target) {
489-
return (target == element) ? true : element.children.any((e) => _svgContains(e, target));
490480
}

lib/src/dnd/draggable_emulated.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ List<StreamSubscription> _installEmulatedDraggable(Element element, DraggableGro
5959

6060
// Text selections should not be a problem with emulated draggable, but it
6161
// seems better usability to remove text selection when dragging something.
62-
html5.clearTextSelections();
62+
utils.clearTextSelections();
6363

6464
// Set the flag to prevent other widgets from inheriting the event
6565
_emulDragHandled = true;
@@ -296,7 +296,7 @@ void _restoreCursor() {
296296
EventTarget _getRealTarget(EventTarget target, Point mouseClientPosition) {
297297
EventTarget realTarget = target;
298298

299-
if (_emulDragImage.element == target || _emulDragImage._contains(target)) {
299+
if (utils.contains(_emulDragImage.element, target)) {
300300
// Forward events on the drag image to element underneath.
301301
_emulDragImage.element.style.visibility = 'hidden';
302302
realTarget = document.elementFromPoint(mouseClientPosition.x,

lib/src/dnd/dropzone.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,7 @@ EventTarget _lastDragEnterTarget;
319319
* mouse entered to.
320320
*/
321321
bool _isMainEvent(Element mainElement, EventTarget relatedTarget) {
322-
return (relatedTarget == null
323-
|| (relatedTarget != mainElement && !mainElement.contains(relatedTarget)));
322+
return relatedTarget == null || (!utils.contains(mainElement, relatedTarget));
324323
}
325324

326325
/**

lib/src/dnd/dropzone_emulated.dart

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,4 @@ List<StreamSubscription> _installEmulatedDropzone(Element element, DropzoneGroup
9393
}));
9494

9595
return subs;
96-
}
97-
98-
/**
99-
* Returns true if either [target1] is an ancestor of [target2] or
100-
* [target2] is a an ancestor of [target1].
101-
*/
102-
bool _areAncestors(EventTarget target1, EventTarget target2) {
103-
if (target1 is! Element || target2 is! Element) return false;
104-
105-
return target1.contains(target2) || target2.contains(target1);
10696
}

lib/src/html5_utils.dart

Lines changed: 0 additions & 83 deletions
This file was deleted.

0 commit comments

Comments
 (0)