Index: sdk/lib/html/dart2js/html_dart2js.dart |
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart |
index 78fb2021d8aa49eba670151b5c59a0d985b8c64c..1d03ea66be4c4031f3db25759620b3755d2078a4 100644 |
--- a/sdk/lib/html/dart2js/html_dart2js.dart |
+++ b/sdk/lib/html/dart2js/html_dart2js.dart |
@@ -7963,6 +7963,23 @@ abstract class Element extends Node implements ElementTraversal native "*Element |
@Creates('Null') // Set from Dart code; does not instantiate a native type. |
var xtag; |
+ static const EventStreamProvider<WheelEvent> mouseWheelEvent = |
+ const _CustomEventStreamProvider<WheelEvent>( |
+ Element._determineMouseWheelEventType); |
+ |
+ static String _determineMouseWheelEventType(EventTarget e) { |
+ if (JS('bool', '#.onwheel !== undefined', e)) { |
+ // W3C spec, and should be IE9+, but IE has a bug exposing onwheel. |
+ return 'wheel'; |
+ } else if (JS('bool', '#.onmousewheel !== undefined', e)) { |
+ // Chrome & IE |
+ return 'mousewheel'; |
+ } else { |
+ // Firefox |
+ return 'DOMMouseScroll'; |
+ } |
+ } |
+ |
/** |
* Creates a text node and inserts it into the DOM at the specified location. |
* |
@@ -8453,6 +8470,8 @@ abstract class Element extends Node implements ElementTraversal native "*Element |
Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this); |
+ Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this); |
+ |
Stream<Event> get onPaste => pasteEvent.forTarget(this); |
Stream<Event> get onReset => resetEvent.forTarget(this); |
@@ -21777,11 +21796,135 @@ class WebSocketEvents extends Events { |
/// @domName WheelEvent |
class WheelEvent extends MouseEvent native "*WheelEvent" { |
+ factory WheelEvent( |
+ String type, |
+ Window view, |
+ int wheelDeltaX, |
+ int wheelDeltaY, |
+ int detail, |
+ int screenX, |
+ int screenY, |
+ int clientX, |
+ int clientY, |
+ int button, |
+ [bool canBubble = true, |
+ bool cancelable = true, |
+ bool ctrlKey = false, |
+ bool altKey = false, |
+ bool shiftKey = false, |
+ bool metaKey = false, |
+ EventTarget relatedTarget = null]) { |
Siggi Cherem (dart-lang)
2013/01/16 18:52:00
generally indentation here looks strange. Consider
blois
2013/01/16 20:04:02
Updated. In general I find the collapsed form fair
|
+ |
+ var eventType = 'WheelEvent'; |
+ if (_Device.isFirefox) { |
+ eventType = 'MouseScrollEvents'; |
+ } |
+ final event = document.$dom_createEvent(eventType); |
+ |
+ if (_Device.isWebKit) { |
+ event.$dom_initMouseEvent( |
+ type, |
+ canBubble, |
+ cancelable, |
+ view, |
+ detail, |
+ screenX, |
+ screenY, |
+ clientX, |
+ clientY, |
+ ctrlKey, |
+ altKey, |
+ shiftKey, |
+ metaKey, |
+ button, |
+ relatedTarget); |
+ event.$dom_initWebKitWheelEvent( |
+ wheelDeltaX, |
+ (wheelDeltaY / 120).toInt(), // Chrome does an auto-convert to pixels. |
+ view, |
+ screenX, |
+ screenY, |
+ clientX, |
+ clientY, |
+ ctrlKey, |
+ altKey, |
+ shiftKey, |
+ metaKey); |
+ } |
+ else if (_Device.isIE) { |
Siggi Cherem (dart-lang)
2013/01/16 18:52:00
move else to previous line?
blois
2013/01/16 20:04:02
Was a by-product of template expansion, updated wi
|
+ var modifiers = []; |
+ if (ctrlKey) { |
+ modifiers.push('Control'); |
+ } |
+ if (altKey) { |
+ modifiers.push('Alt'); |
+ } |
+ if (shiftKey) { |
+ modifiers.push('Shift'); |
+ } |
+ if (metaKey) { |
+ modifiers.push('Meta'); |
+ } |
+ var modifiersList = modifiers.join(' '); |
+ event._initIEWheelEvent( |
+ type, |
+ canBubble, |
+ cancelable, |
+ view, |
+ detail, |
+ screenX, |
+ screenY, |
+ clientX, |
+ clientY, |
+ button, |
+ relatedTarget, |
+ modifiersList, |
Siggi Cherem (dart-lang)
2013/01/16 18:52:00
nit: maybe simply inline modifiers.join(' ') here?
blois
2013/01/16 20:04:02
Done.
|
+ wheelDeltaX, |
+ wheelDeltaY, |
+ 0, |
+ 0); |
+ } else if (_Device.isFirefox) { |
+ var axis = 0; |
+ var detail = 0; |
+ if (wheelDeltaX != 0 && wheelDeltaY != 0) { |
+ throw UnsupportedError( |
+ 'Cannot modify wheelDeltaX and wheelDeltaY simultaneously'); |
+ } |
+ if (wheelDeltaY != 0) { |
+ detail = wheelDeltaY; |
+ axis = JS('int', 'MouseScrollEvent.VERTICAL_AXIS'); |
+ } else if (wheelDeltaX != 0) { |
+ detail = wheelDeltaX; |
+ axis = JS('int', 'MouseScrollEvent.HORIZONTAL_AXIS'); |
+ } |
+ event._initFireFoxMouseScrollEvent( |
+ type, |
+ canBubble, |
+ cancelable, |
+ view, |
+ detail, |
+ screenX, |
+ screenY, |
+ clientX, |
+ clientY, |
+ ctrlKey, |
+ altKey, |
+ shiftKey, |
+ metaKey, |
+ button, |
+ relatedTarget, |
+ axis); |
+ } |
+ return event; |
+ } |
+ |
+ |
/// @domName WheelEvent.webkitDirectionInvertedFromDevice; @docsEditable true |
final bool webkitDirectionInvertedFromDevice; |
/// @domName WheelEvent.initWebKitWheelEvent; @docsEditable true |
- void initWebKitWheelEvent(int wheelDeltaX, int wheelDeltaY, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native; |
+ @JSName('initWebKitWheelEvent') |
+ void $dom_initWebKitWheelEvent(int wheelDeltaX, int wheelDeltaY, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native; |
/** @domName WheelEvent.deltaY */ |
@@ -21856,6 +21999,44 @@ class WheelEvent extends MouseEvent native "*WheelEvent" { |
num get _detail => JS('num', '#.detail', this); |
int get _deltaMode => JS('int', '#.deltaMode', this); |
+ @JSName('initMouseScrollEvent') |
+ void _initFireFoxMouseScrollEvent( |
+ String type, |
+ bool canBubble, |
+ bool cancelable, |
+ Window view, |
+ int detail, |
+ int screenX, |
+ int screenY, |
+ int clientX, |
+ int clientY, |
+ bool ctrlKey, |
+ bool altKey, |
+ bool shiftKey, |
+ bool metaKey, |
+ int button, |
+ EventTarget relatedTarget, |
+ int axis) native; |
+ |
+ @JSName('initWheelEvent') |
+ void _initIEWheelEvent( |
+ String eventType, |
+ bool canBubble, |
+ bool cancelable, |
+ Window view, |
+ int detail, |
+ int screenX, |
+ int screenY, |
+ int clientX, |
+ int clientY, |
+ int button, |
+ EventTarget relatedTarget, |
+ String modifiersList, |
+ int deltaX, |
+ int deltaY, |
+ int deltaZ, |
+ int deltaMode) native; |
+ |
} |
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
// for details. All rights reserved. Use of this source code is governed by a |
@@ -25533,6 +25714,23 @@ class EventStreamProvider<T extends Event> { |
return new _EventStream(e, _eventType, useCapture); |
} |
} |
+ |
+typedef String _EventTypeGetter(EventTarget target); |
Siggi Cherem (dart-lang)
2013/01/16 18:52:00
did you mean to use this type somewhere? (e.g. fie
blois
2013/01/16 20:04:02
Yes, but dart2js checked mode issue blocked it. re
|
+ |
+/** |
+ * A factory to expose DOM events as streams, where the DOM event name has to |
+ * be determined on the fly (for example, mouse wheel events). |
+ */ |
+class _CustomEventStreamProvider<T extends Event> |
+ implements EventStreamProvider<T> { |
+ |
+ final _eventTypeGetter; |
+ const _CustomEventStreamProvider(this._eventTypeGetter); |
+ |
+ Stream<T> forTarget(EventTarget e, {bool useCapture: false}) { |
+ return new _EventStream(e, _eventTypeGetter(e), useCapture); |
+ } |
+} |
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |