NOBUG: Fixed file access permissions
[moodle.git] / lib / yuilib / 3.13.0 / event-simulate / event-simulate-debug.js
blobed99da5223f72ee0cbd5a33f12d90d2a54be931f
1 /*
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/
6 */
8 YUI.add('event-simulate', function (Y, NAME) {
10 (function() {
11 /**
12  * Simulate user interaction by generating native DOM events.
13  *
14  * @module event-simulate
15  * @requires event
16  */
18 //shortcuts
19 var L   = Y.Lang,
20     isFunction  = L.isFunction,
21     isString    = L.isString,
22     isBoolean   = L.isBoolean,
23     isObject    = L.isObject,
24     isNumber    = L.isNumber,
26     //mouse events supported
27     mouseEvents = {
28         click:      1,
29         dblclick:   1,
30         mouseover:  1,
31         mouseout:   1,
32         mousedown:  1,
33         mouseup:    1,
34         mousemove:  1,
35         contextmenu:1
36     },
38     msPointerEvents = {
39         MSPointerOver:  1,
40         MSPointerOut:   1,
41         MSPointerDown:  1,
42         MSPointerUp:    1,
43         MSPointerMove:  1
44     },
46     //key events supported
47     keyEvents   = {
48         keydown:    1,
49         keyup:      1,
50         keypress:   1
51     },
53     //HTML events supported
54     uiEvents  = {
55         submit:     1,
56         blur:       1,
57         change:     1,
58         focus:      1,
59         resize:     1,
60         scroll:     1,
61         select:     1
62     },
64     //events that bubble by default
65     bubbleEvents = {
66         scroll:     1,
67         resize:     1,
68         reset:      1,
69         submit:     1,
70         change:     1,
71         select:     1,
72         error:      1,
73         abort:      1
74     },
76     //touch events supported
77     touchEvents = {
78         touchstart: 1,
79         touchmove: 1,
80         touchend: 1,
81         touchcancel: 1
82     },
84     gestureEvents = {
85         gesturestart: 1,
86         gesturechange: 1,
87         gestureend: 1
88     };
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
101  * crash.
102  * @method simulateKeyEvent
103  * @private
104  * @static
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
114  *      is true.
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.
126  *      The default is 0.
127  * @param {int} charCode (Optional) The Unicode code for the character
128  *      associated with the key being used. The default is 0.
129  */
130 function simulateKeyEvent(target /*:HTMLElement*/, type /*:String*/,
131                              bubbles /*:Boolean*/,  cancelable /*:Boolean*/,
132                              view /*:Window*/,
133                              ctrlKey /*:Boolean*/,    altKey /*:Boolean*/,
134                              shiftKey /*:Boolean*/,   metaKey /*:Boolean*/,
135                              keyCode /*:int*/,        charCode /*:int*/) /*:Void*/
137     //check target
138     if (!target){
139         Y.error("simulateKeyEvent(): Invalid target.");
140     }
142     //check event type
143     if (isString(type)){
144         type = type.toLowerCase();
145         switch(type){
146             case "textevent": //DOM Level 3
147                 type = "keypress";
148                 break;
149             case "keyup":
150             case "keydown":
151             case "keypress":
152                 break;
153             default:
154                 Y.error("simulateKeyEvent(): Event type '" + type + "' not supported.");
155         }
156     } else {
157         Y.error("simulateKeyEvent(): Event type must be a string.");
158     }
160     //setup default values
161     if (!isBoolean(bubbles)){
162         bubbles = true; //all key events bubble
163     }
164     if (!isBoolean(cancelable)){
165         cancelable = true; //all key events can be cancelled
166     }
167     if (!isObject(view)){
168         view = Y.config.win; //view is typically window
169     }
170     if (!isBoolean(ctrlKey)){
171         ctrlKey = false;
172     }
173     if (!isBoolean(altKey)){
174         altKey = false;
175     }
176     if (!isBoolean(shiftKey)){
177         shiftKey = false;
178     }
179     if (!isBoolean(metaKey)){
180         metaKey = false;
181     }
182     if (!isNumber(keyCode)){
183         keyCode = 0;
184     }
185     if (!isNumber(charCode)){
186         charCode = 0;
187     }
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)){
195         try {
197             //try to create key event
198             customEvent = Y.config.doc.createEvent("KeyEvents");
200             /*
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.
207              */
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*/){
214             /*
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.
222              */
223             try {
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");
233             } finally {
235                 customEvent.initEvent(type, bubbles, cancelable);
237                 //initialize
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;
246             }
248         }
250         //fire the event
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;
267         /*
268          * IE doesn't support charCode explicitly. CharCode should
269          * take precedence over any keyCode value for accurate
270          * representation.
271          */
272         customEvent.keyCode = (charCode > 0) ? charCode : keyCode;
274         //fire the event
275         target.fireEvent("on" + type, customEvent);
277     } else {
278         Y.error("simulateKeyEvent(): No event simulation framework present.");
279     }
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
289  * @private
290  * @static
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
302  *      is false.
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.
332  */
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*/
342     //check target
343     if (!target){
344         Y.error("simulateMouseEvent(): Invalid target.");
345     }
348     if (isString(type)){
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.");
353         }
354     }
355     else {
356         Y.error("simulateMouseEvent(): Event type must be a string.");
357     }
359     //setup default values
360     if (!isBoolean(bubbles)){
361         bubbles = true; //all mouse events bubble
362     }
363     if (!isBoolean(cancelable)){
364         cancelable = (type !== "mousemove"); //mousemove is the only one that can't be cancelled
365     }
366     if (!isObject(view)){
367         view = Y.config.win; //view is typically window
368     }
369     if (!isNumber(detail)){
370         detail = 1;  //number of mouse clicks must be at least one
371     }
372     if (!isNumber(screenX)){
373         screenX = 0;
374     }
375     if (!isNumber(screenY)){
376         screenY = 0;
377     }
378     if (!isNumber(clientX)){
379         clientX = 0;
380     }
381     if (!isNumber(clientY)){
382         clientY = 0;
383     }
384     if (!isBoolean(ctrlKey)){
385         ctrlKey = false;
386     }
387     if (!isBoolean(altKey)){
388         altKey = false;
389     }
390     if (!isBoolean(shiftKey)){
391         shiftKey = false;
392     }
393     if (!isBoolean(metaKey)){
394         metaKey = false;
395     }
396     if (!isNumber(button)){
397         button = 0;
398     }
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);
416         } else { //Safari
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;
433         }
435         /*
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
442          * event.
443          */
444         if (relatedTarget && !customEvent.relatedTarget){
445             if (type === "mouseout"){
446                 customEvent.toElement = relatedTarget;
447             } else if (type === "mouseover"){
448                 customEvent.fromElement = relatedTarget;
449             }
450         }
452         //fire the event
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
475         switch(button){
476             case 0:
477                 customEvent.button = 1;
478                 break;
479             case 1:
480                 customEvent.button = 4;
481                 break;
482             case 2:
483                 //leave as is
484                 break;
485             default:
486                 customEvent.button = 0;
487         }
489         /*
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.
493          */
494         customEvent.relatedTarget = relatedTarget;
496         //fire the event
497         target.fireEvent("on" + type, customEvent);
499     } else {
500         Y.error("simulateMouseEvent(): No event simulation framework present.");
501     }
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
511  * @private
512  * @static
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
524  *      is false.
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.
529  */
530 function simulateUIEvent(target /*:HTMLElement*/, type /*:String*/,
531                                bubbles /*:Boolean*/,  cancelable /*:Boolean*/,
532                                view /*:Window*/,        detail /*:int*/) /*:Void*/
535     //check target
536     if (!target){
537         Y.error("simulateUIEvent(): Invalid target.");
538     }
540     //check event type
541     if (isString(type)){
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.");
547         }
548     } else {
549         Y.error("simulateUIEvent(): Event type must be a string.");
550     }
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
559     }
560     if (!isBoolean(cancelable)){
561         cancelable = (type === "submit"); //submit is the only one that can be cancelled
562     }
563     if (!isObject(view)){
564         view = Y.config.win; //view is typically window
565     }
566     if (!isNumber(detail)){
567         detail = 1;  //usually not used but defaulted to this
568     }
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);
577         //fire the event
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;
591         //fire the event
592         target.fireEvent("on" + type, customEvent);
594     } else {
595         Y.error("simulateUIEvent(): No event simulation framework present.");
596     }
600  * (iOS only) This is for creating native DOM gesture events which only iOS
601  * v2.0+ is supporting.
603  * @method simulateGestureEvent
604  * @private
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
615  *      is false.
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.
642  */
643 function simulateGestureEvent(target, type,
644     bubbles,            // boolean
645     cancelable,         // boolean
646     view,               // DOMWindow
647     detail,             // long
648     screenX, screenY,   // long
649     clientX, clientY,   // long
650     ctrlKey, altKey, shiftKey, metaKey, // boolean
651     scale,              // float
652     rotation            // float
653 ) {
654     var customEvent;
656     if(!Y.UA.ios || Y.UA.ios<2.0) {
657         Y.error("simulateGestureEvent(): Native gesture DOM eventframe is not available in this platform.");
658     }
660     // check taget
661     if (!target){
662         Y.error("simulateGestureEvent(): Invalid target.");
663     }
665     //check event type
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.");
672         }
673     } else {
674         Y.error("simulateGestureEvent(): Event type must be a string.");
675     }
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
707  * @private
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
718  *      is false.
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.
751  */
752 function simulateTouchEvent(target, type,
753     bubbles,            // boolean
754     cancelable,         // boolean
755     view,               // DOMWindow
756     detail,             // long
757     screenX, screenY,   // long
758     clientX, clientY,   // long
759     ctrlKey, altKey, shiftKey, metaKey, // boolean
760     touches,            // TouchList
761     targetTouches,      // TouchList
762     changedTouches,     // TouchList
763     scale,              // float
764     rotation            // float
765 ) {
767     var customEvent;
769     // check taget
770     if (!target){
771         Y.error("simulateTouchEvent(): Invalid target.");
772     }
774     //check event type
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.");
781         }
782     } else {
783         Y.error("simulateTouchEvent(): Event type must be a string.");
784     }
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');
792         } else {
793             if(touches.length === 0) {
794                 Y.error('simulateTouchEvent(): No touch object found.');
795             }
796         }
797     } else if(type === 'touchend') {
798         if(!changedTouches instanceof TouchList) {
799             Y.error('simulateTouchEvent(): Invalid touches. It must be a TouchList');
800         } else {
801             if(changedTouches.length === 0) {
802                 Y.error('simulateTouchEvent(): No touch object found.');
803             }
804         }
805     }*/
807     if(type === 'touchstart' || type === 'touchmove') {
808         if(touches.length === 0) {
809             Y.error('simulateTouchEvent(): No touch object in touches');
810         }
811     } else if(type === 'touchend') {
812         if(changedTouches.length === 0) {
813             Y.error('simulateTouchEvent(): No touch object in changedTouches');
814         }
815     }
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
821     }
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)) {
838         if (Y.UA.android) {
839             /*
840                 * Couldn't find android start version that supports touch event.
841                 * Assumed supported(btw APIs broken till icecream sandwitch)
842                 * from the beginning.
843             */
844             if(Y.UA.android < 4.0) {
845                 /*
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.
850                     *
851                     * (Note) Used target for the relatedTarget. Need to verify if
852                     * it has a side effect.
853                 */
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,
858                     0, target);
860                 customEvent.touches = touches;
861                 customEvent.targetTouches = targetTouches;
862                 customEvent.changedTouches = changedTouches;
863             } else {
864                 customEvent = Y.config.doc.createEvent("TouchEvent");
866                 // Andoroid isn't compliant W3C initTouchEvent method signature.
867                 customEvent.initTouchEvent(touches, targetTouches, changedTouches,
868                     type, view,
869                     screenX, screenY, clientX, clientY,
870                     ctrlKey, altKey, shiftKey, metaKey);
871             }
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,
881                     scale, rotation);
882             } else {
883                 Y.error('simulateTouchEvent(): No touch event simulation framework present for iOS, '+Y.UA.ios+'.');
884             }
885         } else {
886             Y.error('simulateTouchEvent(): Not supported agent yet, '+Y.UA.userAgent);
887         }
889         //fire the event
890         target.dispatchEvent(customEvent);
891     //} else if (Y.Lang.isObject(doc.createEventObject)){ // Windows Mobile/IE, support later
892     } else {
893         Y.error('simulateTouchEvent(): No event simulation framework present.');
894     }
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.
904  * @return {void}
905  * @for Event
906  * @method simulate
907  * @static
908  */
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);
937         } else {
938             Y.error("simulate(): Event '" + type + "' can't be simulated. Use gesture-simulate module instead.");
939         }
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);
949     // anything else
950     } else {
951         Y.error("simulate(): Event '" + type + "' can't be simulated.");
952     }
956 })();
960 }, '3.13.0', {"requires": ["event-base"]});