[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 YUI.add('yui2-event', function(Y) { 2 var YAHOO = Y.YUI2; 3 /* 4 Copyright (c) 2011, Yahoo! Inc. All rights reserved. 5 Code licensed under the BSD License: 6 http://developer.yahoo.com/yui/license.html 7 version: 2.9.0 8 */ 9 10 /** 11 * The CustomEvent class lets you define events for your application 12 * that can be subscribed to by one or more independent component. 13 * 14 * @param {String} type The type of event, which is passed to the callback 15 * when the event fires 16 * @param {Object} context The context the event will fire from. "this" will 17 * refer to this object in the callback. Default value: 18 * the window object. The listener can override this. 19 * @param {boolean} silent pass true to prevent the event from writing to 20 * the debugsystem 21 * @param {int} signature the signature that the custom event subscriber 22 * will receive. YAHOO.util.CustomEvent.LIST or 23 * YAHOO.util.CustomEvent.FLAT. The default is 24 * YAHOO.util.CustomEvent.LIST. 25 * @param fireOnce {boolean} If configured to fire once, the custom event 26 * will only notify subscribers a single time regardless of how many times 27 * the event is fired. In addition, new subscribers will be notified 28 * immediately if the event has already been fired. 29 * @namespace YAHOO.util 30 * @class CustomEvent 31 * @constructor 32 */ 33 YAHOO.util.CustomEvent = function(type, context, silent, signature, fireOnce) { 34 35 /** 36 * The type of event, returned to subscribers when the event fires 37 * @property type 38 * @type string 39 */ 40 this.type = type; 41 42 /** 43 * The context the event will fire from by default. Defaults to the window obj. 44 * @property scope 45 * @type object 46 */ 47 this.scope = context || window; 48 49 /** 50 * By default all custom events are logged in the debug build. Set silent to true 51 * to disable debug output for this event. 52 * @property silent 53 * @type boolean 54 */ 55 this.silent = silent; 56 57 /** 58 * If configured to fire once, the custom event will only notify subscribers 59 * a single time regardless of how many times the event is fired. In addition, 60 * new subscribers will be notified immediately if the event has already been 61 * fired. 62 * @property fireOnce 63 * @type boolean 64 * @default false 65 */ 66 this.fireOnce = fireOnce; 67 68 /** 69 * Indicates whether or not this event has ever been fired. 70 * @property fired 71 * @type boolean 72 * @default false 73 */ 74 this.fired = false; 75 76 /** 77 * For fireOnce events the arguments the event was fired with are stored 78 * so that new subscribers get the proper payload. 79 * @property firedWith 80 * @type Array 81 */ 82 this.firedWith = null; 83 84 /** 85 * Custom events support two styles of arguments provided to the event 86 * subscribers. 87 * <ul> 88 * <li>YAHOO.util.CustomEvent.LIST: 89 * <ul> 90 * <li>param1: event name</li> 91 * <li>param2: array of arguments sent to fire</li> 92 * <li>param3: <optional> a custom object supplied by the subscriber</li> 93 * </ul> 94 * </li> 95 * <li>YAHOO.util.CustomEvent.FLAT 96 * <ul> 97 * <li>param1: the first argument passed to fire. If you need to 98 * pass multiple parameters, use and array or object literal</li> 99 * <li>param2: <optional> a custom object supplied by the subscriber</li> 100 * </ul> 101 * </li> 102 * </ul> 103 * @property signature 104 * @type int 105 */ 106 this.signature = signature || YAHOO.util.CustomEvent.LIST; 107 108 /** 109 * The subscribers to this event 110 * @property subscribers 111 * @type Subscriber[] 112 */ 113 this.subscribers = []; 114 115 if (!this.silent) { 116 } 117 118 var onsubscribeType = "_YUICEOnSubscribe"; 119 120 // Only add subscribe events for events that are not generated by 121 // CustomEvent 122 if (type !== onsubscribeType) { 123 124 /** 125 * Custom events provide a custom event that fires whenever there is 126 * a new subscriber to the event. This provides an opportunity to 127 * handle the case where there is a non-repeating event that has 128 * already fired has a new subscriber. 129 * 130 * @event subscribeEvent 131 * @type YAHOO.util.CustomEvent 132 * @param fn {Function} The function to execute 133 * @param obj <Object> An object to be passed along when the event fires. 134 * Defaults to the custom event. 135 * @param override <boolean|Object> If true, the obj passed in becomes the 136 * execution context of the listener. If an object, that object becomes 137 * the execution context. Defaults to the custom event. 138 */ 139 this.subscribeEvent = 140 new YAHOO.util.CustomEvent(onsubscribeType, this, true); 141 142 } 143 144 145 /** 146 * In order to make it possible to execute the rest of the subscriber 147 * stack when one thows an exception, the subscribers exceptions are 148 * caught. The most recent exception is stored in this property 149 * @property lastError 150 * @type Error 151 */ 152 this.lastError = null; 153 }; 154 155 /** 156 * Subscriber listener sigature constant. The LIST type returns three 157 * parameters: the event type, the array of args passed to fire, and 158 * the optional custom object 159 * @property YAHOO.util.CustomEvent.LIST 160 * @static 161 * @type int 162 */ 163 YAHOO.util.CustomEvent.LIST = 0; 164 165 /** 166 * Subscriber listener sigature constant. The FLAT type returns two 167 * parameters: the first argument passed to fire and the optional 168 * custom object 169 * @property YAHOO.util.CustomEvent.FLAT 170 * @static 171 * @type int 172 */ 173 YAHOO.util.CustomEvent.FLAT = 1; 174 175 YAHOO.util.CustomEvent.prototype = { 176 177 /** 178 * Subscribes the caller to this event 179 * @method subscribe 180 * @param {Function} fn The function to execute 181 * @param {Object} obj An object to be passed along when the event 182 * fires. 183 * @param {boolean|Object} overrideContext If true, the obj passed in 184 * becomes the execution. 185 * context of the listener. If an object, that object becomes the execution 186 * context. 187 */ 188 subscribe: function(fn, obj, overrideContext) { 189 190 if (!fn) { 191 throw new Error("Invalid callback for subscriber to '" + this.type + "'"); 192 } 193 194 if (this.subscribeEvent) { 195 this.subscribeEvent.fire(fn, obj, overrideContext); 196 } 197 198 var s = new YAHOO.util.Subscriber(fn, obj, overrideContext); 199 200 if (this.fireOnce && this.fired) { 201 this.notify(s, this.firedWith); 202 } else { 203 this.subscribers.push(s); 204 } 205 }, 206 207 /** 208 * Unsubscribes subscribers. 209 * @method unsubscribe 210 * @param {Function} fn The subscribed function to remove, if not supplied 211 * all will be removed 212 * @param {Object} obj The custom object passed to subscribe. This is 213 * optional, but if supplied will be used to 214 * disambiguate multiple listeners that are the same 215 * (e.g., you subscribe many object using a function 216 * that lives on the prototype) 217 * @return {boolean} True if the subscriber was found and detached. 218 */ 219 unsubscribe: function(fn, obj) { 220 221 if (!fn) { 222 return this.unsubscribeAll(); 223 } 224 225 var found = false; 226 for (var i=0, len=this.subscribers.length; i<len; ++i) { 227 var s = this.subscribers[i]; 228 if (s && s.contains(fn, obj)) { 229 this._delete(i); 230 found = true; 231 } 232 } 233 234 return found; 235 }, 236 237 /** 238 * Notifies the subscribers. The callback functions will be executed 239 * from the context specified when the event was created, and with the 240 * following parameters: 241 * <ul> 242 * <li>The type of event</li> 243 * <li>All of the arguments fire() was executed with as an array</li> 244 * <li>The custom object (if any) that was passed into the subscribe() 245 * method</li> 246 * </ul> 247 * @method fire 248 * @param {Object*} arguments an arbitrary set of parameters to pass to 249 * the handler. 250 * @return {boolean} false if one of the subscribers returned false, 251 * true otherwise 252 */ 253 fire: function() { 254 255 this.lastError = null; 256 257 var errors = [], 258 len=this.subscribers.length; 259 260 261 var args=[].slice.call(arguments, 0), ret=true, i, rebuild=false; 262 263 if (this.fireOnce) { 264 if (this.fired) { 265 return true; 266 } else { 267 this.firedWith = args; 268 } 269 } 270 271 this.fired = true; 272 273 if (!len && this.silent) { 274 return true; 275 } 276 277 if (!this.silent) { 278 } 279 280 // make a copy of the subscribers so that there are 281 // no index problems if one subscriber removes another. 282 var subs = this.subscribers.slice(); 283 284 for (i=0; i<len; ++i) { 285 var s = subs[i]; 286 if (!s || !s.fn) { 287 rebuild=true; 288 } else { 289 290 ret = this.notify(s, args); 291 292 if (false === ret) { 293 if (!this.silent) { 294 } 295 296 break; 297 } 298 } 299 } 300 301 return (ret !== false); 302 }, 303 304 notify: function(s, args) { 305 306 var ret, param=null, scope = s.getScope(this.scope), 307 throwErrors = YAHOO.util.Event.throwErrors; 308 309 if (!this.silent) { 310 } 311 312 if (this.signature == YAHOO.util.CustomEvent.FLAT) { 313 314 if (args.length > 0) { 315 param = args[0]; 316 } 317 318 try { 319 ret = s.fn.call(scope, param, s.obj); 320 } catch(e) { 321 this.lastError = e; 322 // errors.push(e); 323 if (throwErrors) { 324 throw e; 325 } 326 } 327 } else { 328 try { 329 ret = s.fn.call(scope, this.type, args, s.obj); 330 } catch(ex) { 331 this.lastError = ex; 332 if (throwErrors) { 333 throw ex; 334 } 335 } 336 } 337 338 return ret; 339 }, 340 341 /** 342 * Removes all listeners 343 * @method unsubscribeAll 344 * @return {int} The number of listeners unsubscribed 345 */ 346 unsubscribeAll: function() { 347 var l = this.subscribers.length, i; 348 for (i=l-1; i>-1; i--) { 349 this._delete(i); 350 } 351 352 this.subscribers=[]; 353 354 return l; 355 }, 356 357 /** 358 * @method _delete 359 * @private 360 */ 361 _delete: function(index) { 362 var s = this.subscribers[index]; 363 if (s) { 364 delete s.fn; 365 delete s.obj; 366 } 367 368 // this.subscribers[index]=null; 369 this.subscribers.splice(index, 1); 370 }, 371 372 /** 373 * @method toString 374 */ 375 toString: function() { 376 return "CustomEvent: " + "'" + this.type + "', " + 377 "context: " + this.scope; 378 379 } 380 }; 381 382 ///////////////////////////////////////////////////////////////////// 383 384 /** 385 * Stores the subscriber information to be used when the event fires. 386 * @param {Function} fn The function to execute 387 * @param {Object} obj An object to be passed along when the event fires 388 * @param {boolean} overrideContext If true, the obj passed in becomes the execution 389 * context of the listener 390 * @class Subscriber 391 * @constructor 392 */ 393 YAHOO.util.Subscriber = function(fn, obj, overrideContext) { 394 395 /** 396 * The callback that will be execute when the event fires 397 * @property fn 398 * @type function 399 */ 400 this.fn = fn; 401 402 /** 403 * An optional custom object that will passed to the callback when 404 * the event fires 405 * @property obj 406 * @type object 407 */ 408 this.obj = YAHOO.lang.isUndefined(obj) ? null : obj; 409 410 /** 411 * The default execution context for the event listener is defined when the 412 * event is created (usually the object which contains the event). 413 * By setting overrideContext to true, the execution context becomes the custom 414 * object passed in by the subscriber. If overrideContext is an object, that 415 * object becomes the context. 416 * @property overrideContext 417 * @type boolean|object 418 */ 419 this.overrideContext = overrideContext; 420 421 }; 422 423 /** 424 * Returns the execution context for this listener. If overrideContext was set to true 425 * the custom obj will be the context. If overrideContext is an object, that is the 426 * context, otherwise the default context will be used. 427 * @method getScope 428 * @param {Object} defaultScope the context to use if this listener does not 429 * override it. 430 */ 431 YAHOO.util.Subscriber.prototype.getScope = function(defaultScope) { 432 if (this.overrideContext) { 433 if (this.overrideContext === true) { 434 return this.obj; 435 } else { 436 return this.overrideContext; 437 } 438 } 439 return defaultScope; 440 }; 441 442 /** 443 * Returns true if the fn and obj match this objects properties. 444 * Used by the unsubscribe method to match the right subscriber. 445 * 446 * @method contains 447 * @param {Function} fn the function to execute 448 * @param {Object} obj an object to be passed along when the event fires 449 * @return {boolean} true if the supplied arguments match this 450 * subscriber's signature. 451 */ 452 YAHOO.util.Subscriber.prototype.contains = function(fn, obj) { 453 if (obj) { 454 return (this.fn == fn && this.obj == obj); 455 } else { 456 return (this.fn == fn); 457 } 458 }; 459 460 /** 461 * @method toString 462 */ 463 YAHOO.util.Subscriber.prototype.toString = function() { 464 return "Subscriber { obj: " + this.obj + 465 ", overrideContext: " + (this.overrideContext || "no") + " }"; 466 }; 467 468 /** 469 * The Event Utility provides utilities for managing DOM Events and tools 470 * for building event systems 471 * 472 * @module event 473 * @title Event Utility 474 * @namespace YAHOO.util 475 * @requires yahoo 476 */ 477 478 // The first instance of Event will win if it is loaded more than once. 479 // @TODO this needs to be changed so that only the state data that needs to 480 // be preserved is kept, while methods are overwritten/added as needed. 481 // This means that the module pattern can't be used. 482 if (!YAHOO.util.Event) { 483 484 /** 485 * The event utility provides functions to add and remove event listeners, 486 * event cleansing. It also tries to automatically remove listeners it 487 * registers during the unload event. 488 * 489 * @class Event 490 * @static 491 */ 492 YAHOO.util.Event = function() { 493 494 /** 495 * True after the onload event has fired 496 * @property loadComplete 497 * @type boolean 498 * @static 499 * @private 500 */ 501 var loadComplete = false, 502 503 /** 504 * Cache of wrapped listeners 505 * @property listeners 506 * @type array 507 * @static 508 * @private 509 */ 510 listeners = [], 511 512 513 /** 514 * User-defined unload function that will be fired before all events 515 * are detached 516 * @property unloadListeners 517 * @type array 518 * @static 519 * @private 520 */ 521 unloadListeners = [], 522 523 /** 524 * The number of times to poll after window.onload. This number is 525 * increased if additional late-bound handlers are requested after 526 * the page load. 527 * @property retryCount 528 * @static 529 * @private 530 */ 531 retryCount = 0, 532 533 /** 534 * onAvailable listeners 535 * @property onAvailStack 536 * @static 537 * @private 538 */ 539 onAvailStack = [], 540 541 /** 542 * Counter for auto id generation 543 * @property counter 544 * @static 545 * @private 546 */ 547 counter = 0, 548 549 /** 550 * Normalized keycodes for webkit/safari 551 * @property webkitKeymap 552 * @type {int: int} 553 * @private 554 * @static 555 * @final 556 */ 557 webkitKeymap = { 558 63232: 38, // up 559 63233: 40, // down 560 63234: 37, // left 561 63235: 39, // right 562 63276: 33, // page up 563 63277: 34, // page down 564 25: 9 // SHIFT-TAB (Safari provides a different key code in 565 // this case, even though the shiftKey modifier is set) 566 }, 567 568 isIE = YAHOO.env.ua.ie, 569 570 // String constants used by the addFocusListener and removeFocusListener methods 571 572 FOCUSIN = "focusin", 573 FOCUSOUT = "focusout"; 574 575 return { 576 577 /** 578 * The number of times we should look for elements that are not 579 * in the DOM at the time the event is requested after the document 580 * has been loaded. The default is 500@amp;40 ms, so it will poll 581 * for 20 seconds or until all outstanding handlers are bound 582 * (whichever comes first). 583 * @property POLL_RETRYS 584 * @type int 585 * @static 586 * @final 587 */ 588 POLL_RETRYS: 500, 589 590 /** 591 * The poll interval in milliseconds 592 * @property POLL_INTERVAL 593 * @type int 594 * @static 595 * @final 596 */ 597 POLL_INTERVAL: 40, 598 599 /** 600 * Element to bind, int constant 601 * @property EL 602 * @type int 603 * @static 604 * @final 605 */ 606 EL: 0, 607 608 /** 609 * Type of event, int constant 610 * @property TYPE 611 * @type int 612 * @static 613 * @final 614 */ 615 TYPE: 1, 616 617 /** 618 * Function to execute, int constant 619 * @property FN 620 * @type int 621 * @static 622 * @final 623 */ 624 FN: 2, 625 626 /** 627 * Function wrapped for context correction and cleanup, int constant 628 * @property WFN 629 * @type int 630 * @static 631 * @final 632 */ 633 WFN: 3, 634 635 /** 636 * Object passed in by the user that will be returned as a 637 * parameter to the callback, int constant. Specific to 638 * unload listeners 639 * @property OBJ 640 * @type int 641 * @static 642 * @final 643 */ 644 UNLOAD_OBJ: 3, 645 646 /** 647 * Adjusted context, either the element we are registering the event 648 * on or the custom object passed in by the listener, int constant 649 * @property ADJ_SCOPE 650 * @type int 651 * @static 652 * @final 653 */ 654 ADJ_SCOPE: 4, 655 656 /** 657 * The original obj passed into addListener 658 * @property OBJ 659 * @type int 660 * @static 661 * @final 662 */ 663 OBJ: 5, 664 665 /** 666 * The original context parameter passed into addListener 667 * @property OVERRIDE 668 * @type int 669 * @static 670 * @final 671 */ 672 OVERRIDE: 6, 673 674 /** 675 * The original capture parameter passed into addListener 676 * @property CAPTURE 677 * @type int 678 * @static 679 * @final 680 */ 681 CAPTURE: 7, 682 683 /** 684 * addListener/removeListener can throw errors in unexpected scenarios. 685 * These errors are suppressed, the method returns false, and this property 686 * is set 687 * @property lastError 688 * @static 689 * @type Error 690 */ 691 lastError: null, 692 693 /** 694 * Safari detection 695 * @property isSafari 696 * @private 697 * @static 698 * @deprecated use YAHOO.env.ua.webkit 699 */ 700 isSafari: YAHOO.env.ua.webkit, 701 702 /** 703 * webkit version 704 * @property webkit 705 * @type string 706 * @private 707 * @static 708 * @deprecated use YAHOO.env.ua.webkit 709 */ 710 webkit: YAHOO.env.ua.webkit, 711 712 /** 713 * IE detection 714 * @property isIE 715 * @private 716 * @static 717 * @deprecated use YAHOO.env.ua.ie 718 */ 719 isIE: isIE, 720 721 /** 722 * poll handle 723 * @property _interval 724 * @static 725 * @private 726 */ 727 _interval: null, 728 729 /** 730 * document readystate poll handle 731 * @property _dri 732 * @static 733 * @private 734 */ 735 _dri: null, 736 737 738 /** 739 * Map of special event types 740 * @property _specialTypes 741 * @static 742 * @private 743 */ 744 _specialTypes: { 745 focusin: (isIE ? "focusin" : "focus"), 746 focusout: (isIE ? "focusout" : "blur") 747 }, 748 749 750 /** 751 * True when the document is initially usable 752 * @property DOMReady 753 * @type boolean 754 * @static 755 */ 756 DOMReady: false, 757 758 /** 759 * Errors thrown by subscribers of custom events are caught 760 * and the error message is written to the debug console. If 761 * this property is set to true, it will also re-throw the 762 * error. 763 * @property throwErrors 764 * @type boolean 765 * @default false 766 */ 767 throwErrors: false, 768 769 770 /** 771 * @method startInterval 772 * @static 773 * @private 774 */ 775 startInterval: function() { 776 if (!this._interval) { 777 // var self = this; 778 // var callback = function() { self._tryPreloadAttach(); }; 779 // this._interval = setInterval(callback, this.POLL_INTERVAL); 780 this._interval = YAHOO.lang.later(this.POLL_INTERVAL, this, this._tryPreloadAttach, null, true); 781 } 782 }, 783 784 /** 785 * Executes the supplied callback when the item with the supplied 786 * id is found. This is meant to be used to execute behavior as 787 * soon as possible as the page loads. If you use this after the 788 * initial page load it will poll for a fixed time for the element. 789 * The number of times it will poll and the frequency are 790 * configurable. By default it will poll for 10 seconds. 791 * 792 * <p>The callback is executed with a single parameter: 793 * the custom object parameter, if provided.</p> 794 * 795 * @method onAvailable 796 * 797 * @param {string||string[]} id the id of the element, or an array 798 * of ids to look for. 799 * @param {function} fn what to execute when the element is found. 800 * @param {object} obj an optional object to be passed back as 801 * a parameter to fn. 802 * @param {boolean|object} overrideContext If set to true, fn will execute 803 * in the context of obj, if set to an object it 804 * will execute in the context of that object 805 * @param checkContent {boolean} check child node readiness (onContentReady) 806 * @static 807 */ 808 onAvailable: function(id, fn, obj, overrideContext, checkContent) { 809 810 var a = (YAHOO.lang.isString(id)) ? [id] : id; 811 812 for (var i=0; i<a.length; i=i+1) { 813 onAvailStack.push({id: a[i], 814 fn: fn, 815 obj: obj, 816 overrideContext: overrideContext, 817 checkReady: checkContent }); 818 } 819 820 retryCount = this.POLL_RETRYS; 821 822 this.startInterval(); 823 }, 824 825 /** 826 * Works the same way as onAvailable, but additionally checks the 827 * state of sibling elements to determine if the content of the 828 * available element is safe to modify. 829 * 830 * <p>The callback is executed with a single parameter: 831 * the custom object parameter, if provided.</p> 832 * 833 * @method onContentReady 834 * 835 * @param {string} id the id of the element to look for. 836 * @param {function} fn what to execute when the element is ready. 837 * @param {object} obj an optional object to be passed back as 838 * a parameter to fn. 839 * @param {boolean|object} overrideContext If set to true, fn will execute 840 * in the context of obj. If an object, fn will 841 * exectute in the context of that object 842 * 843 * @static 844 */ 845 onContentReady: function(id, fn, obj, overrideContext) { 846 this.onAvailable(id, fn, obj, overrideContext, true); 847 }, 848 849 /** 850 * Executes the supplied callback when the DOM is first usable. This 851 * will execute immediately if called after the DOMReady event has 852 * fired. @todo the DOMContentReady event does not fire when the 853 * script is dynamically injected into the page. This means the 854 * DOMReady custom event will never fire in FireFox or Opera when the 855 * library is injected. It _will_ fire in Safari, and the IE 856 * implementation would allow for us to fire it if the defered script 857 * is not available. We want this to behave the same in all browsers. 858 * Is there a way to identify when the script has been injected 859 * instead of included inline? Is there a way to know whether the 860 * window onload event has fired without having had a listener attached 861 * to it when it did so? 862 * 863 * <p>The callback is a CustomEvent, so the signature is:</p> 864 * <p>type <string>, args <array>, customobject <object></p> 865 * <p>For DOMReady events, there are no fire argments, so the 866 * signature is:</p> 867 * <p>"DOMReady", [], obj</p> 868 * 869 * 870 * @method onDOMReady 871 * 872 * @param {function} fn what to execute when the element is found. 873 * @param {object} obj an optional object to be passed back as 874 * a parameter to fn. 875 * @param {boolean|object} overrideContext If set to true, fn will execute 876 * in the context of obj, if set to an object it 877 * will execute in the context of that object 878 * 879 * @static 880 */ 881 // onDOMReady: function(fn, obj, overrideContext) { 882 onDOMReady: function() { 883 this.DOMReadyEvent.subscribe.apply(this.DOMReadyEvent, arguments); 884 }, 885 886 887 /** 888 * Appends an event handler 889 * 890 * @method _addListener 891 * 892 * @param {String|HTMLElement|Array|NodeList} el An id, an element 893 * reference, or a collection of ids and/or elements to assign the 894 * listener to. 895 * @param {String} sType The type of event to append 896 * @param {Function} fn The method the event invokes 897 * @param {Object} obj An arbitrary object that will be 898 * passed as a parameter to the handler 899 * @param {Boolean|object} overrideContext If true, the obj passed in becomes 900 * the execution context of the listener. If an 901 * object, this object becomes the execution 902 * context. 903 * @param {boolen} capture capture or bubble phase 904 * @return {Boolean} True if the action was successful or defered, 905 * false if one or more of the elements 906 * could not have the listener attached, 907 * or if the operation throws an exception. 908 * @private 909 * @static 910 */ 911 _addListener: function(el, sType, fn, obj, overrideContext, bCapture) { 912 913 if (!fn || !fn.call) { 914 return false; 915 } 916 917 // The el argument can be an array of elements or element ids. 918 if ( this._isValidCollection(el)) { 919 var ok = true; 920 for (var i=0,len=el.length; i<len; ++i) { 921 ok = this.on(el[i], 922 sType, 923 fn, 924 obj, 925 overrideContext) && ok; 926 } 927 return ok; 928 929 } else if (YAHOO.lang.isString(el)) { 930 var oEl = this.getEl(el); 931 // If the el argument is a string, we assume it is 932 // actually the id of the element. If the page is loaded 933 // we convert el to the actual element, otherwise we 934 // defer attaching the event until onload event fires 935 936 // check to see if we need to delay hooking up the event 937 // until after the page loads. 938 if (oEl) { 939 el = oEl; 940 } else { 941 // defer adding the event until the element is available 942 this.onAvailable(el, function() { 943 YAHOO.util.Event._addListener(el, sType, fn, obj, overrideContext, bCapture); 944 }); 945 946 return true; 947 } 948 } 949 950 // Element should be an html element or an array if we get 951 // here. 952 if (!el) { 953 return false; 954 } 955 956 // we need to make sure we fire registered unload events 957 // prior to automatically unhooking them. So we hang on to 958 // these instead of attaching them to the window and fire the 959 // handles explicitly during our one unload event. 960 if ("unload" == sType && obj !== this) { 961 unloadListeners[unloadListeners.length] = 962 [el, sType, fn, obj, overrideContext]; 963 return true; 964 } 965 966 967 // if the user chooses to override the context, we use the custom 968 // object passed in, otherwise the executing context will be the 969 // HTML element that the event is registered on 970 var context = el; 971 if (overrideContext) { 972 if (overrideContext === true) { 973 context = obj; 974 } else { 975 context = overrideContext; 976 } 977 } 978 979 // wrap the function so we can return the obj object when 980 // the event fires; 981 var wrappedFn = function(e) { 982 return fn.call(context, YAHOO.util.Event.getEvent(e, el), 983 obj); 984 }; 985 986 var li = [el, sType, fn, wrappedFn, context, obj, overrideContext, bCapture]; 987 var index = listeners.length; 988 // cache the listener so we can try to automatically unload 989 listeners[index] = li; 990 991 try { 992 this._simpleAdd(el, sType, wrappedFn, bCapture); 993 } catch(ex) { 994 // handle an error trying to attach an event. If it fails 995 // we need to clean up the cache 996 this.lastError = ex; 997 this.removeListener(el, sType, fn); 998 return false; 999 } 1000 1001 return true; 1002 1003 }, 1004 1005 /** 1006 * Checks to see if the type requested is a special type 1007 * (as defined by the _specialTypes hash), and (if so) returns 1008 * the special type name. 1009 * 1010 * @method _getType 1011 * 1012 * @param {String} sType The type to look up 1013 * @private 1014 */ 1015 _getType: function (type) { 1016 1017 return this._specialTypes[type] || type; 1018 1019 }, 1020 1021 1022 /** 1023 * Appends an event handler 1024 * 1025 * @method addListener 1026 * 1027 * @param {String|HTMLElement|Array|NodeList} el An id, an element 1028 * reference, or a collection of ids and/or elements to assign the 1029 * listener to. 1030 * @param {String} sType The type of event to append 1031 * @param {Function} fn The method the event invokes 1032 * @param {Object} obj An arbitrary object that will be 1033 * passed as a parameter to the handler 1034 * @param {Boolean|object} overrideContext If true, the obj passed in becomes 1035 * the execution context of the listener. If an 1036 * object, this object becomes the execution 1037 * context. 1038 * @return {Boolean} True if the action was successful or defered, 1039 * false if one or more of the elements 1040 * could not have the listener attached, 1041 * or if the operation throws an exception. 1042 * @static 1043 */ 1044 addListener: function (el, sType, fn, obj, overrideContext) { 1045 1046 var capture = ((sType == FOCUSIN || sType == FOCUSOUT) && !YAHOO.env.ua.ie) ? true : false; 1047 1048 return this._addListener(el, this._getType(sType), fn, obj, overrideContext, capture); 1049 1050 }, 1051 1052 1053 /** 1054 * Attaches a focusin event listener to the specified element for 1055 * the purpose of listening for the focus event on the element's 1056 * descendants. 1057 * @method addFocusListener 1058 * 1059 * @param {String|HTMLElement|Array|NodeList} el An id, an element 1060 * reference, or a collection of ids and/or elements to assign the 1061 * listener to. 1062 * @param {Function} fn The method the event invokes 1063 * @param {Object} obj An arbitrary object that will be 1064 * passed as a parameter to the handler 1065 * @param {Boolean|object} overrideContext If true, the obj passed in becomes 1066 * the execution context of the listener. If an 1067 * object, this object becomes the execution 1068 * context. 1069 * @return {Boolean} True if the action was successful or defered, 1070 * false if one or more of the elements 1071 * could not have the listener attached, 1072 * or if the operation throws an exception. 1073 * @static 1074 * @deprecated use YAHOO.util.Event.on and specify "focusin" as the event type. 1075 */ 1076 addFocusListener: function (el, fn, obj, overrideContext) { 1077 return this.on(el, FOCUSIN, fn, obj, overrideContext); 1078 }, 1079 1080 1081 /** 1082 * Removes a focusin event listener to the specified element for 1083 * the purpose of listening for the focus event on the element's 1084 * descendants. 1085 * 1086 * @method removeFocusListener 1087 * 1088 * @param {String|HTMLElement|Array|NodeList} el An id, an element 1089 * reference, or a collection of ids and/or elements to remove 1090 * the listener from. 1091 * @param {Function} fn the method the event invokes. If fn is 1092 * undefined, then all event handlers for the type of event are 1093 * removed. 1094 * @return {boolean} true if the unbind was successful, false 1095 * otherwise. 1096 * @static 1097 * @deprecated use YAHOO.util.Event.removeListener and specify "focusin" as the event type. 1098 */ 1099 removeFocusListener: function (el, fn) { 1100 return this.removeListener(el, FOCUSIN, fn); 1101 }, 1102 1103 /** 1104 * Attaches a focusout event listener to the specified element for 1105 * the purpose of listening for the blur event on the element's 1106 * descendants. 1107 * 1108 * @method addBlurListener 1109 * 1110 * @param {String|HTMLElement|Array|NodeList} el An id, an element 1111 * reference, or a collection of ids and/or elements to assign the 1112 * listener to. 1113 * @param {Function} fn The method the event invokes 1114 * @param {Object} obj An arbitrary object that will be 1115 * passed as a parameter to the handler 1116 * @param {Boolean|object} overrideContext If true, the obj passed in becomes 1117 * the execution context of the listener. If an 1118 * object, this object becomes the execution 1119 * context. 1120 * @return {Boolean} True if the action was successful or defered, 1121 * false if one or more of the elements 1122 * could not have the listener attached, 1123 * or if the operation throws an exception. 1124 * @static 1125 * @deprecated use YAHOO.util.Event.on and specify "focusout" as the event type. 1126 */ 1127 addBlurListener: function (el, fn, obj, overrideContext) { 1128 return this.on(el, FOCUSOUT, fn, obj, overrideContext); 1129 }, 1130 1131 /** 1132 * Removes a focusout event listener to the specified element for 1133 * the purpose of listening for the blur event on the element's 1134 * descendants. 1135 * 1136 * @method removeBlurListener 1137 * 1138 * @param {String|HTMLElement|Array|NodeList} el An id, an element 1139 * reference, or a collection of ids and/or elements to remove 1140 * the listener from. 1141 * @param {Function} fn the method the event invokes. If fn is 1142 * undefined, then all event handlers for the type of event are 1143 * removed. 1144 * @return {boolean} true if the unbind was successful, false 1145 * otherwise. 1146 * @static 1147 * @deprecated use YAHOO.util.Event.removeListener and specify "focusout" as the event type. 1148 */ 1149 removeBlurListener: function (el, fn) { 1150 return this.removeListener(el, FOCUSOUT, fn); 1151 }, 1152 1153 /** 1154 * Removes an event listener 1155 * 1156 * @method removeListener 1157 * 1158 * @param {String|HTMLElement|Array|NodeList} el An id, an element 1159 * reference, or a collection of ids and/or elements to remove 1160 * the listener from. 1161 * @param {String} sType the type of event to remove. 1162 * @param {Function} fn the method the event invokes. If fn is 1163 * undefined, then all event handlers for the type of event are 1164 * removed. 1165 * @return {boolean} true if the unbind was successful, false 1166 * otherwise. 1167 * @static 1168 */ 1169 removeListener: function(el, sType, fn) { 1170 var i, len, li; 1171 1172 sType = this._getType(sType); 1173 1174 // The el argument can be a string 1175 if (typeof el == "string") { 1176 el = this.getEl(el); 1177 // The el argument can be an array of elements or element ids. 1178 } else if ( this._isValidCollection(el)) { 1179 var ok = true; 1180 for (i=el.length-1; i>-1; i--) { 1181 ok = ( this.removeListener(el[i], sType, fn) && ok ); 1182 } 1183 return ok; 1184 } 1185 1186 if (!fn || !fn.call) { 1187 //return false; 1188 return this.purgeElement(el, false, sType); 1189 } 1190 1191 if ("unload" == sType) { 1192 1193 for (i=unloadListeners.length-1; i>-1; i--) { 1194 li = unloadListeners[i]; 1195 if (li && 1196 li[0] == el && 1197 li[1] == sType && 1198 li[2] == fn) { 1199 unloadListeners.splice(i, 1); 1200 // unloadListeners[i]=null; 1201 return true; 1202 } 1203 } 1204 1205 return false; 1206 } 1207 1208 var cacheItem = null; 1209 1210 // The index is a hidden parameter; needed to remove it from 1211 // the method signature because it was tempting users to 1212 // try and take advantage of it, which is not possible. 1213 var index = arguments[3]; 1214 1215 if ("undefined" === typeof index) { 1216 index = this._getCacheIndex(listeners, el, sType, fn); 1217 } 1218 1219 if (index >= 0) { 1220 cacheItem = listeners[index]; 1221 } 1222 1223 if (!el || !cacheItem) { 1224 return false; 1225 } 1226 1227 1228 var bCapture = cacheItem[this.CAPTURE] === true ? true : false; 1229 1230 try { 1231 this._simpleRemove(el, sType, cacheItem[this.WFN], bCapture); 1232 } catch(ex) { 1233 this.lastError = ex; 1234 return false; 1235 } 1236 1237 // removed the wrapped handler 1238 delete listeners[index][this.WFN]; 1239 delete listeners[index][this.FN]; 1240 listeners.splice(index, 1); 1241 // listeners[index]=null; 1242 1243 return true; 1244 1245 }, 1246 1247 /** 1248 * Returns the event's target element. Safari sometimes provides 1249 * a text node, and this is automatically resolved to the text 1250 * node's parent so that it behaves like other browsers. 1251 * @method getTarget 1252 * @param {Event} ev the event 1253 * @param {boolean} resolveTextNode when set to true the target's 1254 * parent will be returned if the target is a 1255 * text node. @deprecated, the text node is 1256 * now resolved automatically 1257 * @return {HTMLElement} the event's target 1258 * @static 1259 */ 1260 getTarget: function(ev, resolveTextNode) { 1261 var t = ev.target || ev.srcElement; 1262 return this.resolveTextNode(t); 1263 }, 1264 1265 /** 1266 * In some cases, some browsers will return a text node inside 1267 * the actual element that was targeted. This normalizes the 1268 * return value for getTarget and getRelatedTarget. 1269 * 1270 * If accessing a property of the node throws an error, this is 1271 * probably the anonymous div wrapper Gecko adds inside text 1272 * nodes. This likely will only occur when attempting to access 1273 * the relatedTarget. In this case, we now return null because 1274 * the anonymous div is completely useless and we do not know 1275 * what the related target was because we can't even get to 1276 * the element's parent node. 1277 * 1278 * @method resolveTextNode 1279 * @param {HTMLElement} node node to resolve 1280 * @return {HTMLElement} the normized node 1281 * @static 1282 */ 1283 resolveTextNode: function(n) { 1284 try { 1285 if (n && 3 == n.nodeType) { 1286 return n.parentNode; 1287 } 1288 } catch(e) { 1289 return null; 1290 } 1291 1292 return n; 1293 }, 1294 1295 /** 1296 * Returns the event's pageX 1297 * @method getPageX 1298 * @param {Event} ev the event 1299 * @return {int} the event's pageX 1300 * @static 1301 */ 1302 getPageX: function(ev) { 1303 var x = ev.pageX; 1304 if (!x && 0 !== x) { 1305 x = ev.clientX || 0; 1306 1307 if ( this.isIE ) { 1308 x += this._getScrollLeft(); 1309 } 1310 } 1311 1312 return x; 1313 }, 1314 1315 /** 1316 * Returns the event's pageY 1317 * @method getPageY 1318 * @param {Event} ev the event 1319 * @return {int} the event's pageY 1320 * @static 1321 */ 1322 getPageY: function(ev) { 1323 var y = ev.pageY; 1324 if (!y && 0 !== y) { 1325 y = ev.clientY || 0; 1326 1327 if ( this.isIE ) { 1328 y += this._getScrollTop(); 1329 } 1330 } 1331 1332 1333 return y; 1334 }, 1335 1336 /** 1337 * Returns the pageX and pageY properties as an indexed array. 1338 * @method getXY 1339 * @param {Event} ev the event 1340 * @return {[x, y]} the pageX and pageY properties of the event 1341 * @static 1342 */ 1343 getXY: function(ev) { 1344 return [this.getPageX(ev), this.getPageY(ev)]; 1345 }, 1346 1347 /** 1348 * Returns the event's related target 1349 * @method getRelatedTarget 1350 * @param {Event} ev the event 1351 * @return {HTMLElement} the event's relatedTarget 1352 * @static 1353 */ 1354 getRelatedTarget: function(ev) { 1355 var t = ev.relatedTarget; 1356 if (!t) { 1357 if (ev.type == "mouseout") { 1358 t = ev.toElement; 1359 } else if (ev.type == "mouseover") { 1360 t = ev.fromElement; 1361 } 1362 } 1363 1364 return this.resolveTextNode(t); 1365 }, 1366 1367 /** 1368 * Returns the time of the event. If the time is not included, the 1369 * event is modified using the current time. 1370 * @method getTime 1371 * @param {Event} ev the event 1372 * @return {Date} the time of the event 1373 * @static 1374 */ 1375 getTime: function(ev) { 1376 if (!ev.time) { 1377 var t = new Date().getTime(); 1378 try { 1379 ev.time = t; 1380 } catch(ex) { 1381 this.lastError = ex; 1382 return t; 1383 } 1384 } 1385 1386 return ev.time; 1387 }, 1388 1389 /** 1390 * Convenience method for stopPropagation + preventDefault 1391 * @method stopEvent 1392 * @param {Event} ev the event 1393 * @static 1394 */ 1395 stopEvent: function(ev) { 1396 this.stopPropagation(ev); 1397 this.preventDefault(ev); 1398 }, 1399 1400 /** 1401 * Stops event propagation 1402 * @method stopPropagation 1403 * @param {Event} ev the event 1404 * @static 1405 */ 1406 stopPropagation: function(ev) { 1407 if (ev.stopPropagation) { 1408 ev.stopPropagation(); 1409 } else { 1410 ev.cancelBubble = true; 1411 } 1412 }, 1413 1414 /** 1415 * Prevents the default behavior of the event 1416 * @method preventDefault 1417 * @param {Event} ev the event 1418 * @static 1419 */ 1420 preventDefault: function(ev) { 1421 if (ev.preventDefault) { 1422 ev.preventDefault(); 1423 } else { 1424 ev.returnValue = false; 1425 } 1426 }, 1427 1428 /** 1429 * Finds the event in the window object, the caller's arguments, or 1430 * in the arguments of another method in the callstack. This is 1431 * executed automatically for events registered through the event 1432 * manager, so the implementer should not normally need to execute 1433 * this function at all. 1434 * @method getEvent 1435 * @param {Event} e the event parameter from the handler 1436 * @param {HTMLElement} boundEl the element the listener is attached to 1437 * @return {Event} the event 1438 * @static 1439 */ 1440 getEvent: function(e, boundEl) { 1441 var ev = e || window.event; 1442 1443 if (!ev) { 1444 var c = this.getEvent.caller; 1445 while (c) { 1446 ev = c.arguments[0]; 1447 if (ev && Event == ev.constructor) { 1448 break; 1449 } 1450 c = c.caller; 1451 } 1452 } 1453 1454 return ev; 1455 }, 1456 1457 /** 1458 * Returns the charcode for an event 1459 * @method getCharCode 1460 * @param {Event} ev the event 1461 * @return {int} the event's charCode 1462 * @static 1463 */ 1464 getCharCode: function(ev) { 1465 var code = ev.keyCode || ev.charCode || 0; 1466 1467 // webkit key normalization 1468 if (YAHOO.env.ua.webkit && (code in webkitKeymap)) { 1469 code = webkitKeymap[code]; 1470 } 1471 return code; 1472 }, 1473 1474 /** 1475 * Locating the saved event handler data by function ref 1476 * 1477 * @method _getCacheIndex 1478 * @static 1479 * @private 1480 */ 1481 _getCacheIndex: function(a, el, sType, fn) { 1482 for (var i=0, l=a.length; i<l; i=i+1) { 1483 var li = a[i]; 1484 if ( li && 1485 li[this.FN] == fn && 1486 li[this.EL] == el && 1487 li[this.TYPE] == sType ) { 1488 return i; 1489 } 1490 } 1491 1492 return -1; 1493 }, 1494 1495 /** 1496 * Generates an unique ID for the element if it does not already 1497 * have one. 1498 * @method generateId 1499 * @param el the element to create the id for 1500 * @return {string} the resulting id of the element 1501 * @static 1502 */ 1503 generateId: function(el) { 1504 var id = el.id; 1505 1506 if (!id) { 1507 id = "yuievtautoid-" + counter; 1508 ++counter; 1509 el.id = id; 1510 } 1511 1512 return id; 1513 }, 1514 1515 1516 /** 1517 * We want to be able to use getElementsByTagName as a collection 1518 * to attach a group of events to. Unfortunately, different 1519 * browsers return different types of collections. This function 1520 * tests to determine if the object is array-like. It will also 1521 * fail if the object is an array, but is empty. 1522 * @method _isValidCollection 1523 * @param o the object to test 1524 * @return {boolean} true if the object is array-like and populated 1525 * @static 1526 * @private 1527 */ 1528 _isValidCollection: function(o) { 1529 try { 1530 return ( o && // o is something 1531 typeof o !== "string" && // o is not a string 1532 o.length && // o is indexed 1533 !o.tagName && // o is not an HTML element 1534 !o.alert && // o is not a window 1535 typeof o[0] !== "undefined" ); 1536 } catch(ex) { 1537 return false; 1538 } 1539 1540 }, 1541 1542 /** 1543 * @private 1544 * @property elCache 1545 * DOM element cache 1546 * @static 1547 * @deprecated Elements are not cached due to issues that arise when 1548 * elements are removed and re-added 1549 */ 1550 elCache: {}, 1551 1552 /** 1553 * We cache elements bound by id because when the unload event 1554 * fires, we can no longer use document.getElementById 1555 * @method getEl 1556 * @static 1557 * @private 1558 * @deprecated Elements are not cached any longer 1559 */ 1560 getEl: function(id) { 1561 return (typeof id === "string") ? document.getElementById(id) : id; 1562 }, 1563 1564 /** 1565 * Clears the element cache 1566 * @deprecated Elements are not cached any longer 1567 * @method clearCache 1568 * @static 1569 * @private 1570 */ 1571 clearCache: function() { }, 1572 1573 /** 1574 * Custom event the fires when the dom is initially usable 1575 * @event DOMReadyEvent 1576 */ 1577 DOMReadyEvent: new YAHOO.util.CustomEvent("DOMReady", YAHOO, 0, 0, 1), 1578 1579 /** 1580 * hook up any deferred listeners 1581 * @method _load 1582 * @static 1583 * @private 1584 */ 1585 _load: function(e) { 1586 1587 if (!loadComplete) { 1588 loadComplete = true; 1589 var EU = YAHOO.util.Event; 1590 1591 // Just in case DOMReady did not go off for some reason 1592 EU._ready(); 1593 1594 // Available elements may not have been detected before the 1595 // window load event fires. Try to find them now so that the 1596 // the user is more likely to get the onAvailable notifications 1597 // before the window load notification 1598 EU._tryPreloadAttach(); 1599 1600 } 1601 }, 1602 1603 /** 1604 * Fires the DOMReady event listeners the first time the document is 1605 * usable. 1606 * @method _ready 1607 * @static 1608 * @private 1609 */ 1610 _ready: function(e) { 1611 var EU = YAHOO.util.Event; 1612 if (!EU.DOMReady) { 1613 EU.DOMReady=true; 1614 1615 // Fire the content ready custom event 1616 EU.DOMReadyEvent.fire(); 1617 1618 // Remove the DOMContentLoaded (FF/Opera) 1619 EU._simpleRemove(document, "DOMContentLoaded", EU._ready); 1620 } 1621 }, 1622 1623 /** 1624 * Polling function that runs before the onload event fires, 1625 * attempting to attach to DOM Nodes as soon as they are 1626 * available 1627 * @method _tryPreloadAttach 1628 * @static 1629 * @private 1630 */ 1631 _tryPreloadAttach: function() { 1632 1633 if (onAvailStack.length === 0) { 1634 retryCount = 0; 1635 if (this._interval) { 1636 // clearInterval(this._interval); 1637 this._interval.cancel(); 1638 this._interval = null; 1639 } 1640 return; 1641 } 1642 1643 if (this.locked) { 1644 return; 1645 } 1646 1647 if (this.isIE) { 1648 // Hold off if DOMReady has not fired and check current 1649 // readyState to protect against the IE operation aborted 1650 // issue. 1651 if (!this.DOMReady) { 1652 this.startInterval(); 1653 return; 1654 } 1655 } 1656 1657 this.locked = true; 1658 1659 1660 // keep trying until after the page is loaded. We need to 1661 // check the page load state prior to trying to bind the 1662 // elements so that we can be certain all elements have been 1663 // tested appropriately 1664 var tryAgain = !loadComplete; 1665 if (!tryAgain) { 1666 tryAgain = (retryCount > 0 && onAvailStack.length > 0); 1667 } 1668 1669 // onAvailable 1670 var notAvail = []; 1671 1672 var executeItem = function (el, item) { 1673 var context = el; 1674 if (item.overrideContext) { 1675 if (item.overrideContext === true) { 1676 context = item.obj; 1677 } else { 1678 context = item.overrideContext; 1679 } 1680 } 1681 item.fn.call(context, item.obj); 1682 }; 1683 1684 var i, len, item, el, ready=[]; 1685 1686 // onAvailable onContentReady 1687 for (i=0, len=onAvailStack.length; i<len; i=i+1) { 1688 item = onAvailStack[i]; 1689 if (item) { 1690 el = this.getEl(item.id); 1691 if (el) { 1692 if (item.checkReady) { 1693 if (loadComplete || el.nextSibling || !tryAgain) { 1694 ready.push(item); 1695 onAvailStack[i] = null; 1696 } 1697 } else { 1698 executeItem(el, item); 1699 onAvailStack[i] = null; 1700 } 1701 } else { 1702 notAvail.push(item); 1703 } 1704 } 1705 } 1706 1707 // make sure onContentReady fires after onAvailable 1708 for (i=0, len=ready.length; i<len; i=i+1) { 1709 item = ready[i]; 1710 executeItem(this.getEl(item.id), item); 1711 } 1712 1713 1714 retryCount--; 1715 1716 if (tryAgain) { 1717 for (i=onAvailStack.length-1; i>-1; i--) { 1718 item = onAvailStack[i]; 1719 if (!item || !item.id) { 1720 onAvailStack.splice(i, 1); 1721 } 1722 } 1723 1724 this.startInterval(); 1725 } else { 1726 if (this._interval) { 1727 // clearInterval(this._interval); 1728 this._interval.cancel(); 1729 this._interval = null; 1730 } 1731 } 1732 1733 this.locked = false; 1734 1735 }, 1736 1737 /** 1738 * Removes all listeners attached to the given element via addListener. 1739 * Optionally, the node's children can also be purged. 1740 * Optionally, you can specify a specific type of event to remove. 1741 * @method purgeElement 1742 * @param {HTMLElement} el the element to purge 1743 * @param {boolean} recurse recursively purge this element's children 1744 * as well. Use with caution. 1745 * @param {string} sType optional type of listener to purge. If 1746 * left out, all listeners will be removed 1747 * @static 1748 */ 1749 purgeElement: function(el, recurse, sType) { 1750 var oEl = (YAHOO.lang.isString(el)) ? this.getEl(el) : el; 1751 var elListeners = this.getListeners(oEl, sType), i, len; 1752 if (elListeners) { 1753 for (i=elListeners.length-1; i>-1; i--) { 1754 var l = elListeners[i]; 1755 this.removeListener(oEl, l.type, l.fn); 1756 } 1757 } 1758 1759 if (recurse && oEl && oEl.childNodes) { 1760 for (i=0,len=oEl.childNodes.length; i<len ; ++i) { 1761 this.purgeElement(oEl.childNodes[i], recurse, sType); 1762 } 1763 } 1764 }, 1765 1766 /** 1767 * Returns all listeners attached to the given element via addListener. 1768 * Optionally, you can specify a specific type of event to return. 1769 * @method getListeners 1770 * @param el {HTMLElement|string} the element or element id to inspect 1771 * @param sType {string} optional type of listener to return. If 1772 * left out, all listeners will be returned 1773 * @return {Object} the listener. Contains the following fields: 1774 * type: (string) the type of event 1775 * fn: (function) the callback supplied to addListener 1776 * obj: (object) the custom object supplied to addListener 1777 * adjust: (boolean|object) whether or not to adjust the default context 1778 * scope: (boolean) the derived context based on the adjust parameter 1779 * index: (int) its position in the Event util listener cache 1780 * @static 1781 */ 1782 getListeners: function(el, sType) { 1783 var results=[], searchLists; 1784 if (!sType) { 1785 searchLists = [listeners, unloadListeners]; 1786 } else if (sType === "unload") { 1787 searchLists = [unloadListeners]; 1788 } else { 1789 sType = this._getType(sType); 1790 searchLists = [listeners]; 1791 } 1792 1793 var oEl = (YAHOO.lang.isString(el)) ? this.getEl(el) : el; 1794 1795 for (var j=0;j<searchLists.length; j=j+1) { 1796 var searchList = searchLists[j]; 1797 if (searchList) { 1798 for (var i=0,len=searchList.length; i<len ; ++i) { 1799 var l = searchList[i]; 1800 if ( l && l[this.EL] === oEl && 1801 (!sType || sType === l[this.TYPE]) ) { 1802 results.push({ 1803 type: l[this.TYPE], 1804 fn: l[this.FN], 1805 obj: l[this.OBJ], 1806 adjust: l[this.OVERRIDE], 1807 scope: l[this.ADJ_SCOPE], 1808 index: i 1809 }); 1810 } 1811 } 1812 } 1813 } 1814 1815 return (results.length) ? results : null; 1816 }, 1817 1818 /** 1819 * Removes all listeners registered by pe.event. Called 1820 * automatically during the unload event. 1821 * @method _unload 1822 * @static 1823 * @private 1824 */ 1825 _unload: function(e) { 1826 1827 var EU = YAHOO.util.Event, i, j, l, len, index, 1828 ul = unloadListeners.slice(), context; 1829 1830 // execute and clear stored unload listeners 1831 for (i=0, len=unloadListeners.length; i<len; ++i) { 1832 l = ul[i]; 1833 if (l) { 1834 try { 1835 context = window; 1836 if (l[EU.ADJ_SCOPE]) { 1837 if (l[EU.ADJ_SCOPE] === true) { 1838 context = l[EU.UNLOAD_OBJ]; 1839 } else { 1840 context = l[EU.ADJ_SCOPE]; 1841 } 1842 } 1843 l[EU.FN].call(context, EU.getEvent(e, l[EU.EL]), l[EU.UNLOAD_OBJ] ); 1844 } catch(e1) {} 1845 ul[i] = null; 1846 } 1847 } 1848 1849 l = null; 1850 context = null; 1851 unloadListeners = null; 1852 1853 // Remove listeners to handle IE memory leaks 1854 // 2.5.0 listeners are removed for all browsers again. FireFox preserves 1855 // at least some listeners between page refreshes, potentially causing 1856 // errors during page load (mouseover listeners firing before they 1857 // should if the user moves the mouse at the correct moment). 1858 if (listeners) { 1859 for (j=listeners.length-1; j>-1; j--) { 1860 l = listeners[j]; 1861 if (l) { 1862 try { 1863 EU.removeListener(l[EU.EL], l[EU.TYPE], l[EU.FN], j); 1864 } catch(e2) {} 1865 } 1866 } 1867 l=null; 1868 } 1869 1870 try { 1871 EU._simpleRemove(window, "unload", EU._unload); 1872 EU._simpleRemove(window, "load", EU._load); 1873 } catch(e3) {} 1874 1875 }, 1876 1877 /** 1878 * Returns scrollLeft 1879 * @method _getScrollLeft 1880 * @static 1881 * @private 1882 */ 1883 _getScrollLeft: function() { 1884 return this._getScroll()[1]; 1885 }, 1886 1887 /** 1888 * Returns scrollTop 1889 * @method _getScrollTop 1890 * @static 1891 * @private 1892 */ 1893 _getScrollTop: function() { 1894 return this._getScroll()[0]; 1895 }, 1896 1897 /** 1898 * Returns the scrollTop and scrollLeft. Used to calculate the 1899 * pageX and pageY in Internet Explorer 1900 * @method _getScroll 1901 * @static 1902 * @private 1903 */ 1904 _getScroll: function() { 1905 var dd = document.documentElement, db = document.body; 1906 if (dd && (dd.scrollTop || dd.scrollLeft)) { 1907 return [dd.scrollTop, dd.scrollLeft]; 1908 } else if (db) { 1909 return [db.scrollTop, db.scrollLeft]; 1910 } else { 1911 return [0, 0]; 1912 } 1913 }, 1914 1915 /** 1916 * Used by old versions of CustomEvent, restored for backwards 1917 * compatibility 1918 * @method regCE 1919 * @private 1920 * @static 1921 * @deprecated still here for backwards compatibility 1922 */ 1923 regCE: function() {}, 1924 1925 /** 1926 * Adds a DOM event directly without the caching, cleanup, context adj, etc 1927 * 1928 * @method _simpleAdd 1929 * @param {HTMLElement} el the element to bind the handler to 1930 * @param {string} sType the type of event handler 1931 * @param {function} fn the callback to invoke 1932 * @param {boolen} capture capture or bubble phase 1933 * @static 1934 * @private 1935 */ 1936 _simpleAdd: function () { 1937 if (window.addEventListener) { 1938 return function(el, sType, fn, capture) { 1939 el.addEventListener(sType, fn, (capture)); 1940 }; 1941 } else if (window.attachEvent) { 1942 return function(el, sType, fn, capture) { 1943 el.attachEvent("on" + sType, fn); 1944 }; 1945 } else { 1946 return function(){}; 1947 } 1948 }(), 1949 1950 /** 1951 * Basic remove listener 1952 * 1953 * @method _simpleRemove 1954 * @param {HTMLElement} el the element to bind the handler to 1955 * @param {string} sType the type of event handler 1956 * @param {function} fn the callback to invoke 1957 * @param {boolen} capture capture or bubble phase 1958 * @static 1959 * @private 1960 */ 1961 _simpleRemove: function() { 1962 if (window.removeEventListener) { 1963 return function (el, sType, fn, capture) { 1964 el.removeEventListener(sType, fn, (capture)); 1965 }; 1966 } else if (window.detachEvent) { 1967 return function (el, sType, fn) { 1968 el.detachEvent("on" + sType, fn); 1969 }; 1970 } else { 1971 return function(){}; 1972 } 1973 }() 1974 }; 1975 1976 }(); 1977 1978 (function() { 1979 var EU = YAHOO.util.Event; 1980 1981 /** 1982 * Appends an event handler. This is an alias for <code>addListener</code> 1983 * 1984 * @method on 1985 * 1986 * @param {String|HTMLElement|Array|NodeList} el An id, an element 1987 * reference, or a collection of ids and/or elements to assign the 1988 * listener to. 1989 * @param {String} sType The type of event to append 1990 * @param {Function} fn The method the event invokes 1991 * @param {Object} obj An arbitrary object that will be 1992 * passed as a parameter to the handler 1993 * @param {Boolean|object} overrideContext If true, the obj passed in becomes 1994 * the execution context of the listener. If an 1995 * object, this object becomes the execution 1996 * context. 1997 * @return {Boolean} True if the action was successful or defered, 1998 * false if one or more of the elements 1999 * could not have the listener attached, 2000 * or if the operation throws an exception. 2001 * @static 2002 */ 2003 EU.on = EU.addListener; 2004 2005 /** 2006 * YAHOO.util.Event.onFocus is an alias for addFocusListener 2007 * @method onFocus 2008 * @see addFocusListener 2009 * @static 2010 * @deprecated use YAHOO.util.Event.on and specify "focusin" as the event type. 2011 */ 2012 EU.onFocus = EU.addFocusListener; 2013 2014 /** 2015 * YAHOO.util.Event.onBlur is an alias for addBlurListener 2016 * @method onBlur 2017 * @see addBlurListener 2018 * @static 2019 * @deprecated use YAHOO.util.Event.on and specify "focusout" as the event type. 2020 */ 2021 EU.onBlur = EU.addBlurListener; 2022 2023 /*! DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller/Diego Perini */ 2024 2025 // Internet Explorer: use the readyState of a defered script. 2026 // This isolates what appears to be a safe moment to manipulate 2027 // the DOM prior to when the document's readyState suggests 2028 // it is safe to do so. 2029 if (EU.isIE) { 2030 if (self !== self.top) { 2031 document.onreadystatechange = function() { 2032 if (document.readyState == 'complete') { 2033 document.onreadystatechange = null; 2034 EU._ready(); 2035 } 2036 }; 2037 } else { 2038 2039 // Process onAvailable/onContentReady items when the 2040 // DOM is ready. 2041 YAHOO.util.Event.onDOMReady( 2042 YAHOO.util.Event._tryPreloadAttach, 2043 YAHOO.util.Event, true); 2044 2045 var n = document.createElement('p'); 2046 2047 EU._dri = setInterval(function() { 2048 try { 2049 // throws an error if doc is not ready 2050 n.doScroll('left'); 2051 clearInterval(EU._dri); 2052 EU._dri = null; 2053 EU._ready(); 2054 n = null; 2055 } catch (ex) { 2056 } 2057 }, EU.POLL_INTERVAL); 2058 } 2059 2060 // The document's readyState in Safari currently will 2061 // change to loaded/complete before images are loaded. 2062 } else if (EU.webkit && EU.webkit < 525) { 2063 2064 EU._dri = setInterval(function() { 2065 var rs=document.readyState; 2066 if ("loaded" == rs || "complete" == rs) { 2067 clearInterval(EU._dri); 2068 EU._dri = null; 2069 EU._ready(); 2070 } 2071 }, EU.POLL_INTERVAL); 2072 2073 // FireFox and Opera: These browsers provide a event for this 2074 // moment. The latest WebKit releases now support this event. 2075 } else { 2076 2077 EU._simpleAdd(document, "DOMContentLoaded", EU._ready); 2078 2079 } 2080 ///////////////////////////////////////////////////////////// 2081 2082 2083 EU._simpleAdd(window, "load", EU._load); 2084 EU._simpleAdd(window, "unload", EU._unload); 2085 EU._tryPreloadAttach(); 2086 })(); 2087 2088 } 2089 /** 2090 * EventProvider is designed to be used with YAHOO.augment to wrap 2091 * CustomEvents in an interface that allows events to be subscribed to 2092 * and fired by name. This makes it possible for implementing code to 2093 * subscribe to an event that either has not been created yet, or will 2094 * not be created at all. 2095 * 2096 * @Class EventProvider 2097 */ 2098 YAHOO.util.EventProvider = function() { }; 2099 2100 YAHOO.util.EventProvider.prototype = { 2101 2102 /** 2103 * Private storage of custom events 2104 * @property __yui_events 2105 * @type Object[] 2106 * @private 2107 */ 2108 __yui_events: null, 2109 2110 /** 2111 * Private storage of custom event subscribers 2112 * @property __yui_subscribers 2113 * @type Object[] 2114 * @private 2115 */ 2116 __yui_subscribers: null, 2117 2118 /** 2119 * Subscribe to a CustomEvent by event type 2120 * 2121 * @method subscribe 2122 * @param p_type {string} the type, or name of the event 2123 * @param p_fn {function} the function to exectute when the event fires 2124 * @param p_obj {Object} An object to be passed along when the event 2125 * fires 2126 * @param overrideContext {boolean} If true, the obj passed in becomes the 2127 * execution scope of the listener 2128 */ 2129 subscribe: function(p_type, p_fn, p_obj, overrideContext) { 2130 2131 this.__yui_events = this.__yui_events || {}; 2132 var ce = this.__yui_events[p_type]; 2133 2134 if (ce) { 2135 ce.subscribe(p_fn, p_obj, overrideContext); 2136 } else { 2137 this.__yui_subscribers = this.__yui_subscribers || {}; 2138 var subs = this.__yui_subscribers; 2139 if (!subs[p_type]) { 2140 subs[p_type] = []; 2141 } 2142 subs[p_type].push( 2143 { fn: p_fn, obj: p_obj, overrideContext: overrideContext } ); 2144 } 2145 }, 2146 2147 /** 2148 * Unsubscribes one or more listeners the from the specified event 2149 * @method unsubscribe 2150 * @param p_type {string} The type, or name of the event. If the type 2151 * is not specified, it will attempt to remove 2152 * the listener from all hosted events. 2153 * @param p_fn {Function} The subscribed function to unsubscribe, if not 2154 * supplied, all subscribers will be removed. 2155 * @param p_obj {Object} The custom object passed to subscribe. This is 2156 * optional, but if supplied will be used to 2157 * disambiguate multiple listeners that are the same 2158 * (e.g., you subscribe many object using a function 2159 * that lives on the prototype) 2160 * @return {boolean} true if the subscriber was found and detached. 2161 */ 2162 unsubscribe: function(p_type, p_fn, p_obj) { 2163 this.__yui_events = this.__yui_events || {}; 2164 var evts = this.__yui_events; 2165 if (p_type) { 2166 var ce = evts[p_type]; 2167 if (ce) { 2168 return ce.unsubscribe(p_fn, p_obj); 2169 } 2170 } else { 2171 var ret = true; 2172 for (var i in evts) { 2173 if (YAHOO.lang.hasOwnProperty(evts, i)) { 2174 ret = ret && evts[i].unsubscribe(p_fn, p_obj); 2175 } 2176 } 2177 return ret; 2178 } 2179 2180 return false; 2181 }, 2182 2183 /** 2184 * Removes all listeners from the specified event. If the event type 2185 * is not specified, all listeners from all hosted custom events will 2186 * be removed. 2187 * @method unsubscribeAll 2188 * @param p_type {string} The type, or name of the event 2189 */ 2190 unsubscribeAll: function(p_type) { 2191 return this.unsubscribe(p_type); 2192 }, 2193 2194 /** 2195 * Creates a new custom event of the specified type. If a custom event 2196 * by that name already exists, it will not be re-created. In either 2197 * case the custom event is returned. 2198 * 2199 * @method createEvent 2200 * 2201 * @param p_type {string} the type, or name of the event 2202 * @param p_config {object} optional config params. Valid properties are: 2203 * 2204 * <ul> 2205 * <li> 2206 * scope: defines the default execution scope. If not defined 2207 * the default scope will be this instance. 2208 * </li> 2209 * <li> 2210 * silent: if true, the custom event will not generate log messages. 2211 * This is false by default. 2212 * </li> 2213 * <li> 2214 * fireOnce: if true, the custom event will only notify subscribers 2215 * once regardless of the number of times the event is fired. In 2216 * addition, new subscribers will be executed immediately if the 2217 * event has already fired. 2218 * This is false by default. 2219 * </li> 2220 * <li> 2221 * onSubscribeCallback: specifies a callback to execute when the 2222 * event has a new subscriber. This will fire immediately for 2223 * each queued subscriber if any exist prior to the creation of 2224 * the event. 2225 * </li> 2226 * </ul> 2227 * 2228 * @return {CustomEvent} the custom event 2229 * 2230 */ 2231 createEvent: function(p_type, p_config) { 2232 2233 this.__yui_events = this.__yui_events || {}; 2234 var opts = p_config || {}, 2235 events = this.__yui_events, ce; 2236 2237 if (events[p_type]) { 2238 } else { 2239 2240 ce = new YAHOO.util.CustomEvent(p_type, opts.scope || this, opts.silent, 2241 YAHOO.util.CustomEvent.FLAT, opts.fireOnce); 2242 2243 events[p_type] = ce; 2244 2245 if (opts.onSubscribeCallback) { 2246 ce.subscribeEvent.subscribe(opts.onSubscribeCallback); 2247 } 2248 2249 this.__yui_subscribers = this.__yui_subscribers || {}; 2250 var qs = this.__yui_subscribers[p_type]; 2251 2252 if (qs) { 2253 for (var i=0; i<qs.length; ++i) { 2254 ce.subscribe(qs[i].fn, qs[i].obj, qs[i].overrideContext); 2255 } 2256 } 2257 } 2258 2259 return events[p_type]; 2260 }, 2261 2262 2263 /** 2264 * Fire a custom event by name. The callback functions will be executed 2265 * from the scope specified when the event was created, and with the 2266 * following parameters: 2267 * <ul> 2268 * <li>The first argument fire() was executed with</li> 2269 * <li>The custom object (if any) that was passed into the subscribe() 2270 * method</li> 2271 * </ul> 2272 * @method fireEvent 2273 * @param p_type {string} the type, or name of the event 2274 * @param arguments {Object*} an arbitrary set of parameters to pass to 2275 * the handler. 2276 * @return {boolean} the return value from CustomEvent.fire 2277 * 2278 */ 2279 fireEvent: function(p_type) { 2280 2281 this.__yui_events = this.__yui_events || {}; 2282 var ce = this.__yui_events[p_type]; 2283 2284 if (!ce) { 2285 return null; 2286 } 2287 2288 var args = []; 2289 for (var i=1; i<arguments.length; ++i) { 2290 args.push(arguments[i]); 2291 } 2292 return ce.fire.apply(ce, args); 2293 }, 2294 2295 /** 2296 * Returns true if the custom event of the provided type has been created 2297 * with createEvent. 2298 * @method hasEvent 2299 * @param type {string} the type, or name of the event 2300 */ 2301 hasEvent: function(type) { 2302 if (this.__yui_events) { 2303 if (this.__yui_events[type]) { 2304 return true; 2305 } 2306 } 2307 return false; 2308 } 2309 2310 }; 2311 2312 (function() { 2313 2314 var Event = YAHOO.util.Event, Lang = YAHOO.lang; 2315 2316 /** 2317 * KeyListener is a utility that provides an easy interface for listening for 2318 * keydown/keyup events fired against DOM elements. 2319 * @namespace YAHOO.util 2320 * @class KeyListener 2321 * @constructor 2322 * @param {HTMLElement} attachTo The element or element ID to which the key 2323 * event should be attached 2324 * @param {String} attachTo The element or element ID to which the key 2325 * event should be attached 2326 * @param {Object} keyData The object literal representing the key(s) 2327 * to detect. Possible attributes are 2328 * shift(boolean), alt(boolean), ctrl(boolean) 2329 * and keys(either an int or an array of ints 2330 * representing keycodes). 2331 * @param {Function} handler The CustomEvent handler to fire when the 2332 * key event is detected 2333 * @param {Object} handler An object literal representing the handler. 2334 * @param {String} event Optional. The event (keydown or keyup) to 2335 * listen for. Defaults automatically to keydown. 2336 * 2337 * @knownissue the "keypress" event is completely broken in Safari 2.x and below. 2338 * the workaround is use "keydown" for key listening. However, if 2339 * it is desired to prevent the default behavior of the keystroke, 2340 * that can only be done on the keypress event. This makes key 2341 * handling quite ugly. 2342 * @knownissue keydown is also broken in Safari 2.x and below for the ESC key. 2343 * There currently is no workaround other than choosing another 2344 * key to listen for. 2345 */ 2346 YAHOO.util.KeyListener = function(attachTo, keyData, handler, event) { 2347 if (!attachTo) { 2348 } else if (!keyData) { 2349 } else if (!handler) { 2350 } 2351 2352 if (!event) { 2353 event = YAHOO.util.KeyListener.KEYDOWN; 2354 } 2355 2356 /** 2357 * The CustomEvent fired internally when a key is pressed 2358 * @event keyEvent 2359 * @private 2360 * @param {Object} keyData The object literal representing the key(s) to 2361 * detect. Possible attributes are shift(boolean), 2362 * alt(boolean), ctrl(boolean) and keys(either an 2363 * int or an array of ints representing keycodes). 2364 */ 2365 var keyEvent = new YAHOO.util.CustomEvent("keyPressed"); 2366 2367 /** 2368 * The CustomEvent fired when the KeyListener is enabled via the enable() 2369 * function 2370 * @event enabledEvent 2371 * @param {Object} keyData The object literal representing the key(s) to 2372 * detect. Possible attributes are shift(boolean), 2373 * alt(boolean), ctrl(boolean) and keys(either an 2374 * int or an array of ints representing keycodes). 2375 */ 2376 this.enabledEvent = new YAHOO.util.CustomEvent("enabled"); 2377 2378 /** 2379 * The CustomEvent fired when the KeyListener is disabled via the 2380 * disable() function 2381 * @event disabledEvent 2382 * @param {Object} keyData The object literal representing the key(s) to 2383 * detect. Possible attributes are shift(boolean), 2384 * alt(boolean), ctrl(boolean) and keys(either an 2385 * int or an array of ints representing keycodes). 2386 */ 2387 this.disabledEvent = new YAHOO.util.CustomEvent("disabled"); 2388 2389 if (Lang.isString(attachTo)) { 2390 attachTo = document.getElementById(attachTo); // No Dom util 2391 } 2392 2393 if (Lang.isFunction(handler)) { 2394 keyEvent.subscribe(handler); 2395 } else { 2396 keyEvent.subscribe(handler.fn, handler.scope, handler.correctScope); 2397 } 2398 2399 /** 2400 * Handles the key event when a key is pressed. 2401 * @method handleKeyPress 2402 * @param {DOMEvent} e The keypress DOM event 2403 * @param {Object} obj The DOM event scope object 2404 * @private 2405 */ 2406 function handleKeyPress(e, obj) { 2407 if (! keyData.shift) { 2408 keyData.shift = false; 2409 } 2410 if (! keyData.alt) { 2411 keyData.alt = false; 2412 } 2413 if (! keyData.ctrl) { 2414 keyData.ctrl = false; 2415 } 2416 2417 // check held down modifying keys first 2418 if (e.shiftKey == keyData.shift && 2419 e.altKey == keyData.alt && 2420 e.ctrlKey == keyData.ctrl) { // if we pass this, all modifiers match 2421 2422 var dataItem, keys = keyData.keys, key; 2423 2424 if (YAHOO.lang.isArray(keys)) { 2425 for (var i=0;i<keys.length;i++) { 2426 dataItem = keys[i]; 2427 key = Event.getCharCode(e); 2428 2429 if (dataItem == key) { 2430 keyEvent.fire(key, e); 2431 break; 2432 } 2433 } 2434 } else { 2435 key = Event.getCharCode(e); 2436 if (keys == key ) { 2437 keyEvent.fire(key, e); 2438 } 2439 } 2440 } 2441 } 2442 2443 /** 2444 * Enables the KeyListener by attaching the DOM event listeners to the 2445 * target DOM element 2446 * @method enable 2447 */ 2448 this.enable = function() { 2449 if (! this.enabled) { 2450 Event.on(attachTo, event, handleKeyPress); 2451 this.enabledEvent.fire(keyData); 2452 } 2453 /** 2454 * Boolean indicating the enabled/disabled state of the Tooltip 2455 * @property enabled 2456 * @type Boolean 2457 */ 2458 this.enabled = true; 2459 }; 2460 2461 /** 2462 * Disables the KeyListener by removing the DOM event listeners from the 2463 * target DOM element 2464 * @method disable 2465 */ 2466 this.disable = function() { 2467 if (this.enabled) { 2468 Event.removeListener(attachTo, event, handleKeyPress); 2469 this.disabledEvent.fire(keyData); 2470 } 2471 this.enabled = false; 2472 }; 2473 2474 /** 2475 * Returns a String representation of the object. 2476 * @method toString 2477 * @return {String} The string representation of the KeyListener 2478 */ 2479 this.toString = function() { 2480 return "KeyListener [" + keyData.keys + "] " + attachTo.tagName + 2481 (attachTo.id ? "[" + attachTo.id + "]" : ""); 2482 }; 2483 2484 }; 2485 2486 var KeyListener = YAHOO.util.KeyListener; 2487 2488 /** 2489 * Constant representing the DOM "keydown" event. 2490 * @property YAHOO.util.KeyListener.KEYDOWN 2491 * @static 2492 * @final 2493 * @type String 2494 */ 2495 KeyListener.KEYDOWN = "keydown"; 2496 2497 /** 2498 * Constant representing the DOM "keyup" event. 2499 * @property YAHOO.util.KeyListener.KEYUP 2500 * @static 2501 * @final 2502 * @type String 2503 */ 2504 KeyListener.KEYUP = "keyup"; 2505 2506 /** 2507 * keycode constants for a subset of the special keys 2508 * @property KEY 2509 * @static 2510 * @final 2511 */ 2512 KeyListener.KEY = { 2513 ALT : 18, 2514 BACK_SPACE : 8, 2515 CAPS_LOCK : 20, 2516 CONTROL : 17, 2517 DELETE : 46, 2518 DOWN : 40, 2519 END : 35, 2520 ENTER : 13, 2521 ESCAPE : 27, 2522 HOME : 36, 2523 LEFT : 37, 2524 META : 224, 2525 NUM_LOCK : 144, 2526 PAGE_DOWN : 34, 2527 PAGE_UP : 33, 2528 PAUSE : 19, 2529 PRINTSCREEN : 44, 2530 RIGHT : 39, 2531 SCROLL_LOCK : 145, 2532 SHIFT : 16, 2533 SPACE : 32, 2534 TAB : 9, 2535 UP : 38 2536 }; 2537 2538 })(); 2539 YAHOO.register("event", YAHOO.util.Event, {version: "2.9.0", build: "2800"}); 2540 2541 YAHOO.util.Event.generateId = function(el) { 2542 if (!el.id) { 2543 el.id = Y.guid(); 2544 } 2545 return el.id; 2546 }; 2547 YAHOO.util.Event._load(); 2548 }, '2.9.0' ,{"requires": ["yui2-yahoo"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |