Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Unified Diff: tools/dom/src/dart2js_KeyEvent.dart

Issue 23455033: Fully polyfill KeyEvent so that you can programmatically create your own "keyboard" events. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698