| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * Wraps a callback with translations of mouse events to touch events. Use | |
| 7 * this function to invoke your callback that expects touch events after | |
| 8 * touch events are created from the actual mouse events. | |
| 9 */ | |
| 10 EventListener mouseToTouchCallback(EventListener callback) { | |
| 11 return (MouseEvent e) { | |
| 12 var touches = <Touch>[]; | |
| 13 var targetTouches = <Touch>[]; | |
| 14 var changedTouches = <Touch>[]; | |
| 15 final mockTouch = new MockTouch(e); | |
| 16 final mockTouchList = <Touch>[mockTouch]; | |
| 17 if (e.type == 'mouseup') { | |
| 18 changedTouches = mockTouchList; | |
| 19 } else { | |
| 20 touches = mockTouchList; | |
| 21 targetTouches = mockTouchList; | |
| 22 } | |
| 23 callback(new MockTouchEvent(e, touches, targetTouches, changedTouches)); | |
| 24 // Required to prevent spurious selection changes while tracking touches | |
| 25 // on devices that don't support touch events. | |
| 26 e.preventDefault(); | |
| 27 }; | |
| 28 } | |
| 29 | |
| 30 /** Helper method to attach event listeners to a [node]. */ | |
| 31 void _addEventListeners(Element node, | |
| 32 EventListener onStart, EventListener onMove, EventListener onEnd, | |
| 33 EventListener onCancel, [bool capture = false]) { | |
| 34 | |
| 35 Function removeListeners; | |
| 36 | |
| 37 onEndWrapper(e) { | |
| 38 removeListeners(); | |
| 39 return onEnd(e); | |
| 40 } | |
| 41 | |
| 42 onLeaveWrapper(e) { | |
| 43 removeListeners(); | |
| 44 return onEnd(e); | |
| 45 } | |
| 46 | |
| 47 onCancelWrapper(e) { | |
| 48 removeListeners(); | |
| 49 return onCancel(e); | |
| 50 } | |
| 51 | |
| 52 if (Device.supportsTouch) { | |
| 53 removeListeners = () { | |
| 54 document.on.touchMove.remove(onMove, capture); | |
| 55 document.on.touchEnd.remove(onEndWrapper, capture); | |
| 56 document.on.touchLeave.remove(onLeaveWrapper, capture); | |
| 57 document.on.touchCancel.remove(onCancelWrapper, capture); | |
| 58 }; | |
| 59 | |
| 60 node.on.touchStart.add((e) { | |
| 61 document.on.touchMove.add(onMove, capture); | |
| 62 document.on.touchEnd.add(onEndWrapper, capture); | |
| 63 document.on.touchLeave.add(onLeaveWrapper, capture); | |
| 64 document.on.touchCancel.add(onCancelWrapper, capture); | |
| 65 return onStart(e); | |
| 66 }, capture); | |
| 67 } else { | |
| 68 onStart = mouseToTouchCallback(onStart); | |
| 69 onMove = mouseToTouchCallback(onMove); | |
| 70 onEnd = mouseToTouchCallback(onEnd); | |
| 71 // onLeave will never be called if the device does not support touches. | |
| 72 | |
| 73 removeListeners = () { | |
| 74 document.on.mouseMove.remove(onMove, capture); | |
| 75 document.on.mouseUp.remove(onEndWrapper, capture); | |
| 76 document.on.touchCancel.remove(onCancelWrapper, capture); | |
| 77 }; | |
| 78 | |
| 79 node.on.mouseDown.add((e) { | |
| 80 document.on.mouseMove.add(onMove, capture); | |
| 81 document.on.mouseUp.add(onEndWrapper, capture); | |
| 82 document.on.touchCancel.add(onCancelWrapper, capture); | |
| 83 return onStart(e); | |
| 84 }, capture); | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 /** | |
| 89 * Gets whether the given touch event targets the node, or one of the node's | |
| 90 * children. | |
| 91 */ | |
| 92 bool _touchEventTargetsNode(event, Node node) { | |
| 93 Node target = event.changedTouches[0].target; | |
| 94 | |
| 95 // TODO(rnystrom): Move this into Dom. | |
| 96 // Walk up the parents looking for the node. | |
| 97 while (target != null) { | |
| 98 if (target == node) { | |
| 99 return true; | |
| 100 } | |
| 101 target = target.parent; | |
| 102 } | |
| 103 | |
| 104 return false; | |
| 105 } | |
| 106 | |
| 107 interface Touchable { | |
| 108 /** | |
| 109 * Provide the HTML element that should respond to touch events. | |
| 110 */ | |
| 111 Element getElement(); | |
| 112 | |
| 113 /** | |
| 114 * The object has received a touchend event. | |
| 115 */ | |
| 116 void onTouchEnd(); | |
| 117 | |
| 118 /** | |
| 119 * The object has received a touchstart event. | |
| 120 * Returns return true if you want to allow a drag sequence to begin, | |
| 121 * false you want to disable dragging for the duration of this touch. | |
| 122 */ | |
| 123 bool onTouchStart(TouchEvent e); | |
| 124 } | |
| 125 | |
| 126 interface Draggable extends Touchable { | |
| 127 /** | |
| 128 * The object's drag sequence is now complete. | |
| 129 */ | |
| 130 void onDragEnd(); | |
| 131 | |
| 132 /** | |
| 133 * The object has been dragged to a new position. | |
| 134 */ | |
| 135 void onDragMove(); | |
| 136 | |
| 137 /** | |
| 138 * The object has started dragging. | |
| 139 * Returns true to allow a drag sequence to begin (custom behavior), | |
| 140 * false to disable dragging for this touch duration (allow native scrolling). | |
| 141 */ | |
| 142 bool onDragStart(TouchEvent e); | |
| 143 | |
| 144 bool get verticalEnabled(); | |
| 145 bool get horizontalEnabled(); | |
| 146 } | |
| 147 | |
| 148 class MockTouch implements Touch { | |
| 149 MouseEvent wrapped; | |
| 150 | |
| 151 MockTouch(MouseEvent this.wrapped) {} | |
| 152 | |
| 153 int get clientX() => wrapped.clientX; | |
| 154 | |
| 155 int get clientY() => wrapped.clientY; | |
| 156 | |
| 157 int get identifier() => 0; | |
| 158 | |
| 159 int get pageX() => wrapped.pageX; | |
| 160 | |
| 161 int get pageY() => wrapped.pageY; | |
| 162 | |
| 163 int get screenX() => wrapped.screenX; | |
| 164 | |
| 165 int get screenY() {return wrapped.screenY; } | |
| 166 | |
| 167 EventTarget get target() => wrapped.target; | |
| 168 | |
| 169 num get webkitForce() { throw new NotImplementedException(); } | |
| 170 int get webkitRadiusX() { throw new NotImplementedException(); } | |
| 171 int get webkitRadiusY() { throw new NotImplementedException(); } | |
| 172 num get webkitRotationAngle() { throw new NotImplementedException(); } | |
| 173 } | |
| 174 | |
| 175 class MockTouchEvent implements TouchEvent { | |
| 176 MouseEvent wrapped; | |
| 177 // TODO(jacobr): these are currently Lists instead of a TouchList. | |
| 178 final List<Touch> touches; | |
| 179 final List<Touch> targetTouches; | |
| 180 final List<Touch> changedTouches; | |
| 181 MockTouchEvent(MouseEvent this.wrapped, List<Touch> this.touches, | |
| 182 List<Touch> this.targetTouches, | |
| 183 List<Touch> this.changedTouches) {} | |
| 184 | |
| 185 bool get bubbles() => wrapped.bubbles; | |
| 186 | |
| 187 bool get cancelBubble() => wrapped.cancelBubble; | |
| 188 | |
| 189 void set cancelBubble(bool value) { wrapped.cancelBubble = value; } | |
| 190 | |
| 191 bool get cancelable() => wrapped.cancelable; | |
| 192 | |
| 193 EventTarget get currentTarget() => wrapped.currentTarget; | |
| 194 | |
| 195 bool get defaultPrevented() => wrapped.defaultPrevented; | |
| 196 | |
| 197 int get eventPhase() => wrapped.eventPhase; | |
| 198 | |
| 199 void set returnValue(bool value) { wrapped.returnValue = value; } | |
| 200 | |
| 201 bool get returnValue() => wrapped.returnValue; | |
| 202 | |
| 203 EventTarget get srcElement() => wrapped.srcElement; | |
| 204 | |
| 205 EventTarget get target() => wrapped.target; | |
| 206 | |
| 207 int get timeStamp() => wrapped.timeStamp; | |
| 208 | |
| 209 String get type() => wrapped.type; | |
| 210 | |
| 211 void preventDefault() { wrapped.preventDefault(); } | |
| 212 | |
| 213 void stopImmediatePropagation() { wrapped.stopImmediatePropagation(); } | |
| 214 | |
| 215 void stopPropagation() { wrapped.stopPropagation(); } | |
| 216 | |
| 217 int get charCode() => wrapped.charCode; | |
| 218 | |
| 219 int get detail() => wrapped.detail; | |
| 220 | |
| 221 int get keyCode() => wrapped.keyCode; | |
| 222 | |
| 223 int get layerX() => wrapped.layerX; | |
| 224 | |
| 225 int get layerY() => wrapped.layerY; | |
| 226 | |
| 227 int get pageX() => wrapped.pageX; | |
| 228 | |
| 229 int get pageY() => wrapped.pageY; | |
| 230 | |
| 231 Window get view() => wrapped.view; | |
| 232 | |
| 233 int get which() => wrapped.which; | |
| 234 | |
| 235 bool get altKey() => wrapped.altKey; | |
| 236 | |
| 237 bool get ctrlKey() => wrapped.ctrlKey; | |
| 238 | |
| 239 bool get metaKey() => wrapped.metaKey; | |
| 240 | |
| 241 bool get shiftKey() => wrapped.shiftKey; | |
| 242 } | |
| OLD | NEW |