2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
8 YUI.add('event-simulate', function (Y, NAME) {
12 * Simulate user interaction by generating native DOM events.
14 * @module event-simulate
20 isFunction = L.isFunction,
21 isString = L.isString,
22 isBoolean = L.isBoolean,
23 isObject = L.isObject,
24 isNumber = L.isNumber,
26 //mouse events supported
46 //key events supported
53 //HTML events supported
64 //events that bubble by default
76 //touch events supported
90 //all key, mouse and touch events bubble
91 Y.mix(bubbleEvents, mouseEvents);
92 Y.mix(bubbleEvents, keyEvents);
93 Y.mix(bubbleEvents, touchEvents);
96 * Note: Intentionally not for YUIDoc generation.
97 * Simulates a key event using the given event information to populate
98 * the generated event object. This method does browser-equalizing
99 * calculations to account for differences in the DOM and IE event models
100 * as well as different browser quirks. Note: keydown causes Safari 2.x to
102 * @method simulateKeyEvent
105 * @param {HTMLElement} target The target of the given event.
106 * @param {String} type The type of event to fire. This can be any one of
107 * the following: keyup, keydown, and keypress.
108 * @param {Boolean} bubbles (Optional) Indicates if the event can be
109 * bubbled up. DOM Level 3 specifies that all key events bubble by
110 * default. The default is true.
111 * @param {Boolean} cancelable (Optional) Indicates if the event can be
112 * canceled using preventDefault(). DOM Level 3 specifies that all
113 * key events can be cancelled. The default
115 * @param {Window} view (Optional) The view containing the target. This is
116 * typically the window object. The default is window.
117 * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
118 * is pressed while the event is firing. The default is false.
119 * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
120 * is pressed while the event is firing. The default is false.
121 * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
122 * is pressed while the event is firing. The default is false.
123 * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
124 * is pressed while the event is firing. The default is false.
125 * @param {int} keyCode (Optional) The code for the key that is in use.
127 * @param {int} charCode (Optional) The Unicode code for the character
128 * associated with the key being used. The default is 0.
130 function simulateKeyEvent(target /*:HTMLElement*/, type /*:String*/,
131 bubbles /*:Boolean*/, cancelable /*:Boolean*/,
133 ctrlKey /*:Boolean*/, altKey /*:Boolean*/,
134 shiftKey /*:Boolean*/, metaKey /*:Boolean*/,
135 keyCode /*:int*/, charCode /*:int*/) /*:Void*/
139 Y.error("simulateKeyEvent(): Invalid target.");
144 type = type.toLowerCase();
146 case "textevent": //DOM Level 3
154 Y.error("simulateKeyEvent(): Event type '" + type + "' not supported.");
157 Y.error("simulateKeyEvent(): Event type must be a string.");
160 //setup default values
161 if (!isBoolean(bubbles)){
162 bubbles = true; //all key events bubble
164 if (!isBoolean(cancelable)){
165 cancelable = true; //all key events can be cancelled
167 if (!isObject(view)){
168 view = Y.config.win; //view is typically window
170 if (!isBoolean(ctrlKey)){
173 if (!isBoolean(altKey)){
176 if (!isBoolean(shiftKey)){
179 if (!isBoolean(metaKey)){
182 if (!isNumber(keyCode)){
185 if (!isNumber(charCode)){
189 //try to create a mouse event
190 var customEvent /*:MouseEvent*/ = null;
192 //check for DOM-compliant browsers first
193 if (isFunction(Y.config.doc.createEvent)){
197 //try to create key event
198 customEvent = Y.config.doc.createEvent("KeyEvents");
201 * Interesting problem: Firefox implemented a non-standard
202 * version of initKeyEvent() based on DOM Level 2 specs.
203 * Key event was removed from DOM Level 2 and re-introduced
204 * in DOM Level 3 with a different interface. Firefox is the
205 * only browser with any implementation of Key Events, so for
206 * now, assume it's Firefox if the above line doesn't error.
208 // @TODO: Decipher between Firefox's implementation and a correct one.
209 customEvent.initKeyEvent(type, bubbles, cancelable, view, ctrlKey,
210 altKey, shiftKey, metaKey, keyCode, charCode);
212 } catch (ex /*:Error*/){
215 * If it got here, that means key events aren't officially supported.
216 * Safari/WebKit is a real problem now. WebKit 522 won't let you
217 * set keyCode, charCode, or other properties if you use a
218 * UIEvent, so we first must try to create a generic event. The
219 * fun part is that this will throw an error on Safari 2.x. The
220 * end result is that we need another try...catch statement just to
221 * deal with this mess.
225 //try to create generic event - will fail in Safari 2.x
226 customEvent = Y.config.doc.createEvent("Events");
228 } catch (uierror /*:Error*/){
230 //the above failed, so create a UIEvent for Safari 2.x
231 customEvent = Y.config.doc.createEvent("UIEvents");
235 customEvent.initEvent(type, bubbles, cancelable);
238 customEvent.view = view;
239 customEvent.altKey = altKey;
240 customEvent.ctrlKey = ctrlKey;
241 customEvent.shiftKey = shiftKey;
242 customEvent.metaKey = metaKey;
243 customEvent.keyCode = keyCode;
244 customEvent.charCode = charCode;
251 target.dispatchEvent(customEvent);
253 } else if (isObject(Y.config.doc.createEventObject)){ //IE
255 //create an IE event object
256 customEvent = Y.config.doc.createEventObject();
258 //assign available properties
259 customEvent.bubbles = bubbles;
260 customEvent.cancelable = cancelable;
261 customEvent.view = view;
262 customEvent.ctrlKey = ctrlKey;
263 customEvent.altKey = altKey;
264 customEvent.shiftKey = shiftKey;
265 customEvent.metaKey = metaKey;
268 * IE doesn't support charCode explicitly. CharCode should
269 * take precedence over any keyCode value for accurate
272 customEvent.keyCode = (charCode > 0) ? charCode : keyCode;
275 target.fireEvent("on" + type, customEvent);
278 Y.error("simulateKeyEvent(): No event simulation framework present.");
283 * Note: Intentionally not for YUIDoc generation.
284 * Simulates a mouse event using the given event information to populate
285 * the generated event object. This method does browser-equalizing
286 * calculations to account for differences in the DOM and IE event models
287 * as well as different browser quirks.
288 * @method simulateMouseEvent
291 * @param {HTMLElement} target The target of the given event.
292 * @param {String} type The type of event to fire. This can be any one of
293 * the following: click, dblclick, mousedown, mouseup, mouseout,
294 * mouseover, and mousemove.
295 * @param {Boolean} bubbles (Optional) Indicates if the event can be
296 * bubbled up. DOM Level 2 specifies that all mouse events bubble by
297 * default. The default is true.
298 * @param {Boolean} cancelable (Optional) Indicates if the event can be
299 * canceled using preventDefault(). DOM Level 2 specifies that all
300 * mouse events except mousemove can be cancelled. The default
301 * is true for all events except mousemove, for which the default
303 * @param {Window} view (Optional) The view containing the target. This is
304 * typically the window object. The default is window.
305 * @param {int} detail (Optional) The number of times the mouse button has
306 * been used. The default value is 1.
307 * @param {int} screenX (Optional) The x-coordinate on the screen at which
308 * point the event occured. The default is 0.
309 * @param {int} screenY (Optional) The y-coordinate on the screen at which
310 * point the event occured. The default is 0.
311 * @param {int} clientX (Optional) The x-coordinate on the client at which
312 * point the event occured. The default is 0.
313 * @param {int} clientY (Optional) The y-coordinate on the client at which
314 * point the event occured. The default is 0.
315 * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
316 * is pressed while the event is firing. The default is false.
317 * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
318 * is pressed while the event is firing. The default is false.
319 * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
320 * is pressed while the event is firing. The default is false.
321 * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
322 * is pressed while the event is firing. The default is false.
323 * @param {int} button (Optional) The button being pressed while the event
324 * is executing. The value should be 0 for the primary mouse button
325 * (typically the left button), 1 for the terciary mouse button
326 * (typically the middle button), and 2 for the secondary mouse button
327 * (typically the right button). The default is 0.
328 * @param {HTMLElement} relatedTarget (Optional) For mouseout events,
329 * this is the element that the mouse has moved to. For mouseover
330 * events, this is the element that the mouse has moved from. This
331 * argument is ignored for all other events. The default is null.
333 function simulateMouseEvent(target /*:HTMLElement*/, type /*:String*/,
334 bubbles /*:Boolean*/, cancelable /*:Boolean*/,
335 view /*:Window*/, detail /*:int*/,
336 screenX /*:int*/, screenY /*:int*/,
337 clientX /*:int*/, clientY /*:int*/,
338 ctrlKey /*:Boolean*/, altKey /*:Boolean*/,
339 shiftKey /*:Boolean*/, metaKey /*:Boolean*/,
340 button /*:int*/, relatedTarget /*:HTMLElement*/) /*:Void*/
344 Y.error("simulateMouseEvent(): Invalid target.");
350 //make sure it's a supported mouse event or an msPointerEvent.
351 if (!mouseEvents[type.toLowerCase()] && !msPointerEvents[type]){
352 Y.error("simulateMouseEvent(): Event type '" + type + "' not supported.");
356 Y.error("simulateMouseEvent(): Event type must be a string.");
359 //setup default values
360 if (!isBoolean(bubbles)){
361 bubbles = true; //all mouse events bubble
363 if (!isBoolean(cancelable)){
364 cancelable = (type !== "mousemove"); //mousemove is the only one that can't be cancelled
366 if (!isObject(view)){
367 view = Y.config.win; //view is typically window
369 if (!isNumber(detail)){
370 detail = 1; //number of mouse clicks must be at least one
372 if (!isNumber(screenX)){
375 if (!isNumber(screenY)){
378 if (!isNumber(clientX)){
381 if (!isNumber(clientY)){
384 if (!isBoolean(ctrlKey)){
387 if (!isBoolean(altKey)){
390 if (!isBoolean(shiftKey)){
393 if (!isBoolean(metaKey)){
396 if (!isNumber(button)){
400 relatedTarget = relatedTarget || null;
402 //try to create a mouse event
403 var customEvent /*:MouseEvent*/ = null;
405 //check for DOM-compliant browsers first
406 if (isFunction(Y.config.doc.createEvent)){
408 customEvent = Y.config.doc.createEvent("MouseEvents");
410 //Safari 2.x (WebKit 418) still doesn't implement initMouseEvent()
411 if (customEvent.initMouseEvent){
412 customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
413 screenX, screenY, clientX, clientY,
414 ctrlKey, altKey, shiftKey, metaKey,
415 button, relatedTarget);
418 //the closest thing available in Safari 2.x is UIEvents
419 customEvent = Y.config.doc.createEvent("UIEvents");
420 customEvent.initEvent(type, bubbles, cancelable);
421 customEvent.view = view;
422 customEvent.detail = detail;
423 customEvent.screenX = screenX;
424 customEvent.screenY = screenY;
425 customEvent.clientX = clientX;
426 customEvent.clientY = clientY;
427 customEvent.ctrlKey = ctrlKey;
428 customEvent.altKey = altKey;
429 customEvent.metaKey = metaKey;
430 customEvent.shiftKey = shiftKey;
431 customEvent.button = button;
432 customEvent.relatedTarget = relatedTarget;
436 * Check to see if relatedTarget has been assigned. Firefox
437 * versions less than 2.0 don't allow it to be assigned via
438 * initMouseEvent() and the property is readonly after event
439 * creation, so in order to keep YAHOO.util.getRelatedTarget()
440 * working, assign to the IE proprietary toElement property
441 * for mouseout event and fromElement property for mouseover
444 if (relatedTarget && !customEvent.relatedTarget){
445 if (type === "mouseout"){
446 customEvent.toElement = relatedTarget;
447 } else if (type === "mouseover"){
448 customEvent.fromElement = relatedTarget;
453 target.dispatchEvent(customEvent);
455 } else if (isObject(Y.config.doc.createEventObject)){ //IE
457 //create an IE event object
458 customEvent = Y.config.doc.createEventObject();
460 //assign available properties
461 customEvent.bubbles = bubbles;
462 customEvent.cancelable = cancelable;
463 customEvent.view = view;
464 customEvent.detail = detail;
465 customEvent.screenX = screenX;
466 customEvent.screenY = screenY;
467 customEvent.clientX = clientX;
468 customEvent.clientY = clientY;
469 customEvent.ctrlKey = ctrlKey;
470 customEvent.altKey = altKey;
471 customEvent.metaKey = metaKey;
472 customEvent.shiftKey = shiftKey;
474 //fix button property for IE's wacky implementation
477 customEvent.button = 1;
480 customEvent.button = 4;
486 customEvent.button = 0;
490 * Have to use relatedTarget because IE won't allow assignment
491 * to toElement or fromElement on generic events. This keeps
492 * YAHOO.util.customEvent.getRelatedTarget() functional.
494 customEvent.relatedTarget = relatedTarget;
497 target.fireEvent("on" + type, customEvent);
500 Y.error("simulateMouseEvent(): No event simulation framework present.");
505 * Note: Intentionally not for YUIDoc generation.
506 * Simulates a UI event using the given event information to populate
507 * the generated event object. This method does browser-equalizing
508 * calculations to account for differences in the DOM and IE event models
509 * as well as different browser quirks.
510 * @method simulateHTMLEvent
513 * @param {HTMLElement} target The target of the given event.
514 * @param {String} type The type of event to fire. This can be any one of
515 * the following: click, dblclick, mousedown, mouseup, mouseout,
516 * mouseover, and mousemove.
517 * @param {Boolean} bubbles (Optional) Indicates if the event can be
518 * bubbled up. DOM Level 2 specifies that all mouse events bubble by
519 * default. The default is true.
520 * @param {Boolean} cancelable (Optional) Indicates if the event can be
521 * canceled using preventDefault(). DOM Level 2 specifies that all
522 * mouse events except mousemove can be cancelled. The default
523 * is true for all events except mousemove, for which the default
525 * @param {Window} view (Optional) The view containing the target. This is
526 * typically the window object. The default is window.
527 * @param {int} detail (Optional) The number of times the mouse button has
528 * been used. The default value is 1.
530 function simulateUIEvent(target /*:HTMLElement*/, type /*:String*/,
531 bubbles /*:Boolean*/, cancelable /*:Boolean*/,
532 view /*:Window*/, detail /*:int*/) /*:Void*/
537 Y.error("simulateUIEvent(): Invalid target.");
542 type = type.toLowerCase();
544 //make sure it's a supported mouse event
545 if (!uiEvents[type]){
546 Y.error("simulateUIEvent(): Event type '" + type + "' not supported.");
549 Y.error("simulateUIEvent(): Event type must be a string.");
552 //try to create a mouse event
553 var customEvent = null;
556 //setup default values
557 if (!isBoolean(bubbles)){
558 bubbles = (type in bubbleEvents); //not all events bubble
560 if (!isBoolean(cancelable)){
561 cancelable = (type === "submit"); //submit is the only one that can be cancelled
563 if (!isObject(view)){
564 view = Y.config.win; //view is typically window
566 if (!isNumber(detail)){
567 detail = 1; //usually not used but defaulted to this
570 //check for DOM-compliant browsers first
571 if (isFunction(Y.config.doc.createEvent)){
573 //just a generic UI Event object is needed
574 customEvent = Y.config.doc.createEvent("UIEvents");
575 customEvent.initUIEvent(type, bubbles, cancelable, view, detail);
578 target.dispatchEvent(customEvent);
580 } else if (isObject(Y.config.doc.createEventObject)){ //IE
582 //create an IE event object
583 customEvent = Y.config.doc.createEventObject();
585 //assign available properties
586 customEvent.bubbles = bubbles;
587 customEvent.cancelable = cancelable;
588 customEvent.view = view;
589 customEvent.detail = detail;
592 target.fireEvent("on" + type, customEvent);
595 Y.error("simulateUIEvent(): No event simulation framework present.");
600 * (iOS only) This is for creating native DOM gesture events which only iOS
601 * v2.0+ is supporting.
603 * @method simulateGestureEvent
605 * @param {HTMLElement} target The target of the given event.
606 * @param {String} type The type of event to fire. This can be any one of
607 * the following: touchstart, touchmove, touchend, touchcancel.
608 * @param {Boolean} bubbles (Optional) Indicates if the event can be
609 * bubbled up. DOM Level 2 specifies that all mouse events bubble by
610 * default. The default is true.
611 * @param {Boolean} cancelable (Optional) Indicates if the event can be
612 * canceled using preventDefault(). DOM Level 2 specifies that all
613 * touch events except touchcancel can be cancelled. The default
614 * is true for all events except touchcancel, for which the default
616 * @param {Window} view (Optional) The view containing the target. This is
617 * typically the window object. The default is window.
618 * @param {int} detail (Optional) Specifies some detail information about
619 * the event depending on the type of event.
620 * @param {int} screenX (Optional) The x-coordinate on the screen at which
621 * point the event occured. The default is 0.
622 * @param {int} screenY (Optional) The y-coordinate on the screen at which
623 * point the event occured. The default is 0.
624 * @param {int} clientX (Optional) The x-coordinate on the client at which
625 * point the event occured. The default is 0.
626 * @param {int} clientY (Optional) The y-coordinate on the client at which
627 * point the event occured. The default is 0.
628 * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
629 * is pressed while the event is firing. The default is false.
630 * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
631 * is pressed while the event is firing. The default is false.
632 * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
633 * is pressed while the event is firing. The default is false.
634 * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
635 * is pressed while the event is firing. The default is false.
636 * @param {float} scale (iOS v2+ only) The distance between two fingers
637 * since the start of an event as a multiplier of the initial distance.
638 * The default value is 1.0.
639 * @param {float} rotation (iOS v2+ only) The delta rotation since the start
640 * of an event, in degrees, where clockwise is positive and
641 * counter-clockwise is negative. The default value is 0.0.
643 function simulateGestureEvent(target, type,
645 cancelable, // boolean
648 screenX, screenY, // long
649 clientX, clientY, // long
650 ctrlKey, altKey, shiftKey, metaKey, // boolean
656 if(!Y.UA.ios || Y.UA.ios<2.0) {
657 Y.error("simulateGestureEvent(): Native gesture DOM eventframe is not available in this platform.");
662 Y.error("simulateGestureEvent(): Invalid target.");
666 if (Y.Lang.isString(type)) {
667 type = type.toLowerCase();
669 //make sure it's a supported touch event
670 if (!gestureEvents[type]){
671 Y.error("simulateTouchEvent(): Event type '" + type + "' not supported.");
674 Y.error("simulateGestureEvent(): Event type must be a string.");
677 // setup default values
678 if (!Y.Lang.isBoolean(bubbles)) { bubbles = true; } // bubble by default
679 if (!Y.Lang.isBoolean(cancelable)) { cancelable = true; }
680 if (!Y.Lang.isObject(view)) { view = Y.config.win; }
681 if (!Y.Lang.isNumber(detail)) { detail = 2; } // usually not used.
682 if (!Y.Lang.isNumber(screenX)) { screenX = 0; }
683 if (!Y.Lang.isNumber(screenY)) { screenY = 0; }
684 if (!Y.Lang.isNumber(clientX)) { clientX = 0; }
685 if (!Y.Lang.isNumber(clientY)) { clientY = 0; }
686 if (!Y.Lang.isBoolean(ctrlKey)) { ctrlKey = false; }
687 if (!Y.Lang.isBoolean(altKey)) { altKey = false; }
688 if (!Y.Lang.isBoolean(shiftKey)){ shiftKey = false; }
689 if (!Y.Lang.isBoolean(metaKey)) { metaKey = false; }
691 if (!Y.Lang.isNumber(scale)){ scale = 1.0; }
692 if (!Y.Lang.isNumber(rotation)){ rotation = 0.0; }
694 customEvent = Y.config.doc.createEvent("GestureEvent");
696 customEvent.initGestureEvent(type, bubbles, cancelable, view, detail,
697 screenX, screenY, clientX, clientY,
698 ctrlKey, altKey, shiftKey, metaKey,
699 target, scale, rotation);
701 target.dispatchEvent(customEvent);
706 * @method simulateTouchEvent
708 * @param {HTMLElement} target The target of the given event.
709 * @param {String} type The type of event to fire. This can be any one of
710 * the following: touchstart, touchmove, touchend, touchcancel.
711 * @param {Boolean} bubbles (Optional) Indicates if the event can be
712 * bubbled up. DOM Level 2 specifies that all mouse events bubble by
713 * default. The default is true.
714 * @param {Boolean} cancelable (Optional) Indicates if the event can be
715 * canceled using preventDefault(). DOM Level 2 specifies that all
716 * touch events except touchcancel can be cancelled. The default
717 * is true for all events except touchcancel, for which the default
719 * @param {Window} view (Optional) The view containing the target. This is
720 * typically the window object. The default is window.
721 * @param {int} detail (Optional) Specifies some detail information about
722 * the event depending on the type of event.
723 * @param {int} screenX (Optional) The x-coordinate on the screen at which
724 * point the event occured. The default is 0.
725 * @param {int} screenY (Optional) The y-coordinate on the screen at which
726 * point the event occured. The default is 0.
727 * @param {int} clientX (Optional) The x-coordinate on the client at which
728 * point the event occured. The default is 0.
729 * @param {int} clientY (Optional) The y-coordinate on the client at which
730 * point the event occured. The default is 0.
731 * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
732 * is pressed while the event is firing. The default is false.
733 * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
734 * is pressed while the event is firing. The default is false.
735 * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
736 * is pressed while the event is firing. The default is false.
737 * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
738 * is pressed while the event is firing. The default is false.
739 * @param {TouchList} touches A collection of Touch objects representing
740 * all touches associated with this event.
741 * @param {TouchList} targetTouches A collection of Touch objects
742 * representing all touches associated with this target.
743 * @param {TouchList} changedTouches A collection of Touch objects
744 * representing all touches that changed in this event.
745 * @param {float} scale (iOS v2+ only) The distance between two fingers
746 * since the start of an event as a multiplier of the initial distance.
747 * The default value is 1.0.
748 * @param {float} rotation (iOS v2+ only) The delta rotation since the start
749 * of an event, in degrees, where clockwise is positive and
750 * counter-clockwise is negative. The default value is 0.0.
752 function simulateTouchEvent(target, type,
754 cancelable, // boolean
757 screenX, screenY, // long
758 clientX, clientY, // long
759 ctrlKey, altKey, shiftKey, metaKey, // boolean
760 touches, // TouchList
761 targetTouches, // TouchList
762 changedTouches, // TouchList
771 Y.error("simulateTouchEvent(): Invalid target.");
775 if (Y.Lang.isString(type)) {
776 type = type.toLowerCase();
778 //make sure it's a supported touch event
779 if (!touchEvents[type]){
780 Y.error("simulateTouchEvent(): Event type '" + type + "' not supported.");
783 Y.error("simulateTouchEvent(): Event type must be a string.");
786 // note that the caller is responsible to pass appropriate touch objects.
787 // check touch objects
788 // Android(even 4.0) doesn't define TouchList yet
789 /*if(type === 'touchstart' || type === 'touchmove') {
790 if(!touches instanceof TouchList) {
791 Y.error('simulateTouchEvent(): Invalid touches. It must be a TouchList');
793 if(touches.length === 0) {
794 Y.error('simulateTouchEvent(): No touch object found.');
797 } else if(type === 'touchend') {
798 if(!changedTouches instanceof TouchList) {
799 Y.error('simulateTouchEvent(): Invalid touches. It must be a TouchList');
801 if(changedTouches.length === 0) {
802 Y.error('simulateTouchEvent(): No touch object found.');
807 if(type === 'touchstart' || type === 'touchmove') {
808 if(touches.length === 0) {
809 Y.error('simulateTouchEvent(): No touch object in touches');
811 } else if(type === 'touchend') {
812 if(changedTouches.length === 0) {
813 Y.error('simulateTouchEvent(): No touch object in changedTouches');
817 // setup default values
818 if (!Y.Lang.isBoolean(bubbles)) { bubbles = true; } // bubble by default.
819 if (!Y.Lang.isBoolean(cancelable)) {
820 cancelable = (type !== "touchcancel"); // touchcancel is not cancelled
822 if (!Y.Lang.isObject(view)) { view = Y.config.win; }
823 if (!Y.Lang.isNumber(detail)) { detail = 1; } // usually not used. defaulted to # of touch objects.
824 if (!Y.Lang.isNumber(screenX)) { screenX = 0; }
825 if (!Y.Lang.isNumber(screenY)) { screenY = 0; }
826 if (!Y.Lang.isNumber(clientX)) { clientX = 0; }
827 if (!Y.Lang.isNumber(clientY)) { clientY = 0; }
828 if (!Y.Lang.isBoolean(ctrlKey)) { ctrlKey = false; }
829 if (!Y.Lang.isBoolean(altKey)) { altKey = false; }
830 if (!Y.Lang.isBoolean(shiftKey)){ shiftKey = false; }
831 if (!Y.Lang.isBoolean(metaKey)) { metaKey = false; }
832 if (!Y.Lang.isNumber(scale)) { scale = 1.0; }
833 if (!Y.Lang.isNumber(rotation)) { rotation = 0.0; }
836 //check for DOM-compliant browsers first
837 if (Y.Lang.isFunction(Y.config.doc.createEvent)) {
840 * Couldn't find android start version that supports touch event.
841 * Assumed supported(btw APIs broken till icecream sandwitch)
842 * from the beginning.
844 if(Y.UA.android < 4.0) {
846 * Touch APIs are broken in androids older than 4.0. We will use
847 * simulated touch apis for these versions.
848 * App developer still can listen for touch events. This events
849 * will be dispatched with touch event types.
851 * (Note) Used target for the relatedTarget. Need to verify if
852 * it has a side effect.
854 customEvent = Y.config.doc.createEvent("MouseEvents");
855 customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
856 screenX, screenY, clientX, clientY,
857 ctrlKey, altKey, shiftKey, metaKey,
860 customEvent.touches = touches;
861 customEvent.targetTouches = targetTouches;
862 customEvent.changedTouches = changedTouches;
864 customEvent = Y.config.doc.createEvent("TouchEvent");
866 // Andoroid isn't compliant W3C initTouchEvent method signature.
867 customEvent.initTouchEvent(touches, targetTouches, changedTouches,
869 screenX, screenY, clientX, clientY,
870 ctrlKey, altKey, shiftKey, metaKey);
872 } else if (Y.UA.ios) {
873 if(Y.UA.ios >= 2.0) {
874 customEvent = Y.config.doc.createEvent("TouchEvent");
876 // Available iOS 2.0 and later
877 customEvent.initTouchEvent(type, bubbles, cancelable, view, detail,
878 screenX, screenY, clientX, clientY,
879 ctrlKey, altKey, shiftKey, metaKey,
880 touches, targetTouches, changedTouches,
883 Y.error('simulateTouchEvent(): No touch event simulation framework present for iOS, '+Y.UA.ios+'.');
886 Y.error('simulateTouchEvent(): Not supported agent yet, '+Y.UA.userAgent);
890 target.dispatchEvent(customEvent);
891 //} else if (Y.Lang.isObject(doc.createEventObject)){ // Windows Mobile/IE, support later
893 Y.error('simulateTouchEvent(): No event simulation framework present.');
898 * Simulates the event or gesture with the given name on a target.
899 * @param {HTMLElement} target The DOM element that's the target of the event.
900 * @param {String} type The type of event or name of the supported gesture to simulate
901 * (i.e., "click", "doubletap", "flick").
902 * @param {Object} options (Optional) Extra options to copy onto the event object.
903 * For gestures, options are used to refine the gesture behavior.
909 Y.Event.simulate = function(target, type, options){
911 options = options || {};
913 if (mouseEvents[type] || msPointerEvents[type]){
914 simulateMouseEvent(target, type, options.bubbles,
915 options.cancelable, options.view, options.detail, options.screenX,
916 options.screenY, options.clientX, options.clientY, options.ctrlKey,
917 options.altKey, options.shiftKey, options.metaKey, options.button,
918 options.relatedTarget);
919 } else if (keyEvents[type]){
920 simulateKeyEvent(target, type, options.bubbles,
921 options.cancelable, options.view, options.ctrlKey,
922 options.altKey, options.shiftKey, options.metaKey,
923 options.keyCode, options.charCode);
924 } else if (uiEvents[type]){
925 simulateUIEvent(target, type, options.bubbles,
926 options.cancelable, options.view, options.detail);
928 // touch low-level event simulation
929 } else if (touchEvents[type]) {
930 if((Y.config.win && ("ontouchstart" in Y.config.win)) && !(Y.UA.phantomjs) && !(Y.UA.chrome && Y.UA.chrome < 6)) {
931 simulateTouchEvent(target, type,
932 options.bubbles, options.cancelable, options.view, options.detail,
933 options.screenX, options.screenY, options.clientX, options.clientY,
934 options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
935 options.touches, options.targetTouches, options.changedTouches,
936 options.scale, options.rotation);
938 Y.error("simulate(): Event '" + type + "' can't be simulated. Use gesture-simulate module instead.");
941 // ios gesture low-level event simulation (iOS v2+ only)
942 } else if(Y.UA.ios && Y.UA.ios >= 2.0 && gestureEvents[type]) {
943 simulateGestureEvent(target, type,
944 options.bubbles, options.cancelable, options.view, options.detail,
945 options.screenX, options.screenY, options.clientX, options.clientY,
946 options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
947 options.scale, options.rotation);
951 Y.error("simulate(): Event '" + type + "' can't be simulated.");
960 }, '3.13.0', {"requires": ["event-base"]});