Chromium Code Reviews| Index: tools/dom/src/dart2js_KeyEvent.dart |
| diff --git a/tools/dom/src/dart2js_KeyEvent.dart b/tools/dom/src/dart2js_KeyEvent.dart |
| index 303d4457e60017571e47d48df2365a7f2ce52477..0b2c3865111710294c238f6b8a4c75f51f78208a 100644 |
| --- a/tools/dom/src/dart2js_KeyEvent.dart |
| +++ b/tools/dom/src/dart2js_KeyEvent.dart |
| @@ -10,6 +10,7 @@ |
| * on how we can make this class work with as many international keyboards as |
| * possible. Bugs welcome! |
| */ |
| +@Experimental() |
| class KeyEvent extends _WrappedEvent implements KeyboardEvent { |
| /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */ |
| KeyboardEvent _parent; |
| @@ -45,24 +46,103 @@ class KeyEvent extends _WrappedEvent implements KeyboardEvent { |
| bool get _realAltKey => JS('bool', '#.altKey', _parent); |
| /** Construct a KeyEvent with [parent] as the event we're emulating. */ |
| - KeyEvent(KeyboardEvent parent): super(parent) { |
| + KeyEvent.wrap(KeyboardEvent parent): super(parent) { |
| _parent = parent; |
| _shadowAltKey = _realAltKey; |
| _shadowCharCode = _realCharCode; |
| _shadowKeyCode = _realKeyCode; |
| } |
| + /** Programmatically create a new KeyEvent (and KeyboardEvent). */ |
| + factory KeyEvent(String type, |
| + {Window view, bool canBubble: true, bool cancelable: true, int keyCode: 0, |
| + int charCode: 0, int keyLocation: 1, bool ctrlKey: false, |
| + bool altKey: false, bool shiftKey: false, bool metaKey: false, |
| + bool altGraphKey: false}) { |
| + if (view == null) { |
|
blois
2013/09/09 21:13:15
If this event cannot be dispatched, why not have a
|
| + view = window; |
| + } |
| + |
| + var eventObj; |
| + if (canUseDispatchEvent) { |
| + // Currently works in everything but Internet Explorer. |
| + eventObj = new Event.eventType('Event', type, |
| + canBubble: canBubble, cancelable: cancelable); |
| + |
| + JS('void', '#.keyCode = #', eventObj, keyCode); |
| + JS('void', '#.which = #', eventObj, keyCode); |
| + JS('void', '#.charCode = #', eventObj, charCode); |
| + |
| + JS('void', '#.keyLocation = #', eventObj, keyLocation); |
| + JS('void', '#.ctrlKey = #', eventObj, ctrlKey); |
| + JS('void', '#.altKey = #', eventObj, altKey); |
| + JS('void', '#.shiftKey = #', eventObj, shiftKey); |
| + JS('void', '#.metaKey = #', eventObj, metaKey); |
| + JS('void', '#.altGraphKey = #', eventObj, altGraphKey); |
| + } else { |
| + // Currently this works on everything but Safari. Safari throws an |
| + // "Attempting to change access mechanism for an unconfigurable property" |
| + // TypeError when trying to do the Object.defineProperty hack, so we avoid |
| + // this branch if possible. |
| + // Also, if we want this branch to work in FF, we also need to modify |
| + // _initKeyboardEvent to also take charCode and keyCode values to |
| + // initialize initKeyEvent. |
| + |
| + eventObj = new Event.eventType('KeyboardEvent', type, |
| + canBubble: canBubble, cancelable: cancelable); |
| + |
| + // Chromium Hack |
| + JS('void', "Object.defineProperty(#, 'keyCode', {" |
| + " get : function() { return this.keyCodeVal; } })", eventObj); |
| + JS('void', "Object.defineProperty(#, 'which', {" |
| + " get : function() { return this.keyCodeVal; } })", eventObj); |
| + JS('void', "Object.defineProperty(#, 'charCode', {" |
| + " get : function() { return this.charCodeVal; } })", eventObj); |
| + |
| + var keyIdentifier = _convertToHexString(charCode, keyCode); |
| + eventObj._initKeyboardEvent(type, canBubble, cancelable, view, |
| + keyIdentifier, keyLocation, ctrlKey, altKey, shiftKey, metaKey, |
| + altGraphKey); |
| + JS('void', '#.keyCodeVal = #', eventObj, keyCode); |
| + JS('void', '#.charCodeVal = #', eventObj, charCode); |
| + } |
| + // Tell dart2js that it smells like a KeyboardEvent! |
| + var interceptor = new KeyboardEvent._private(); |
|
blois
2013/09/09 21:13:15
Is there any way to use the JS constructor to get
Emily Fortuna
2013/10/04 23:41:30
No. Stephen and I worked on this, and this was the
sra1
2013/10/07 17:47:11
It would certainly be handy to have a special way
Emily Fortuna
2013/10/07 18:43:04
Haven't run into other instances just yet, but I c
|
| + var record = makeLeafDispatchRecord(interceptor); |
|
Emily Fortuna
2013/09/04 00:08:08
Stephen and I worked on this wackiness. It was the
|
| + setDispatchProperty(eventObj, record); |
| + |
| + return new KeyEvent.wrap(eventObj); |
| + } |
| + |
| + // Currently known to work on all browsers but IE. |
| + static bool get canUseDispatchEvent => |
| + JS('bool', '(typeof document.body.dispatchEvent == "function")' |
| + '&& document.body.dispatchEvent.length > 0'); |
| + |
| + // This is an experimental method to be sure. |
| + static String _convertToHexString(int charCode, int keyCode) { |
| + if (charCode != -1) { |
| + var hex = charCode.toRadixString(16); // Convert to hexadecimal. |
| + StringBuffer sb = new StringBuffer('U+'); |
| + for (int i = 0; i < 4 - hex.length; i++) sb.write('0'); |
| + sb.write(hex); |
| + return sb.toString(); |
| + } else { |
| + return KeyCode._convertKeyCodeToKeyName(keyCode); |
| + } |
| + } |
| + |
| // TODO(efortuna): If KeyEvent is sufficiently successful that we want to make |
| // it the default keyboard event handling, move these methods over to Element. |
| /** Accessor to provide a stream of KeyEvents on the desired target. */ |
| static EventStreamProvider<KeyEvent> keyDownEvent = |
| - new _KeyboardEventHandler('keydown'); |
| + new _KeyboardEventHandler('keydown'); |
| /** Accessor to provide a stream of KeyEvents on the desired target. */ |
| static EventStreamProvider<KeyEvent> keyUpEvent = |
| - new _KeyboardEventHandler('keyup'); |
| + new _KeyboardEventHandler('keyup'); |
| /** Accessor to provide a stream of KeyEvents on the desired target. */ |
| static EventStreamProvider<KeyEvent> keyPressEvent = |
| - new _KeyboardEventHandler('keypress'); |
| + new _KeyboardEventHandler('keypress'); |
| /** True if the altGraphKey is pressed during this event. */ |
| bool get altGraphKey => _parent.altGraphKey; |