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