1 /**
  2  * Olives http://flams.github.com/olives
  3  * The MIT License (MIT)
  4  * Copyright (c) 2012-2014 Olivier Scherrer <pode.fr@gmail.com> - Olivier Wietrich <olivier.wietrich@gmail.com>
  5  */
  6 "use strict";
  7 
  8 var DomUtils = require("./DomUtils");
  9 
 10 /**
 11 * @class
 12 * @requires Utils
 13 * Event plugin adds events listeners to DOM nodes.
 14 * It can also delegate the event handling to a parent dom node
 15 * The event plugin constructor.
 16 * ex: new EventPlugin({method: function(){} ...}, false);
 17 * @param {Object} the object that has the event handling methods
 18 * @param {Boolean} $isMobile if the event handler has to map with touch events
 19 */
 20 module.exports = function EventPluginConstructor($parent, $isMobile) {
 21 
 22     /**
 23      * The parent callback
 24      * @private
 25      */
 26     var _parent = null,
 27 
 28     /**
 29      * The mapping object.
 30      * @private
 31      */
 32     _map = {
 33         "mousedown" : "touchstart",
 34         "mouseup" : "touchend",
 35         "mousemove" : "touchmove"
 36     },
 37 
 38     /**
 39      * Is touch device.
 40      * @private
 41      */
 42     _isMobile = !!$isMobile;
 43 
 44     /**
 45      * Add mapped event listener (for testing purpose).
 46      * @private
 47      */
 48     this.addEventListener = function addEventListener(node, event, callback, useCapture) {
 49         node.addEventListener(this.map(event), callback, !!useCapture);
 50     };
 51 
 52     /**
 53      * Listen to DOM events.
 54      * @param {Object} node DOM node
 55      * @param {String} name event's name
 56      * @param {String} listener callback's name
 57      * @param {String} useCapture string
 58      */
 59     this.listen = function listen(node, name, listener, useCapture) {
 60         this.addEventListener(node, name, function(e){
 61             _parent[listener].call(_parent, e, node);
 62         }, !!useCapture);
 63     };
 64 
 65     /**
 66      * Delegate the event handling to a parent DOM element
 67      * @param {Object} node DOM node
 68      * @param {String} selector CSS3 selector to the element that listens to the event
 69      * @param {String} name event's name
 70      * @param {String} listener callback's name
 71      * @param {String} useCapture string
 72      */
 73     this.delegate = function delegate(node, selector, name, listener, useCapture) {
 74         this.addEventListener(node, name, function(event){
 75             if (DomUtils.matches(node, selector, event.target)) {
 76                 _parent[listener].call(_parent, event, node);
 77             }
 78         }, !!useCapture);
 79     };
 80 
 81     /**
 82      * Get the parent object.
 83      * @return {Object} the parent object
 84      */
 85     this.getParent = function getParent() {
 86         return _parent;
 87     };
 88 
 89     /**
 90      * Set the parent object.
 91      * The parent object is an object which the functions are called by node listeners.
 92      * @param {Object} the parent object
 93      * @return true if object has been set
 94      */
 95     this.setParent = function setParent(parent) {
 96         if (parent instanceof Object){
 97             _parent = parent;
 98             return true;
 99         }
100         return false;
101     };
102 
103     /**
104      * Get event mapping.
105      * @param {String} event's name
106      * @return the mapped event's name
107      */
108     this.map = function map(name) {
109         return _isMobile ? (_map[name] || name) : name;
110     };
111 
112     /**
113      * Set event mapping.
114      * @param {String} event's name
115      * @param {String} event's value
116      * @return true if mapped
117      */
118     this.setMap = function setMap(name, value) {
119         if (typeof name == "string" &&
120             typeof value == "string") {
121             _map[name] = value;
122             return true;
123         }
124         return false;
125     };
126 
127     //init
128     this.setParent($parent);
129 };