UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

268 lines (228 loc) 9.18 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2008 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Sebastian Werner (wpbasti) ************************************************************************ */ /** * This class is mainly a convenience wrapper for DOM elements to * qooxdoo's event system. * * @require(qx.event.dispatch.Direct) * @require(qx.event.dispatch.DomBubbling) * @require(qx.event.handler.Keyboard) * @require(qx.event.handler.Mouse) * @require(qx.event.handler.Element) * @require(qx.event.handler.Appear) * @require(qx.event.handler.Touch) * @require(qx.event.handler.Offline) * @require(qx.event.handler.Input) * @require(qx.event.handler.Pointer) * @require(qx.event.handler.Gesture) */ qx.Class.define("qx.bom.Element", { /* ***************************************************************************** STATICS ***************************************************************************** */ statics : { /* --------------------------------------------------------------------------- EVENTS --------------------------------------------------------------------------- */ /** * Add an event listener to a DOM element. The event listener is passed an * instance of {@link Event} containing all relevant information * about the event as parameter. * * @param element {Element} DOM element to attach the event on. * @param type {String} Name of the event e.g. "click", "keydown", ... * @param listener {Function} Event listener function * @param self {Object ? null} Reference to the 'this' variable inside * the event listener. When not given, the corresponding dispatcher * usually falls back to a default, which is the target * by convention. Note this is not a strict requirement, i.e. * custom dispatchers can follow a different strategy. * @param capture {Boolean} Whether to attach the event to the * capturing phase or the bubbling phase of the event. The default is * to attach the event handler to the bubbling phase. * @return {String} An opaque id, which can be used to remove the event listener * using the {@link #removeListenerById} method. */ addListener : function(element, type, listener, self, capture) { return qx.event.Registration.addListener(element, type, listener, self, capture); }, /** * Remove an event listener from a from DOM node. * * Note: All registered event listeners will automatically be removed from * the DOM at page unload so it is not necessary to detach events yourself. * * @param element {Element} DOM Element * @param type {String} Name of the event * @param listener {Function} The pointer to the event listener * @param self {Object ? null} Reference to the 'this' variable inside * the event listener. * @param capture {Boolean} Whether to remove the event listener of * the bubbling or of the capturing phase. * @return {Boolean} <code>true</code> if the listener was removed */ removeListener : function(element, type, listener, self, capture) { return qx.event.Registration.removeListener(element, type, listener, self, capture); }, /** * Removes an event listener from an event target by an id returned by * {@link #addListener} * * @param target {Object} The event target * @param id {String} The id returned by {@link #addListener} * @return {Boolean} <code>true</code> if the listener was removed */ removeListenerById : function(target, id) { return qx.event.Registration.removeListenerById(target, id); }, /** * Check whether there are one or more listeners for an event type * registered at the element. * * @param element {Element} DOM element * @param type {String} The event type * @param capture {Boolean ? false} Whether to check for listeners of * the bubbling or of the capturing phase. * @return {Boolean} Whether the element has event listeners of the given type. */ hasListener : function(element, type, capture) { return qx.event.Registration.hasListener(element, type, capture); }, /** * Focuses the given element. The element needs to have a positive <code>tabIndex</code> value. * * @param element {Element} DOM element to focus */ focus : function(element) { qx.event.Registration.getManager(element).getHandler(qx.event.handler.Focus).focus(element); }, /** * Blurs the given element * * @param element {Element} DOM element to blur */ blur : function(element) { qx.event.Registration.getManager(element).getHandler(qx.event.handler.Focus).blur(element); }, /** * Activates the given element. The active element receives all key board events. * * @param element {Element} DOM element to focus */ activate : function(element) { qx.event.Registration.getManager(element).getHandler(qx.event.handler.Focus).activate(element); }, /** * Deactivates the given element. The active element receives all key board events. * * @param element {Element} DOM element to focus */ deactivate : function(element) { qx.event.Registration.getManager(element).getHandler(qx.event.handler.Focus).deactivate(element); }, /** * Captures the given element * * @param element {Element} DOM element to capture * @param containerCapture {Boolean?true} If true all events originating in * the container are captured. If false events originating in the container * are not captured. */ capture : function(element, containerCapture) { qx.event.Registration.getManager(element).getDispatcher(qx.event.dispatch.MouseCapture).activateCapture(element, containerCapture); }, /** * Releases the given element (from a previous {@link #capture} call) * * @param element {Element} DOM element to release */ releaseCapture : function(element) { qx.event.Registration.getManager(element).getDispatcher(qx.event.dispatch.MouseCapture).releaseCapture(element); }, /* --------------------------------------------------------------------------- UTILS --------------------------------------------------------------------------- */ /** * Clone given DOM element. May optionally clone all attached * events (recursively) as well. * * @param element {Element} Element to clone * @param events {Boolean?false} Whether events should be copied as well * @return {Element} The copied element */ clone : function(element, events) { var clone; if (events || ((qx.core.Environment.get("engine.name") == "mshtml") && !qx.xml.Document.isXmlDocument(element))) { var mgr = qx.event.Registration.getManager(element); var all = qx.dom.Hierarchy.getDescendants(element); all.push(element); } // IE copies events bound via attachEvent() when // using cloneNode(). Calling detachEvent() on the // clone will also remove the events from the original. // // In order to get around this, we detach all locally // attached events first, do the cloning and recover // them afterwards again. if ((qx.core.Environment.get("engine.name") == "mshtml")) { for (var i=0, l=all.length; i<l; i++) { mgr.toggleAttachedEvents(all[i], false); } } // Do the native cloning var clone = element.cloneNode(true); // Recover events on original elements if ((qx.core.Environment.get("engine.name") == "mshtml")) { for (var i=0, l=all.length; i<l; i++) { mgr.toggleAttachedEvents(all[i], true); } } // Attach events from original element if (events === true) { // Produce recursive list of elements in the clone var cloneAll = qx.dom.Hierarchy.getDescendants(clone); cloneAll.push(clone); // Process all elements and copy over listeners var eventList, cloneElem, origElem, eventEntry; for (var i=0, il=all.length; i<il; i++) { origElem = all[i]; eventList = mgr.serializeListeners(origElem); if (eventList.length > 0) { cloneElem = cloneAll[i]; for (var j=0, jl=eventList.length; j<jl; j++) { eventEntry = eventList[j]; mgr.addListener(cloneElem, eventEntry.type, eventEntry.handler, eventEntry.self, eventEntry.capture); } } } } // Finally return the clone return clone; } } });