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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/dom/src/KeyboardEventStream.dart ('k') | tools/dom/src/dartium_KeyEvent.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /** 1 /**
2 * A custom KeyboardEvent that attempts to eliminate cross-browser 2 * A custom KeyboardEvent that attempts to eliminate cross-browser
3 * inconsistencies, and also provide both keyCode and charCode information 3 * inconsistencies, and also provide both keyCode and charCode information
4 * for all key events (when such information can be determined). 4 * for all key events (when such information can be determined).
5 * 5 *
6 * KeyEvent tries to provide a higher level, more polished keyboard event 6 * KeyEvent tries to provide a higher level, more polished keyboard event
7 * information on top of the "raw" [KeyboardEvent]. 7 * information on top of the "raw" [KeyboardEvent].
8 * 8 *
9 * This class is very much a work in progress, and we'd love to get information 9 * This class is very much a work in progress, and we'd love to get information
10 * on how we can make this class work with as many international keyboards as 10 * on how we can make this class work with as many international keyboards as
11 * possible. Bugs welcome! 11 * possible. Bugs welcome!
12 */ 12 */
13 @Experimental()
13 class KeyEvent extends _WrappedEvent implements KeyboardEvent { 14 class KeyEvent extends _WrappedEvent implements KeyboardEvent {
14 /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */ 15 /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
15 KeyboardEvent _parent; 16 KeyboardEvent _parent;
16 17
17 /** The "fixed" value of whether the alt key is being pressed. */ 18 /** The "fixed" value of whether the alt key is being pressed. */
18 bool _shadowAltKey; 19 bool _shadowAltKey;
19 20
20 /** Caculated value of what the estimated charCode is for this event. */ 21 /** Caculated value of what the estimated charCode is for this event. */
21 int _shadowCharCode; 22 int _shadowCharCode;
22 23
(...skipping 14 matching lines...) Expand all
37 38
38 /** Accessor to the underlying keyCode value is the parent event. */ 39 /** Accessor to the underlying keyCode value is the parent event. */
39 int get _realKeyCode => JS('int', '#.keyCode', _parent); 40 int get _realKeyCode => JS('int', '#.keyCode', _parent);
40 41
41 /** Accessor to the underlying charCode value is the parent event. */ 42 /** Accessor to the underlying charCode value is the parent event. */
42 int get _realCharCode => JS('int', '#.charCode', _parent); 43 int get _realCharCode => JS('int', '#.charCode', _parent);
43 44
44 /** Accessor to the underlying altKey value is the parent event. */ 45 /** Accessor to the underlying altKey value is the parent event. */
45 bool get _realAltKey => JS('bool', '#.altKey', _parent); 46 bool get _realAltKey => JS('bool', '#.altKey', _parent);
46 47
48 /** Shadows on top of the parent's currentTarget. */
49 EventTarget _currentTarget;
50
51 /**
52 * The value we want to use for this object's dispatch. Created here so it is
53 * only invoked once.
54 */
55 static final _keyboardEventDispatchRecord = _makeRecord();
56
57 /** Helper to statically create the dispatch record. */
58 _makeRecord() {
59 // 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
60 // constructors; Issue 13873.
61 var interceptor = new KeyboardEvent._private();
62 return makeLeafDispatchRecord(interceptor);
63 }
64
47 /** Construct a KeyEvent with [parent] as the event we're emulating. */ 65 /** Construct a KeyEvent with [parent] as the event we're emulating. */
48 KeyEvent(KeyboardEvent parent): super(parent) { 66 KeyEvent.wrap(KeyboardEvent parent): super(parent) {
49 _parent = parent; 67 _parent = parent;
50 _shadowAltKey = _realAltKey; 68 _shadowAltKey = _realAltKey;
51 _shadowCharCode = _realCharCode; 69 _shadowCharCode = _realCharCode;
52 _shadowKeyCode = _realKeyCode; 70 _shadowKeyCode = _realKeyCode;
71 _currentTarget = _parent.currentTarget;
72 }
73
74 /** Programmatically create a new KeyEvent (and KeyboardEvent). */
75 factory KeyEvent(String type,
76 {Window view, bool canBubble: true, bool cancelable: true, int keyCode: 0,
77 int charCode: 0, int keyLocation: 1, bool ctrlKey: false,
78 bool altKey: false, bool shiftKey: false, bool metaKey: false,
79 bool altGraphKey: false, EventTarget currentTarget}) {
80 if (view == null) {
81 view = window;
82 }
83
84 var eventObj;
85 // In these two branches we create an underlying native KeyboardEvent, but
86 // we set it with our specified values. Because we are doing custom setting
87 // of certain values (charCode/keyCode, etc) only in this class (as opposed
88 // to KeyboardEvent) and the way we set these custom values depends on the
89 // type of underlying JS object, we do all the contruction for the
90 // underlying KeyboardEvent here.
91 if (canUseDispatchEvent) {
92 // Currently works in everything but Internet Explorer.
93 eventObj = new Event.eventType('Event', type,
94 canBubble: canBubble, cancelable: cancelable);
95
96 JS('void', '#.keyCode = #', eventObj, keyCode);
97 JS('void', '#.which = #', eventObj, keyCode);
98 JS('void', '#.charCode = #', eventObj, charCode);
99
100 JS('void', '#.keyLocation = #', eventObj, keyLocation);
101 JS('void', '#.ctrlKey = #', eventObj, ctrlKey);
102 JS('void', '#.altKey = #', eventObj, altKey);
103 JS('void', '#.shiftKey = #', eventObj, shiftKey);
104 JS('void', '#.metaKey = #', eventObj, metaKey);
105 JS('void', '#.altGraphKey = #', eventObj, altGraphKey);
106 } else {
107 // Currently this works on everything but Safari. Safari throws an
108 // "Attempting to change access mechanism for an unconfigurable property"
109 // TypeError when trying to do the Object.defineProperty hack, so we avoid
110 // this branch if possible.
111 // Also, if we want this branch to work in FF, we also need to modify
112 // _initKeyboardEvent to also take charCode and keyCode values to
113 // initialize initKeyEvent.
114
115 eventObj = new Event.eventType('KeyboardEvent', type,
116 canBubble: canBubble, cancelable: cancelable);
117
118 // Chromium Hack
119 JS('void', "Object.defineProperty(#, 'keyCode', {"
120 " get : function() { return this.keyCodeVal; } })", eventObj);
121 JS('void', "Object.defineProperty(#, 'which', {"
122 " get : function() { return this.keyCodeVal; } })", eventObj);
123 JS('void', "Object.defineProperty(#, 'charCode', {"
124 " get : function() { return this.charCodeVal; } })", eventObj);
125
126 var keyIdentifier = _convertToHexString(charCode, keyCode);
127 eventObj._initKeyboardEvent(type, canBubble, cancelable, view,
128 keyIdentifier, keyLocation, ctrlKey, altKey, shiftKey, metaKey,
129 altGraphKey);
130 JS('void', '#.keyCodeVal = #', eventObj, keyCode);
131 JS('void', '#.charCodeVal = #', eventObj, charCode);
132 }
133 // Tell dart2js that it smells like a KeyboardEvent!
134 setDispatchProperty(eventObj, _keyboardEventDispatchRecord);
135
136 var keyEvent = new KeyEvent.wrap(eventObj);
137 if (keyEvent._currentTarget == null) {
138 keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
139 }
140 return keyEvent;
141 }
142
143 // Currently known to work on all browsers but IE.
144 static bool get canUseDispatchEvent =>
145 JS('bool',
146 '(typeof document.body.dispatchEvent == "function")'
147 '&& document.body.dispatchEvent.length > 0');
148
149 /** The currently registered target for this event. */
150 EventTarget get currentTarget => _currentTarget;
151
152 // This is an experimental method to be sure.
153 static String _convertToHexString(int charCode, int keyCode) {
154 if (charCode != -1) {
155 var hex = charCode.toRadixString(16); // Convert to hexadecimal.
156 StringBuffer sb = new StringBuffer('U+');
157 for (int i = 0; i < 4 - hex.length; i++) sb.write('0');
158 sb.write(hex);
159 return sb.toString();
160 } else {
161 return KeyCode._convertKeyCodeToKeyName(keyCode);
162 }
53 } 163 }
54 164
55 // TODO(efortuna): If KeyEvent is sufficiently successful that we want to make 165 // TODO(efortuna): If KeyEvent is sufficiently successful that we want to make
56 // it the default keyboard event handling, move these methods over to Element. 166 // it the default keyboard event handling, move these methods over to Element.
57 /** Accessor to provide a stream of KeyEvents on the desired target. */ 167 /** Accessor to provide a stream of KeyEvents on the desired target. */
58 static EventStreamProvider<KeyEvent> keyDownEvent = 168 static EventStreamProvider<KeyEvent> keyDownEvent =
59 new _KeyboardEventHandler('keydown'); 169 new _KeyboardEventHandler('keydown');
60 /** Accessor to provide a stream of KeyEvents on the desired target. */ 170 /** Accessor to provide a stream of KeyEvents on the desired target. */
61 static EventStreamProvider<KeyEvent> keyUpEvent = 171 static EventStreamProvider<KeyEvent> keyUpEvent =
62 new _KeyboardEventHandler('keyup'); 172 new _KeyboardEventHandler('keyup');
63 /** Accessor to provide a stream of KeyEvents on the desired target. */ 173 /** Accessor to provide a stream of KeyEvents on the desired target. */
64 static EventStreamProvider<KeyEvent> keyPressEvent = 174 static EventStreamProvider<KeyEvent> keyPressEvent =
65 new _KeyboardEventHandler('keypress'); 175 new _KeyboardEventHandler('keypress');
66 176
67 /** True if the altGraphKey is pressed during this event. */ 177 /** True if the altGraphKey is pressed during this event. */
68 bool get altGraphKey => _parent.altGraphKey; 178 bool get altGraphKey => _parent.altGraphKey;
69 /** Accessor to the clipboardData available for this event. */ 179 /** Accessor to the clipboardData available for this event. */
70 DataTransfer get clipboardData => _parent.clipboardData; 180 DataTransfer get clipboardData => _parent.clipboardData;
71 /** True if the ctrl key is pressed during this event. */ 181 /** True if the ctrl key is pressed during this event. */
72 bool get ctrlKey => _parent.ctrlKey; 182 bool get ctrlKey => _parent.ctrlKey;
73 int get detail => _parent.detail; 183 int get detail => _parent.detail;
74 /** 184 /**
75 * Accessor to the part of the keyboard that the key was pressed from (one of 185 * Accessor to the part of the keyboard that the key was pressed from (one of
(...skipping 20 matching lines...) Expand all
96 throw new UnsupportedError("keyIdentifier is unsupported."); 206 throw new UnsupportedError("keyIdentifier is unsupported.");
97 } 207 }
98 void _initKeyboardEvent(String type, bool canBubble, bool cancelable, 208 void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
99 Window view, String keyIdentifier, int keyLocation, bool ctrlKey, 209 Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
100 bool altKey, bool shiftKey, bool metaKey, 210 bool altKey, bool shiftKey, bool metaKey,
101 bool altGraphKey) { 211 bool altGraphKey) {
102 throw new UnsupportedError( 212 throw new UnsupportedError(
103 "Cannot initialize a KeyboardEvent from a KeyEvent."); 213 "Cannot initialize a KeyboardEvent from a KeyEvent.");
104 } 214 }
105 } 215 }
OLDNEW
« 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