// Copyright 2005 Google Inc. // All Rights Reserved // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the // distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. /** * @fileoverview Class to create objects which want to handle multiple events * and have their listeners easily cleaned up via a dispose method. * * Example: *
* function Something() {
* goog.events.EventHandler.call(this);
*
* ... set up object ...
*
* // Add event listeners
* this.listen(this.starEl, 'click', this.handleStar);
* this.listen(this.headerEl, 'click', this.expand);
* this.listen(this.collapseEl, 'click', this.collapse);
* this.listen(this.infoEl, 'mouseover', this.showHover);
* this.listen(this.infoEl, 'mouseout', this.hideHover);
* }
* goog.inherits(Something, goog.events.EventHandler);
*
* Something.prototype.disposeInternal = function() {
* Something.superClass_.disposeInternal.call(this);
* goog.dom.removeNode(this.container);
* };
*
*
* // Then elsewhere:
*
* var activeSomething = null;
* function openSomething() {
* activeSomething = new Something();
* }
*
* function closeSomething() {
* if (activeSomething) {
* activeSomething.dispose(); // Remove event listeners
* activeSomething = null;
* }
* }
*
*
*/
goog.provide('goog.events.EventHandler');
goog.require('goog.Disposable');
goog.require('goog.events');
goog.require('goog.object');
goog.require('goog.structs.SimplePool');
/**
* Super class for objects that want to easily manage a number of event
* listeners. It allows a short cut to listen and also provides a quick way
* to remove all events listeners belonging to this object. It is optimized to
* use less objects if only one event is being listened to, but if that's the
* case, it may not be worth using the EventHandler anyway.
* @param {Object} opt_handler Object in who's scope to call the listeners.
* @constructor
* @extends {goog.Disposable}
*/
goog.events.EventHandler = function(opt_handler) {
this.handler_ = opt_handler;
};
goog.inherits(goog.events.EventHandler, goog.Disposable);
/**
* Initial count for the keyPool_
* @type {number}
*/
goog.events.EventHandler.KEY_POOL_INITIAL_COUNT = 0;
/**
* Max count for the keyPool_
* @type {number}
*/
goog.events.EventHandler.KEY_POOL_MAX_COUNT = 100;
/**
* SimplePool to cache the key object. This was implemented to make IE6
* performance better and removed an object allocation in the listen method
* when in steady state.
* @type {goog.structs.SimplePool}
* @private
*/
goog.events.EventHandler.keyPool_ = new goog.structs.SimplePool(
goog.events.EventHandler.KEY_POOL_INITIAL_COUNT,
goog.events.EventHandler.KEY_POOL_MAX_COUNT);
/**
* Keys for events that are being listened to. This is used once there are more
* than one event to listen to. If there is only one event to listen to, key_
* is used.
* @type {Object?}
* @private
*/
goog.events.EventHandler.keys_ = null;
/**
* Keys for event that is being listened to if only one event is being listened
* to. This is a performance optimization to avoid creating an extra object
* if not necessary.
* @type {string?}
* @private
*/
goog.events.EventHandler.key_ = null;
/**
* Listen to an event on a DOM node or EventTarget. If the function is ommitted
* then the EventHandler's handleEvent method will be used.
* @param {goog.events.EventTarget|EventTarget} src Event source.
* @param {string|Array.