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

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, 2 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
« no previous file with comments | « tools/dom/src/KeyboardEventStream.dart ('k') | tools/dom/src/dartium_KeyEvent.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..e8453035f4c74ad735bbd6d2b9a927fd1e57dfff 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;
@@ -44,25 +45,134 @@ class KeyEvent extends _WrappedEvent implements KeyboardEvent {
/** Accessor to the underlying altKey value is the parent event. */
bool get _realAltKey => JS('bool', '#.altKey', _parent);
+ /** Shadows on top of the parent's currentTarget. */
+ EventTarget _currentTarget;
+
+ /**
+ * The value we want to use for this object's dispatch. Created here so it is
+ * only invoked once.
+ */
+ static final _keyboardEventDispatchRecord = _makeRecord();
+
+ /** Helper to statically create the dispatch record. */
+ _makeRecord() {
+ // TODO(efortuna): Use better way to get interceptor and remove _private()
sra1 2013/10/07 18:46:10 I'd make this TODO(13873)
Emily Fortuna 2013/10/07 19:29:06 Okay. Just curious, when did this format change? F
+ // constructors; Issue 13873.
+ var interceptor = new KeyboardEvent._private();
+ return makeLeafDispatchRecord(interceptor);
+ }
+
/** 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;
+ _currentTarget = _parent.currentTarget;
+ }
+
+ /** 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, EventTarget currentTarget}) {
+ if (view == null) {
+ view = window;
+ }
+
+ var eventObj;
+ // In these two branches we create an underlying native KeyboardEvent, but
+ // we set it with our specified values. Because we are doing custom setting
+ // of certain values (charCode/keyCode, etc) only in this class (as opposed
+ // to KeyboardEvent) and the way we set these custom values depends on the
+ // type of underlying JS object, we do all the contruction for the
+ // underlying KeyboardEvent here.
+ 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!
+ setDispatchProperty(eventObj, _keyboardEventDispatchRecord);
+
+ var keyEvent = new KeyEvent.wrap(eventObj);
+ if (keyEvent._currentTarget == null) {
+ keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
+ }
+ return keyEvent;
+ }
+
+ // 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');
+
+ /** The currently registered target for this event. */
+ EventTarget get currentTarget => _currentTarget;
+
+ // 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;
« no previous file with comments | « tools/dom/src/KeyboardEventStream.dart ('k') | tools/dom/src/dartium_KeyEvent.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698