blob: 190cc26046c3826417220d59c3ffec23c23b3d3e [file] [log] [blame]
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview This file contains a class to provide a unified mechanism for
* CLICK and enter KEYDOWN events. This provides better accessibility by
* providing the given functionality to a keyboard user which is otherwise
* would be available only via a mouse click.
*
* If there is an existing CLICK listener or planning to be added as below -
*
* <code>this.eventHandler_.listen(el, CLICK, this.onClick_);<code>
*
* it can be replaced with an ACTION listener as follows:
*
* <code>this.eventHandler_.listen(
* new goog.events.ActionHandler(el),
* ACTION,
* this.onAction_);<code>
*
*/
goog.provide('goog.events.ActionEvent');
goog.provide('goog.events.ActionHandler');
goog.provide('goog.events.ActionHandler.EventType');
goog.provide('goog.events.BeforeActionEvent');
goog.require('goog.events');
goog.require('goog.events.BrowserEvent');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
goog.require('goog.events.KeyCodes');
goog.require('goog.userAgent');
/**
* A wrapper around an element that you want to listen to ACTION events on.
* @param {Element|Document} element The element or document to listen on.
* @constructor
* @extends {goog.events.EventTarget}
* @final
*/
goog.events.ActionHandler = function(element) {
goog.events.EventTarget.call(this);
/**
* This is the element that we will listen to events on.
* @type {Element|Document}
* @private
*/
this.element_ = element;
goog.events.listen(element, goog.events.ActionHandler.KEY_EVENT_TYPE_,
this.handleKeyDown_, false, this);
goog.events.listen(element, goog.events.EventType.CLICK,
this.handleClick_, false, this);
};
goog.inherits(goog.events.ActionHandler, goog.events.EventTarget);
/**
* Enum type for the events fired by the action handler
* @enum {string}
*/
goog.events.ActionHandler.EventType = {
ACTION: 'action',
BEFOREACTION: 'beforeaction'
};
/**
* Key event type to listen for.
* @type {string}
* @private
*/
goog.events.ActionHandler.KEY_EVENT_TYPE_ = goog.userAgent.GECKO ?
goog.events.EventType.KEYPRESS :
goog.events.EventType.KEYDOWN;
/**
* Handles key press events.
* @param {!goog.events.BrowserEvent} e The key press event.
* @private
*/
goog.events.ActionHandler.prototype.handleKeyDown_ = function(e) {
if (e.keyCode == goog.events.KeyCodes.ENTER ||
goog.userAgent.WEBKIT && e.keyCode == goog.events.KeyCodes.MAC_ENTER) {
this.dispatchEvents_(e);
}
};
/**
* Handles mouse events.
* @param {!goog.events.BrowserEvent} e The click event.
* @private
*/
goog.events.ActionHandler.prototype.handleClick_ = function(e) {
this.dispatchEvents_(e);
};
/**
* Dispatches BeforeAction and Action events to the element
* @param {!goog.events.BrowserEvent} e The event causing dispatches.
* @private
*/
goog.events.ActionHandler.prototype.dispatchEvents_ = function(e) {
var beforeActionEvent = new goog.events.BeforeActionEvent(e);
// Allow application specific logic here before the ACTION event.
// For example, Gmail uses this event to restore keyboard focus
if (!this.dispatchEvent(beforeActionEvent)) {
// If the listener swallowed the BEFOREACTION event, don't dispatch the
// ACTION event.
return;
}
// Wrap up original event and send it off
var actionEvent = new goog.events.ActionEvent(e);
try {
this.dispatchEvent(actionEvent);
} finally {
// Stop propagating the event
e.stopPropagation();
}
};
/** @override */
goog.events.ActionHandler.prototype.disposeInternal = function() {
goog.events.ActionHandler.superClass_.disposeInternal.call(this);
goog.events.unlisten(this.element_, goog.events.ActionHandler.KEY_EVENT_TYPE_,
this.handleKeyDown_, false, this);
goog.events.unlisten(this.element_, goog.events.EventType.CLICK,
this.handleClick_, false, this);
delete this.element_;
};
/**
* This class is used for the goog.events.ActionHandler.EventType.ACTION event.
* @param {!goog.events.BrowserEvent} browserEvent Browser event object.
* @constructor
* @extends {goog.events.BrowserEvent}
* @final
*/
goog.events.ActionEvent = function(browserEvent) {
goog.events.BrowserEvent.call(this, browserEvent.getBrowserEvent());
this.type = goog.events.ActionHandler.EventType.ACTION;
};
goog.inherits(goog.events.ActionEvent, goog.events.BrowserEvent);
/**
* This class is used for the goog.events.ActionHandler.EventType.BEFOREACTION
* event. BEFOREACTION gives a chance to the application so the keyboard focus
* can be restored back, if required.
* @param {!goog.events.BrowserEvent} browserEvent Browser event object.
* @constructor
* @extends {goog.events.BrowserEvent}
* @final
*/
goog.events.BeforeActionEvent = function(browserEvent) {
goog.events.BrowserEvent.call(this, browserEvent.getBrowserEvent());
this.type = goog.events.ActionHandler.EventType.BEFOREACTION;
};
goog.inherits(goog.events.BeforeActionEvent, goog.events.BrowserEvent);