2 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
9 * DOM event simulation utility
10 * @module event-simulate
11 * @namespace YAHOO.util
12 * @requires yahoo,dom,event
16 * The UserAction object provides functions that simulate events occurring in
17 * the browser. Since these are simulated events, they do not behave exactly
18 * as regular, user-initiated events do, but can be used to test simple
19 * user interactions safely.
21 * @namespace YAHOO.util
25 YAHOO.util.UserAction = {
27 //--------------------------------------------------------------------------
28 // Generic event methods
29 //--------------------------------------------------------------------------
32 * Simulates a key event using the given event information to populate
33 * the generated event object. This method does browser-equalizing
34 * calculations to account for differences in the DOM and IE event models
35 * as well as different browser quirks. Note: keydown causes Safari 2.x to
37 * @method simulateKeyEvent
40 * @param {HTMLElement} target The target of the given event.
41 * @param {String} type The type of event to fire. This can be any one of
42 * the following: keyup, keydown, and keypress.
43 * @param {Boolean} bubbles (Optional) Indicates if the event can be
44 * bubbled up. DOM Level 3 specifies that all key events bubble by
45 * default. The default is true.
46 * @param {Boolean} cancelable (Optional) Indicates if the event can be
47 * canceled using preventDefault(). DOM Level 3 specifies that all
48 * key events can be cancelled. The default
50 * @param {Window} view (Optional) The view containing the target. This is
51 * typically the window object. The default is window.
52 * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
53 * is pressed while the event is firing. The default is false.
54 * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
55 * is pressed while the event is firing. The default is false.
56 * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
57 * is pressed while the event is firing. The default is false.
58 * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
59 * is pressed while the event is firing. The default is false.
60 * @param {int} keyCode (Optional) The code for the key that is in use.
62 * @param {int} charCode (Optional) The Unicode code for the character
63 * associated with the key being used. The default is 0.
65 simulateKeyEvent : function (target /*:HTMLElement*/, type /*:String*/,
66 bubbles /*:Boolean*/, cancelable /*:Boolean*/,
68 ctrlKey /*:Boolean*/, altKey /*:Boolean*/,
69 shiftKey /*:Boolean*/, metaKey /*:Boolean*/,
70 keyCode /*:int*/, charCode /*:int*/) /*:Void*/
73 target = YAHOO.util.Dom.get(target);
75 throw new Error("simulateKeyEvent(): Invalid target.");
79 if (YAHOO.lang.isString(type)){
80 type = type.toLowerCase();
86 case "textevent": //DOM Level 3
89 // @TODO was the fallthrough intentional, if so throw error
91 throw new Error("simulateKeyEvent(): Event type '" + type + "' not supported.");
94 throw new Error("simulateKeyEvent(): Event type must be a string.");
97 //setup default values
98 if (!YAHOO.lang.isBoolean(bubbles)){
99 bubbles = true; //all key events bubble
101 if (!YAHOO.lang.isBoolean(cancelable)){
102 cancelable = true; //all key events can be cancelled
104 if (!YAHOO.lang.isObject(view)){
105 view = window; //view is typically window
107 if (!YAHOO.lang.isBoolean(ctrlKey)){
110 if (!YAHOO.lang.isBoolean(altKey)){
113 if (!YAHOO.lang.isBoolean(shiftKey)){
116 if (!YAHOO.lang.isBoolean(metaKey)){
119 if (!YAHOO.lang.isNumber(keyCode)){
122 if (!YAHOO.lang.isNumber(charCode)){
126 //try to create a mouse event
127 var customEvent /*:MouseEvent*/ = null;
129 //check for DOM-compliant browsers first
130 if (YAHOO.lang.isFunction(document.createEvent)){
134 //try to create key event
135 customEvent = document.createEvent("KeyEvents");
138 * Interesting problem: Firefox implemented a non-standard
139 * version of initKeyEvent() based on DOM Level 2 specs.
140 * Key event was removed from DOM Level 2 and re-introduced
141 * in DOM Level 3 with a different interface. Firefox is the
142 * only browser with any implementation of Key Events, so for
143 * now, assume it's Firefox if the above line doesn't error.
145 //TODO: Decipher between Firefox's implementation and a correct one.
146 customEvent.initKeyEvent(type, bubbles, cancelable, view, ctrlKey,
147 altKey, shiftKey, metaKey, keyCode, charCode);
149 } catch (ex /*:Error*/){
152 * If it got here, that means key events aren't officially supported.
153 * Safari/WebKit is a real problem now. WebKit 522 won't let you
154 * set keyCode, charCode, or other properties if you use a
155 * UIEvent, so we first must try to create a generic event. The
156 * fun part is that this will throw an error on Safari 2.x. The
157 * end result is that we need another try...catch statement just to
158 * deal with this mess.
162 //try to create generic event - will fail in Safari 2.x
163 customEvent = document.createEvent("Events");
165 } catch (uierror /*:Error*/){
167 //the above failed, so create a UIEvent for Safari 2.x
168 customEvent = document.createEvent("UIEvents");
172 customEvent.initEvent(type, bubbles, cancelable);
175 customEvent.view = view;
176 customEvent.altKey = altKey;
177 customEvent.ctrlKey = ctrlKey;
178 customEvent.shiftKey = shiftKey;
179 customEvent.metaKey = metaKey;
180 customEvent.keyCode = keyCode;
181 customEvent.charCode = charCode;
188 target.dispatchEvent(customEvent);
190 } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
192 //create an IE event object
193 customEvent = document.createEventObject();
195 //assign available properties
196 customEvent.bubbles = bubbles;
197 customEvent.cancelable = cancelable;
198 customEvent.view = view;
199 customEvent.ctrlKey = ctrlKey;
200 customEvent.altKey = altKey;
201 customEvent.shiftKey = shiftKey;
202 customEvent.metaKey = metaKey;
205 * IE doesn't support charCode explicitly. CharCode should
206 * take precedence over any keyCode value for accurate
209 customEvent.keyCode = (charCode > 0) ? charCode : keyCode;
212 target.fireEvent("on" + type, customEvent);
215 throw new Error("simulateKeyEvent(): No event simulation framework present.");
220 * Simulates a mouse event using the given event information to populate
221 * the generated event object. This method does browser-equalizing
222 * calculations to account for differences in the DOM and IE event models
223 * as well as different browser quirks.
224 * @method simulateMouseEvent
227 * @param {HTMLElement} target The target of the given event.
228 * @param {String} type The type of event to fire. This can be any one of
229 * the following: click, dblclick, mousedown, mouseup, mouseout,
230 * mouseover, and mousemove.
231 * @param {Boolean} bubbles (Optional) Indicates if the event can be
232 * bubbled up. DOM Level 2 specifies that all mouse events bubble by
233 * default. The default is true.
234 * @param {Boolean} cancelable (Optional) Indicates if the event can be
235 * canceled using preventDefault(). DOM Level 2 specifies that all
236 * mouse events except mousemove can be cancelled. The default
237 * is true for all events except mousemove, for which the default
239 * @param {Window} view (Optional) The view containing the target. This is
240 * typically the window object. The default is window.
241 * @param {int} detail (Optional) The number of times the mouse button has
242 * been used. The default value is 1.
243 * @param {int} screenX (Optional) The x-coordinate on the screen at which
244 * point the event occured. The default is 0.
245 * @param {int} screenY (Optional) The y-coordinate on the screen at which
246 * point the event occured. The default is 0.
247 * @param {int} clientX (Optional) The x-coordinate on the client at which
248 * point the event occured. The default is 0.
249 * @param {int} clientY (Optional) The y-coordinate on the client at which
250 * point the event occured. The default is 0.
251 * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
252 * is pressed while the event is firing. The default is false.
253 * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
254 * is pressed while the event is firing. The default is false.
255 * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
256 * is pressed while the event is firing. The default is false.
257 * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
258 * is pressed while the event is firing. The default is false.
259 * @param {int} button (Optional) The button being pressed while the event
260 * is executing. The value should be 0 for the primary mouse button
261 * (typically the left button), 1 for the terciary mouse button
262 * (typically the middle button), and 2 for the secondary mouse button
263 * (typically the right button). The default is 0.
264 * @param {HTMLElement} relatedTarget (Optional) For mouseout events,
265 * this is the element that the mouse has moved to. For mouseover
266 * events, this is the element that the mouse has moved from. This
267 * argument is ignored for all other events. The default is null.
269 simulateMouseEvent : function (target /*:HTMLElement*/, type /*:String*/,
270 bubbles /*:Boolean*/, cancelable /*:Boolean*/,
271 view /*:Window*/, detail /*:int*/,
272 screenX /*:int*/, screenY /*:int*/,
273 clientX /*:int*/, clientY /*:int*/,
274 ctrlKey /*:Boolean*/, altKey /*:Boolean*/,
275 shiftKey /*:Boolean*/, metaKey /*:Boolean*/,
276 button /*:int*/, relatedTarget /*:HTMLElement*/) /*:Void*/
280 target = YAHOO.util.Dom.get(target);
282 throw new Error("simulateMouseEvent(): Invalid target.");
285 relatedTarget = relatedTarget || null;
288 if (YAHOO.lang.isString(type)){
289 type = type.toLowerCase();
300 throw new Error("simulateMouseEvent(): Event type '" + type + "' not supported.");
303 throw new Error("simulateMouseEvent(): Event type must be a string.");
306 //setup default values
307 if (!YAHOO.lang.isBoolean(bubbles)){
308 bubbles = true; //all mouse events bubble
310 if (!YAHOO.lang.isBoolean(cancelable)){
311 cancelable = (type != "mousemove"); //mousemove is the only one that can't be cancelled
313 if (!YAHOO.lang.isObject(view)){
314 view = window; //view is typically window
316 if (!YAHOO.lang.isNumber(detail)){
317 detail = 1; //number of mouse clicks must be at least one
319 if (!YAHOO.lang.isNumber(screenX)){
322 if (!YAHOO.lang.isNumber(screenY)){
325 if (!YAHOO.lang.isNumber(clientX)){
328 if (!YAHOO.lang.isNumber(clientY)){
331 if (!YAHOO.lang.isBoolean(ctrlKey)){
334 if (!YAHOO.lang.isBoolean(altKey)){
337 if (!YAHOO.lang.isBoolean(shiftKey)){
340 if (!YAHOO.lang.isBoolean(metaKey)){
343 if (!YAHOO.lang.isNumber(button)){
347 //try to create a mouse event
348 var customEvent /*:MouseEvent*/ = null;
350 //check for DOM-compliant browsers first
351 if (YAHOO.lang.isFunction(document.createEvent)){
353 customEvent = document.createEvent("MouseEvents");
355 //Safari 2.x (WebKit 418) still doesn't implement initMouseEvent()
356 if (customEvent.initMouseEvent){
357 customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
358 screenX, screenY, clientX, clientY,
359 ctrlKey, altKey, shiftKey, metaKey,
360 button, relatedTarget);
363 //the closest thing available in Safari 2.x is UIEvents
364 customEvent = document.createEvent("UIEvents");
365 customEvent.initEvent(type, bubbles, cancelable);
366 customEvent.view = view;
367 customEvent.detail = detail;
368 customEvent.screenX = screenX;
369 customEvent.screenY = screenY;
370 customEvent.clientX = clientX;
371 customEvent.clientY = clientY;
372 customEvent.ctrlKey = ctrlKey;
373 customEvent.altKey = altKey;
374 customEvent.metaKey = metaKey;
375 customEvent.shiftKey = shiftKey;
376 customEvent.button = button;
377 customEvent.relatedTarget = relatedTarget;
381 * Check to see if relatedTarget has been assigned. Firefox
382 * versions less than 2.0 don't allow it to be assigned via
383 * initMouseEvent() and the property is readonly after event
384 * creation, so in order to keep YAHOO.util.getRelatedTarget()
385 * working, assign to the IE proprietary toElement property
386 * for mouseout event and fromElement property for mouseover
389 if (relatedTarget && !customEvent.relatedTarget){
390 if (type == "mouseout"){
391 customEvent.toElement = relatedTarget;
392 } else if (type == "mouseover"){
393 customEvent.fromElement = relatedTarget;
398 target.dispatchEvent(customEvent);
400 } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
402 //create an IE event object
403 customEvent = document.createEventObject();
405 //assign available properties
406 customEvent.bubbles = bubbles;
407 customEvent.cancelable = cancelable;
408 customEvent.view = view;
409 customEvent.detail = detail;
410 customEvent.screenX = screenX;
411 customEvent.screenY = screenY;
412 customEvent.clientX = clientX;
413 customEvent.clientY = clientY;
414 customEvent.ctrlKey = ctrlKey;
415 customEvent.altKey = altKey;
416 customEvent.metaKey = metaKey;
417 customEvent.shiftKey = shiftKey;
419 //fix button property for IE's wacky implementation
422 customEvent.button = 1;
425 customEvent.button = 4;
431 customEvent.button = 0;
435 * Have to use relatedTarget because IE won't allow assignment
436 * to toElement or fromElement on generic events. This keeps
437 * YAHOO.util.customEvent.getRelatedTarget() functional.
439 customEvent.relatedTarget = relatedTarget;
442 target.fireEvent("on" + type, customEvent);
445 throw new Error("simulateMouseEvent(): No event simulation framework present.");
449 //--------------------------------------------------------------------------
451 //--------------------------------------------------------------------------
454 * Simulates a mouse event on a particular element.
455 * @param {HTMLElement} target The element to click on.
456 * @param {String} type The type of event to fire. This can be any one of
457 * the following: click, dblclick, mousedown, mouseup, mouseout,
458 * mouseover, and mousemove.
459 * @param {Object} options Additional event options (use DOM standard names).
463 fireMouseEvent : function (target /*:HTMLElement*/, type /*:String*/,
464 options /*:Object*/) /*:Void*/
466 options = options || {};
467 this.simulateMouseEvent(target, type, options.bubbles,
468 options.cancelable, options.view, options.detail, options.screenX,
469 options.screenY, options.clientX, options.clientY, options.ctrlKey,
470 options.altKey, options.shiftKey, options.metaKey, options.button,
471 options.relatedTarget);
475 * Simulates a click on a particular element.
476 * @param {HTMLElement} target The element to click on.
477 * @param {Object} options Additional event options (use DOM standard names).
481 click : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
482 this.fireMouseEvent(target, "click", options);
486 * Simulates a double click on a particular element.
487 * @param {HTMLElement} target The element to double click on.
488 * @param {Object} options Additional event options (use DOM standard names).
492 dblclick : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
493 this.fireMouseEvent( target, "dblclick", options);
497 * Simulates a mousedown on a particular element.
498 * @param {HTMLElement} target The element to act on.
499 * @param {Object} options Additional event options (use DOM standard names).
503 mousedown : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
504 this.fireMouseEvent(target, "mousedown", options);
508 * Simulates a mousemove on a particular element.
509 * @param {HTMLElement} target The element to act on.
510 * @param {Object} options Additional event options (use DOM standard names).
514 mousemove : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
515 this.fireMouseEvent(target, "mousemove", options);
519 * Simulates a mouseout event on a particular element. Use "relatedTarget"
520 * on the options object to specify where the mouse moved to.
521 * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
522 * toElement is assigned in its place. IE doesn't allow toElement to be
523 * be assigned, so relatedTarget is assigned in its place. Both of these
524 * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
526 * @param {HTMLElement} target The element to act on.
527 * @param {Object} options Additional event options (use DOM standard names).
531 mouseout : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
532 this.fireMouseEvent(target, "mouseout", options);
536 * Simulates a mouseover event on a particular element. Use "relatedTarget"
537 * on the options object to specify where the mouse moved from.
538 * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
539 * fromElement is assigned in its place. IE doesn't allow fromElement to be
540 * be assigned, so relatedTarget is assigned in its place. Both of these
541 * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
543 * @param {HTMLElement} target The element to act on.
544 * @param {Object} options Additional event options (use DOM standard names).
548 mouseover : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
549 this.fireMouseEvent(target, "mouseover", options);
553 * Simulates a mouseup on a particular element.
554 * @param {HTMLElement} target The element to act on.
555 * @param {Object} options Additional event options (use DOM standard names).
559 mouseup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
560 this.fireMouseEvent(target, "mouseup", options);
563 //--------------------------------------------------------------------------
565 //--------------------------------------------------------------------------
568 * Fires an event that normally would be fired by the keyboard (keyup,
569 * keydown, keypress). Make sure to specify either keyCode or charCode as
572 * @param {String} type The type of event ("keyup", "keydown" or "keypress").
573 * @param {HTMLElement} target The target of the event.
574 * @param {Object} options Options for the event. Either keyCode or charCode
576 * @method fireKeyEvent
579 fireKeyEvent : function (type /*:String*/, target /*:HTMLElement*/,
580 options /*:Object*/) /*:Void*/
582 options = options || {};
583 this.simulateKeyEvent(target, type, options.bubbles,
584 options.cancelable, options.view, options.ctrlKey,
585 options.altKey, options.shiftKey, options.metaKey,
586 options.keyCode, options.charCode);
590 * Simulates a keydown event on a particular element.
591 * @param {HTMLElement} target The element to act on.
592 * @param {Object} options Additional event options (use DOM standard names).
596 keydown : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
597 this.fireKeyEvent("keydown", target, options);
601 * Simulates a keypress on a particular element.
602 * @param {HTMLElement} target The element to act on.
603 * @param {Object} options Additional event options (use DOM standard names).
607 keypress : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
608 this.fireKeyEvent("keypress", target, options);
612 * Simulates a keyup event on a particular element.
613 * @param {HTMLElement} target The element to act on.
614 * @param {Object} options Additional event options (use DOM standard names).
618 keyup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
619 this.fireKeyEvent("keyup", target, options);
624 YAHOO.register("event-simulate", YAHOO.util.UserAction, {version: "2.9.0", build: "2800"});