| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * @fileoverview This contains an implementation of the EventTarget interface |
| * as defined by DOM Level 2 Events. |
| */ |
| base.exportTo('base', function() { |
| |
| /** |
| * Creates a new EventTarget. This class implements the DOM level 2 |
| * EventTarget interface and can be used wherever those are used. |
| * @constructor |
| */ |
| function EventTarget() { |
| } |
| |
| EventTarget.prototype = { |
| |
| /** |
| * Adds an event listener to the target. |
| * @param {string} type The name of the event. |
| * @param {!Function|{handleEvent:Function}} handler The handler for the |
| * event. This is called when the event is dispatched. |
| */ |
| addEventListener: function(type, handler) { |
| if (!this.listeners_) |
| this.listeners_ = Object.create(null); |
| if (!(type in this.listeners_)) { |
| this.listeners_[type] = [handler]; |
| } else { |
| var handlers = this.listeners_[type]; |
| if (handlers.indexOf(handler) < 0) |
| handlers.push(handler); |
| } |
| }, |
| |
| /** |
| * Removes an event listener from the target. |
| * @param {string} type The name of the event. |
| * @param {!Function|{handleEvent:Function}} handler The handler for the |
| * event. |
| */ |
| removeEventListener: function(type, handler) { |
| if (!this.listeners_) |
| return; |
| if (type in this.listeners_) { |
| var handlers = this.listeners_[type]; |
| var index = handlers.indexOf(handler); |
| if (index >= 0) { |
| // Clean up if this was the last listener. |
| if (handlers.length == 1) |
| delete this.listeners_[type]; |
| else |
| handlers.splice(index, 1); |
| } |
| } |
| }, |
| |
| /** |
| * Dispatches an event and calls all the listeners that are listening to |
| * the type of the event. |
| * @param {!cr.event.Event} event The event to dispatch. |
| * @return {boolean} Whether the default action was prevented. If someone |
| * calls preventDefault on the event object then this returns false. |
| */ |
| dispatchEvent: function(event) { |
| if (!this.listeners_) |
| return true; |
| |
| // Since we are using DOM Event objects we need to override some of the |
| // properties and methods so that we can emulate this correctly. |
| var self = this; |
| event.__defineGetter__('target', function() { |
| return self; |
| }); |
| event.preventDefault = function() { |
| this.returnValue = false; |
| }; |
| |
| var type = event.type; |
| var prevented = 0; |
| if (type in this.listeners_) { |
| // Clone to prevent removal during dispatch |
| var handlers = this.listeners_[type].concat(); |
| for (var i = 0, handler; handler = handlers[i]; i++) { |
| if (handler.handleEvent) |
| prevented |= handler.handleEvent.call(handler, event) === false; |
| else |
| prevented |= handler.call(this, event) === false; |
| } |
| } |
| |
| return !prevented && event.returnValue; |
| } |
| }; |
| |
| // Export |
| return { |
| EventTarget: EventTarget |
| }; |
| }); |