Your IP : 18.219.40.177


Current Path : /usr/local/mgr5/skins/orion/src/
Upload File :
Current File : //usr/local/mgr5/skins/orion/src/eventmgr.js

// Event manager
//@todo unit test
var EventMgr = {

  o: function() {
    'use strict';
    return $('body');
  },

  hooks: {},

  isTouch: function() {
    return (navigator.userAgent.match(/Android/i) ||
     navigator.userAgent.match(/webOS/i) ||
     navigator.userAgent.match(/iPhone/i) ||
     navigator.userAgent.match(/iPad/i) ||
     navigator.userAgent.match(/iPod/i) ||
     navigator.userAgent.match(/BlackBerry/i) ||
     navigator.userAgent.match(/Windows Phone/i));
  },

  touchEvents: {},

  touchData: {},
  /**
   * bind custom event
   * @this {EventMgr} EventMgr object
   */
  bind: function(event, callback) {
    'use strict';
    var events = event.split(','),
        l = event.length;
    while (l--) {
      this.o().on(events[l], callback);
    }
  },
  /**
   * bind custom event for one time
   * @this {EventMgr} EventMgr object
   */
  one: function(event, callback, data) {
    'use strict';
    var events = event.split(','),
        l = event.length;
    while (l--) {
      this.o().one(events[l], data, callback);
    }
  },
  /**
   * wrapper for jQuery.one
   */
  oone: function(object, event, callback) {
    'use strict';
    if (typeof object === 'string') {
      $(object).one(event, callback);
    } else {
      object.one(event, callback);
    }
  },
  /**
   * wrapper for jQuery.obind
   */
  obind: function(object, event, callback) {
    'use strict';
    var touch;
    if (event === 'click' &&
         this.isTouch() &&
         typeof object === 'string') {
      event = 'touchstart';
      touch = true;
    }
    if (!touch) {
      if (typeof object === 'string') {
        $(object).on(event, callback);
      } else {
        object.on(event, callback);
      }
    } else {
      var data = {
          eventMgr: this,
          cb: callback
      };
      if (typeof object === 'string') {
        data.innerSelect = object;
        $(object).on(event, data, this.touchStart);
       // $(object).on('touchmove', data, this.touchMove);
        $(object).on('touchend', data, this.touchEnd);
      }
    }
  },

  /**
   * wrapper for jQuery.on
   * */
  on: function(outObject, innerSelect, event, callback) {
    'use strict';
    var touch = false;
    if (event === 'click' && this.isTouch()) {
      event = 'touchstart';
      touch = true;
    }
    if (!touch) {
      if (typeof outObject === 'string') {
        $(outObject).on(event, innerSelect, callback);
      } else {
        outObject.on(event, innerSelect, callback);
      }
    } else {
        var data = {
          innerSelect: innerSelect,
          eventMgr: this,
          cb: callback
        };
       if (typeof outObject === 'string') {
        $(outObject).on(event, innerSelect, data, this.touchStart);
        //$(outObject).on('touchmove', innerSelect, data, this.touchMove);
        $(outObject).on('touchend', innerSelect, data, this.touchEnd);
      } else {
        outObject.on(event, innerSelect, data, this.touchStart);
        //outObject.on('touchmove', innerSelect, data, this.touchMove);
        outObject.on('touchend', innerSelect, data, this.touchEnd);
      }
    }
  },
  /**
   * allow hooks for original events
   * @this {EventMgr} EventMgr object
   */
  onwithdata: function(outObject, innerSelect, event, customEvent, callback) {
    'use strict';
    var data = {
      targetEvent: customEvent,
      targetCallback: callback,
      eventMgr: this,
      innerSelect: innerSelect,
      withData: true
    },
    touch = false;

    if (event === 'click' && this.isTouch()) {
      event = 'touchstart';
      touch = true;
    }
    if (!touch) {
      if (typeof outObject === 'string') {
        $(outObject).on(event, innerSelect, data, this.onwithdataHandler);
      } else {
        outObject.on(event, innerSelect, data, this.onwithdataHandler);
      }
    } else {
      if (typeof outObject === 'string') {
        $(outObject).on(event, innerSelect, data, this.touchStart);
        //$(outObject).on('touchmove', innerSelect, data, this.touchMove);
        $(outObject).on('touchend', innerSelect, data, this.touchEnd);
      } else {
        outObject.on(event, innerSelect, data, this.touchStart);
        //outObject.on('touchmove', innerSelect, data, this.touchMove);
        outObject.on('touchend', innerSelect, data, this.touchEnd);
      }
    }
  },

  touchStart: function(e) {
    e.preventDefault();
    var selector = e.data.innerSelect,
        em = e.data.eventMgr;
    em.touchEvents[selector] = true;
  },

  touchMove: function(e) {
    var selector = e.data.innerSelect,
        em = e.data.eventMgr;
    em.touchEvents[selector] = false;
  },

  touchEnd: function(e) {
    var selector = e.data.innerSelect,
        em = e.data.eventMgr;
    if (em.touchEvents[selector]) {
      if (e.data.withData) {
        em.onwithdataHandler.apply(this, [e]);
        em.touchEvents[selector] = false;
      } else {
        e.data.cb.apply(this, [e]);
        em.touchEvents[selector] = false;
      }
    }
  },

  /**
   * handler for onwithdata
   * @this {HTMLNode} HTMLNode
   */
  onwithdataHandler: function(e) {
    'use strict';
    var eventData = e.data,
        targetEvent = eventData.targetEvent,
        targetCallback = eventData.targetCallback,
        data = {},
        self = eventData.eventMgr;
    if (this) {
      data.tabId = this.getAttribute('data-tabid');
      data.elemId = this.getAttribute('data-elemid');
    }
    if (targetEvent) {
      if (self.hooks[targetEvent] && self.hooks[targetEvent].length > 0) {
        var l = self.hooks[targetEvent].length;
        while (l--) {
          if (typeof self.hooks[targetEvent][l] === 'function') {
            self.hooks[targetEvent][l].apply(window, [data]);
          }
        }
      }
    }
    if (typeof targetCallback === 'function') {
      targetCallback.apply(this, [e, data]);
    }
  },
  /**
   * wrapper for jQuery.off
   */
  off: function(outObject, event) {
    'use strict';
    if (typeof outObject === 'string') {
      $(outObject).off(event);
    } else {
      outObject.off(event);
    }
  },
  /**
   * unbind event
   * @this {EventMgr} EventMgr object
   */
  unbind: function(event, callback) {
    'use strict';
    var events = event.split(','),
        l = event.length;
    while (l--) {
      this.o().off(events[l], callback);
    }
  },
  /**
   * wrapper for jQuery.trigger
   * @this {EventMgr} EventMgr object
   */
  trigger: function(event, data, delay) {
    'use strict';
    if (delay) {
      setTimeout(function(self) { return function() {
        if (typeof event !== 'string') {
          console.log('event !== string in trigger', event, data);
          event = String(event);
        }
        self.o().trigger(event, data);};
      } (this), delay);
    } else {
      if (this.hooks[event] && this.hooks[event].length > 0) {
        var l = this.hooks[event].length;
        while (l--) {
          if (typeof this.hooks[event][l] === 'function') {
            this.hooks[event][l].apply(window, [data]);
          }
        }
      }
      if (typeof event !== 'string') {
        console.log('event !== string in trigger', event, data);
        event = String(event);
      }
      this.o().trigger(event, data);
    }
    if (this.triggerStack[event]) {
      this.triggerStackHandler(event, data);
    }
  },
  triggerStack: {},
  /**
   * add to trigger stack
   * @param {String} event event name
   * @param {function} func function for call
   * @param {number} priority stack call order
   * @this {EventMgr} EventMgr object
   */
  addToTriggerStack: function(event, func, priority) {
    if (!this.triggerStack[event]) {
      this.triggerStack[event] = [];
    }
    this.triggerStack[event].push({
        func: func,
        priority: priority
    });
    this.triggerStack[event].sort(this.prioritySort);
  },

  triggerStackHandler: function(event, data) {
    if (this.triggerStack[event]) {
      var l = this.triggerStack[event].length;
      for (var i = 0; i < l; i++) {
         if (typeof this.triggerStack[event][i].func === 'function') {
           //break if return true
           if (this.triggerStack[event][i].func.apply(window, [{}, data])) {
            break;
           }
         }
      }
    }
  },
  prioritySort: function(a, b) {
    return a.priority - b.priority;
  },
  /**
   * add hook for custom event
   * @this {EventMgr} EventMgr object
   */
  addHook: function(event, callback) {
    'use strict';
    var events = event.split(','),
        l = event.length;
    while (l--) {
      if (this.hooks[events[l]]) {
        this.hooks[events[l]].push(callback);
      } else {
        this.hooks[events[l]] = [];
        this.hooks[events[l]].push(callback);
      }
    }
  },
  /**
   * remove hook
   * @this {EventMgr} EventMgr object
   */
  deleteHook: function(event, callback) {
    'use strict';
    if (this.hooks[event]) {
      var len = this.hooks[event].length - 1,
          ar = this.hooks[event];

      for (var i = len; i <= 0; i--) {
        if (ar(i) === callback) {
          ar.slice(i, i);
        }
      }
    }
  }
};