src/cm/media/js/lib/yui/yui_3.0.0b1/build/event-simulate/event-simulate.js
changeset 0 40c8f766c9b8
equal deleted inserted replaced
-1:000000000000 0:40c8f766c9b8
       
     1 /*
       
     2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
       
     3 Code licensed under the BSD License:
       
     4 http://developer.yahoo.net/yui/license.txt
       
     5 version: 3.0.0b1
       
     6 build: 1163
       
     7 */
       
     8 YUI.add('event-simulate', function(Y) {
       
     9 
       
    10 (function() {
       
    11 /**
       
    12  * Synthetic DOM events
       
    13  * @module event-simulate
       
    14  */
       
    15 
       
    16 //shortcuts
       
    17 var L   = Y.Lang,
       
    18     array       = Y.Array,
       
    19     isFunction  = L.isFunction,
       
    20     isString    = L.isString,
       
    21     isBoolean   = L.isBoolean,
       
    22     isObject    = L.isObject,
       
    23     isNumber    = L.isNumber,
       
    24     doc         = Y.config.doc,
       
    25     
       
    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     },
       
    36     
       
    37     //key events supported
       
    38     keyEvents   = {
       
    39         keydown:    1,
       
    40         keyup:      1,
       
    41         keypress:   1
       
    42     };
       
    43 
       
    44 /*
       
    45  * Note: Intentionally not for YUIDoc generation.
       
    46  * Simulates a key event using the given event information to populate
       
    47  * the generated event object. This method does browser-equalizing
       
    48  * calculations to account for differences in the DOM and IE event models
       
    49  * as well as different browser quirks. Note: keydown causes Safari 2.x to
       
    50  * crash.
       
    51  * @method simulateKeyEvent
       
    52  * @private
       
    53  * @static
       
    54  * @param {HTMLElement} target The target of the given event.
       
    55  * @param {String} type The type of event to fire. This can be any one of
       
    56  *      the following: keyup, keydown, and keypress.
       
    57  * @param {Boolean} bubbles (Optional) Indicates if the event can be
       
    58  *      bubbled up. DOM Level 3 specifies that all key events bubble by
       
    59  *      default. The default is true.
       
    60  * @param {Boolean} cancelable (Optional) Indicates if the event can be
       
    61  *      canceled using preventDefault(). DOM Level 3 specifies that all
       
    62  *      key events can be cancelled. The default 
       
    63  *      is true.
       
    64  * @param {Window} view (Optional) The view containing the target. This is
       
    65  *      typically the window object. The default is window.
       
    66  * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
       
    67  *      is pressed while the event is firing. The default is false.
       
    68  * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
       
    69  *      is pressed while the event is firing. The default is false.
       
    70  * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
       
    71  *      is pressed while the event is firing. The default is false.
       
    72  * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
       
    73  *      is pressed while the event is firing. The default is false.
       
    74  * @param {int} keyCode (Optional) The code for the key that is in use. 
       
    75  *      The default is 0.
       
    76  * @param {int} charCode (Optional) The Unicode code for the character
       
    77  *      associated with the key being used. The default is 0.
       
    78  */
       
    79 function simulateKeyEvent(target /*:HTMLElement*/, type /*:String*/, 
       
    80                              bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
       
    81                              view /*:Window*/,
       
    82                              ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
       
    83                              shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
       
    84                              keyCode /*:int*/,        charCode /*:int*/) /*:Void*/                             
       
    85 {
       
    86     //check target    
       
    87     if (!target){
       
    88         Y.error("simulateKeyEvent(): Invalid target.");
       
    89     }
       
    90     
       
    91     //check event type
       
    92     if (isString(type)){
       
    93         type = type.toLowerCase();
       
    94         switch(type){
       
    95             case "textevent": //DOM Level 3
       
    96                 type = "keypress";
       
    97                 break;
       
    98             case "keyup":
       
    99             case "keydown":
       
   100             case "keypress":
       
   101                 break;
       
   102             default:
       
   103                 Y.error("simulateKeyEvent(): Event type '" + type + "' not supported.");
       
   104         }
       
   105     } else {
       
   106         Y.error("simulateKeyEvent(): Event type must be a string.");
       
   107     }
       
   108     
       
   109     //setup default values
       
   110     if (!isBoolean(bubbles)){
       
   111         bubbles = true; //all key events bubble
       
   112     }
       
   113     if (!isBoolean(cancelable)){
       
   114         cancelable = true; //all key events can be cancelled
       
   115     }
       
   116     if (!isObject(view)){
       
   117         view = window; //view is typically window
       
   118     }
       
   119     if (!isBoolean(ctrlKey)){
       
   120         ctrlKey = false;
       
   121     }
       
   122     if (!isBoolean(altKey)){
       
   123         altKey = false;
       
   124     }
       
   125     if (!isBoolean(shiftKey)){
       
   126         shiftKey = false;
       
   127     }
       
   128     if (!isBoolean(metaKey)){
       
   129         metaKey = false;
       
   130     }
       
   131     if (!isNumber(keyCode)){
       
   132         keyCode = 0;
       
   133     }
       
   134     if (!isNumber(charCode)){
       
   135         charCode = 0; 
       
   136     }
       
   137 
       
   138     //try to create a mouse event
       
   139     var customEvent /*:MouseEvent*/ = null;
       
   140         
       
   141     //check for DOM-compliant browsers first
       
   142     if (isFunction(doc.createEvent)){
       
   143     
       
   144         try {
       
   145             
       
   146             //try to create key event
       
   147             customEvent = doc.createEvent("KeyEvents");
       
   148             
       
   149             /*
       
   150              * Interesting problem: Firefox implemented a non-standard
       
   151              * version of initKeyEvent() based on DOM Level 2 specs.
       
   152              * Key event was removed from DOM Level 2 and re-introduced
       
   153              * in DOM Level 3 with a different interface. Firefox is the
       
   154              * only browser with any implementation of Key Events, so for
       
   155              * now, assume it's Firefox if the above line doesn't error.
       
   156              */
       
   157             // @TODO: Decipher between Firefox's implementation and a correct one.
       
   158             customEvent.initKeyEvent(type, bubbles, cancelable, view, ctrlKey,
       
   159                 altKey, shiftKey, metaKey, keyCode, charCode);       
       
   160             
       
   161         } catch (ex /*:Error*/){
       
   162 
       
   163             /*
       
   164              * If it got here, that means key events aren't officially supported. 
       
   165              * Safari/WebKit is a real problem now. WebKit 522 won't let you
       
   166              * set keyCode, charCode, or other properties if you use a
       
   167              * UIEvent, so we first must try to create a generic event. The
       
   168              * fun part is that this will throw an error on Safari 2.x. The
       
   169              * end result is that we need another try...catch statement just to
       
   170              * deal with this mess.
       
   171              */
       
   172             try {
       
   173 
       
   174                 //try to create generic event - will fail in Safari 2.x
       
   175                 customEvent = doc.createEvent("Events");
       
   176 
       
   177             } catch (uierror /*:Error*/){
       
   178 
       
   179                 //the above failed, so create a UIEvent for Safari 2.x
       
   180                 customEvent = doc.createEvent("UIEvents");
       
   181 
       
   182             } finally {
       
   183 
       
   184                 customEvent.initEvent(type, bubbles, cancelable);
       
   185 
       
   186                 //initialize
       
   187                 customEvent.view = view;
       
   188                 customEvent.altKey = altKey;
       
   189                 customEvent.ctrlKey = ctrlKey;
       
   190                 customEvent.shiftKey = shiftKey;
       
   191                 customEvent.metaKey = metaKey;
       
   192                 customEvent.keyCode = keyCode;
       
   193                 customEvent.charCode = charCode;
       
   194       
       
   195             }          
       
   196          
       
   197         }
       
   198         
       
   199         //fire the event
       
   200         target.dispatchEvent(customEvent);
       
   201 
       
   202     } else if (isObject(doc.createEventObject)){ //IE
       
   203     
       
   204         //create an IE event object
       
   205         customEvent = doc.createEventObject();
       
   206         
       
   207         //assign available properties
       
   208         customEvent.bubbles = bubbles;
       
   209         customEvent.cancelable = cancelable;
       
   210         customEvent.view = view;
       
   211         customEvent.ctrlKey = ctrlKey;
       
   212         customEvent.altKey = altKey;
       
   213         customEvent.shiftKey = shiftKey;
       
   214         customEvent.metaKey = metaKey;
       
   215         
       
   216         /*
       
   217          * IE doesn't support charCode explicitly. CharCode should
       
   218          * take precedence over any keyCode value for accurate
       
   219          * representation.
       
   220          */
       
   221         customEvent.keyCode = (charCode > 0) ? charCode : keyCode;
       
   222         
       
   223         //fire the event
       
   224         target.fireEvent("on" + type, customEvent);  
       
   225                 
       
   226     } else {
       
   227         Y.error("simulateKeyEvent(): No event simulation framework present.");
       
   228     }
       
   229 }
       
   230 
       
   231 /*
       
   232  * Note: Intentionally not for YUIDoc generation.
       
   233  * Simulates a mouse event using the given event information to populate
       
   234  * the generated event object. This method does browser-equalizing
       
   235  * calculations to account for differences in the DOM and IE event models
       
   236  * as well as different browser quirks.
       
   237  * @method simulateMouseEvent
       
   238  * @private
       
   239  * @static
       
   240  * @param {HTMLElement} target The target of the given event.
       
   241  * @param {String} type The type of event to fire. This can be any one of
       
   242  *      the following: click, dblclick, mousedown, mouseup, mouseout,
       
   243  *      mouseover, and mousemove.
       
   244  * @param {Boolean} bubbles (Optional) Indicates if the event can be
       
   245  *      bubbled up. DOM Level 2 specifies that all mouse events bubble by
       
   246  *      default. The default is true.
       
   247  * @param {Boolean} cancelable (Optional) Indicates if the event can be
       
   248  *      canceled using preventDefault(). DOM Level 2 specifies that all
       
   249  *      mouse events except mousemove can be cancelled. The default 
       
   250  *      is true for all events except mousemove, for which the default 
       
   251  *      is false.
       
   252  * @param {Window} view (Optional) The view containing the target. This is
       
   253  *      typically the window object. The default is window.
       
   254  * @param {int} detail (Optional) The number of times the mouse button has
       
   255  *      been used. The default value is 1.
       
   256  * @param {int} screenX (Optional) The x-coordinate on the screen at which
       
   257  *      point the event occured. The default is 0.
       
   258  * @param {int} screenY (Optional) The y-coordinate on the screen at which
       
   259  *      point the event occured. The default is 0.
       
   260  * @param {int} clientX (Optional) The x-coordinate on the client at which
       
   261  *      point the event occured. The default is 0.
       
   262  * @param {int} clientY (Optional) The y-coordinate on the client at which
       
   263  *      point the event occured. The default is 0.
       
   264  * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
       
   265  *      is pressed while the event is firing. The default is false.
       
   266  * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
       
   267  *      is pressed while the event is firing. The default is false.
       
   268  * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
       
   269  *      is pressed while the event is firing. The default is false.
       
   270  * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
       
   271  *      is pressed while the event is firing. The default is false.
       
   272  * @param {int} button (Optional) The button being pressed while the event
       
   273  *      is executing. The value should be 0 for the primary mouse button
       
   274  *      (typically the left button), 1 for the terciary mouse button
       
   275  *      (typically the middle button), and 2 for the secondary mouse button
       
   276  *      (typically the right button). The default is 0.
       
   277  * @param {HTMLElement} relatedTarget (Optional) For mouseout events,
       
   278  *      this is the element that the mouse has moved to. For mouseover
       
   279  *      events, this is the element that the mouse has moved from. This
       
   280  *      argument is ignored for all other events. The default is null.
       
   281  */
       
   282 function simulateMouseEvent(target /*:HTMLElement*/, type /*:String*/, 
       
   283                                bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
       
   284                                view /*:Window*/,        detail /*:int*/, 
       
   285                                screenX /*:int*/,        screenY /*:int*/, 
       
   286                                clientX /*:int*/,        clientY /*:int*/,       
       
   287                                ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
       
   288                                shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
       
   289                                button /*:int*/,         relatedTarget /*:HTMLElement*/) /*:Void*/
       
   290 {
       
   291     
       
   292     //check target   
       
   293     if (!target){
       
   294         Y.error("simulateMouseEvent(): Invalid target.");
       
   295     }
       
   296     
       
   297     //check event type
       
   298     if (isString(type)){
       
   299         type = type.toLowerCase();
       
   300         
       
   301         //make sure it's a supported mouse event
       
   302         if (!mouseEvents[type]){
       
   303             Y.error("simulateMouseEvent(): Event type '" + type + "' not supported.");
       
   304         }
       
   305     } else {
       
   306         Y.error("simulateMouseEvent(): Event type must be a string.");
       
   307     }
       
   308     
       
   309     //setup default values
       
   310     if (!isBoolean(bubbles)){
       
   311         bubbles = true; //all mouse events bubble
       
   312     }
       
   313     if (!isBoolean(cancelable)){
       
   314         cancelable = (type != "mousemove"); //mousemove is the only one that can't be cancelled
       
   315     }
       
   316     if (!isObject(view)){
       
   317         view = window; //view is typically window
       
   318     }
       
   319     if (!isNumber(detail)){
       
   320         detail = 1;  //number of mouse clicks must be at least one
       
   321     }
       
   322     if (!isNumber(screenX)){
       
   323         screenX = 0; 
       
   324     }
       
   325     if (!isNumber(screenY)){
       
   326         screenY = 0; 
       
   327     }
       
   328     if (!isNumber(clientX)){
       
   329         clientX = 0; 
       
   330     }
       
   331     if (!isNumber(clientY)){
       
   332         clientY = 0; 
       
   333     }
       
   334     if (!isBoolean(ctrlKey)){
       
   335         ctrlKey = false;
       
   336     }
       
   337     if (!isBoolean(altKey)){
       
   338         altKey = false;
       
   339     }
       
   340     if (!isBoolean(shiftKey)){
       
   341         shiftKey = false;
       
   342     }
       
   343     if (!isBoolean(metaKey)){
       
   344         metaKey = false;
       
   345     }
       
   346     if (!isNumber(button)){
       
   347         button = 0; 
       
   348     }
       
   349 
       
   350     //try to create a mouse event
       
   351     var customEvent /*:MouseEvent*/ = null;
       
   352         
       
   353     //check for DOM-compliant browsers first
       
   354     if (isFunction(doc.createEvent)){
       
   355     
       
   356         customEvent = doc.createEvent("MouseEvents");
       
   357     
       
   358         //Safari 2.x (WebKit 418) still doesn't implement initMouseEvent()
       
   359         if (customEvent.initMouseEvent){
       
   360             customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
       
   361                                  screenX, screenY, clientX, clientY, 
       
   362                                  ctrlKey, altKey, shiftKey, metaKey, 
       
   363                                  button, relatedTarget);
       
   364         } else { //Safari
       
   365         
       
   366             //the closest thing available in Safari 2.x is UIEvents
       
   367             customEvent = doc.createEvent("UIEvents");
       
   368             customEvent.initEvent(type, bubbles, cancelable);
       
   369             customEvent.view = view;
       
   370             customEvent.detail = detail;
       
   371             customEvent.screenX = screenX;
       
   372             customEvent.screenY = screenY;
       
   373             customEvent.clientX = clientX;
       
   374             customEvent.clientY = clientY;
       
   375             customEvent.ctrlKey = ctrlKey;
       
   376             customEvent.altKey = altKey;
       
   377             customEvent.metaKey = metaKey;
       
   378             customEvent.shiftKey = shiftKey;
       
   379             customEvent.button = button;
       
   380             customEvent.relatedTarget = relatedTarget;
       
   381         }
       
   382         
       
   383         /*
       
   384          * Check to see if relatedTarget has been assigned. Firefox
       
   385          * versions less than 2.0 don't allow it to be assigned via
       
   386          * initMouseEvent() and the property is readonly after event
       
   387          * creation, so in order to keep YAHOO.util.getRelatedTarget()
       
   388          * working, assign to the IE proprietary toElement property
       
   389          * for mouseout event and fromElement property for mouseover
       
   390          * event.
       
   391          */
       
   392         if (relatedTarget && !customEvent.relatedTarget){
       
   393             if (type == "mouseout"){
       
   394                 customEvent.toElement = relatedTarget;
       
   395             } else if (type == "mouseover"){
       
   396                 customEvent.fromElement = relatedTarget;
       
   397             }
       
   398         }
       
   399         
       
   400         //fire the event
       
   401         target.dispatchEvent(customEvent);
       
   402 
       
   403     } else if (isObject(doc.createEventObject)){ //IE
       
   404     
       
   405         //create an IE event object
       
   406         customEvent = doc.createEventObject();
       
   407         
       
   408         //assign available properties
       
   409         customEvent.bubbles = bubbles;
       
   410         customEvent.cancelable = cancelable;
       
   411         customEvent.view = view;
       
   412         customEvent.detail = detail;
       
   413         customEvent.screenX = screenX;
       
   414         customEvent.screenY = screenY;
       
   415         customEvent.clientX = clientX;
       
   416         customEvent.clientY = clientY;
       
   417         customEvent.ctrlKey = ctrlKey;
       
   418         customEvent.altKey = altKey;
       
   419         customEvent.metaKey = metaKey;
       
   420         customEvent.shiftKey = shiftKey;
       
   421 
       
   422         //fix button property for IE's wacky implementation
       
   423         switch(button){
       
   424             case 0:
       
   425                 customEvent.button = 1;
       
   426                 break;
       
   427             case 1:
       
   428                 customEvent.button = 4;
       
   429                 break;
       
   430             case 2:
       
   431                 //leave as is
       
   432                 break;
       
   433             default:
       
   434                 customEvent.button = 0;                    
       
   435         }    
       
   436 
       
   437         /*
       
   438          * Have to use relatedTarget because IE won't allow assignment
       
   439          * to toElement or fromElement on generic events. This keeps
       
   440          * YAHOO.util.customEvent.getRelatedTarget() functional.
       
   441          */
       
   442         customEvent.relatedTarget = relatedTarget;
       
   443         
       
   444         //fire the event
       
   445         target.fireEvent("on" + type, customEvent);
       
   446                 
       
   447     } else {
       
   448         Y.error("simulateMouseEvent(): No event simulation framework present.");
       
   449     }
       
   450 }
       
   451 
       
   452 
       
   453 /**
       
   454  * Simulates the event with the given name on a target.
       
   455  * @param {HTMLElement} target The DOM element that's the target of the event.
       
   456  * @param {String} type The type of event to simulate (i.e., "click").
       
   457  * @param {Object} options (Optional) Extra options to copy onto the event object.
       
   458  * @return {void}
       
   459  * @method simulate
       
   460  * @static
       
   461  */
       
   462 Y.Event.simulate = function(target, type, options){
       
   463 
       
   464     options = options || {};
       
   465     
       
   466     if (mouseEvents[type]){
       
   467         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);        
       
   472     } else if (keyEvents[type]){
       
   473         simulateKeyEvent(target, type, options.bubbles,
       
   474             options.cancelable, options.view, options.ctrlKey,
       
   475             options.altKey, options.shiftKey, options.metaKey, 
       
   476             options.keyCode, options.charCode);     
       
   477     } else {
       
   478         Y.error("simulate(): Event '" + type + "' can't be simulated.");
       
   479     }
       
   480 };
       
   481 
       
   482 /*
       
   483  * @TODO: focus(), blur(), submit()
       
   484  */
       
   485 
       
   486 })();
       
   487 
       
   488 
       
   489 
       
   490 }, '3.0.0b1' );