[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/widget-uievents/ -> widget-uievents.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('widget-uievents', function (Y, NAME) {
   9  
  10  /**
  11   * Support for Widget UI Events (Custom Events fired by the widget, which wrap the underlying DOM events - e.g. widget:click, widget:mousedown)
  12   *
  13   * @module widget
  14   * @submodule widget-uievents
  15   */
  16  
  17  var BOUNDING_BOX = "boundingBox",
  18      Widget = Y.Widget,
  19      RENDER = "render",
  20      L = Y.Lang,
  21      EVENT_PREFIX_DELIMITER = ":",
  22  
  23      //  Map of Node instances serving as a delegation containers for a specific
  24      //  event type to Widget instances using that delegation container.
  25      _uievts = Y.Widget._uievts = Y.Widget._uievts || {};
  26  
  27  Y.mix(Widget.prototype, {
  28  
  29      /**
  30       * Destructor logic for UI event infrastructure,
  31       * invoked during Widget destruction.
  32       *
  33       * @method _destroyUIEvents
  34       * @for Widget
  35       * @private
  36       */
  37      _destroyUIEvents: function() {
  38  
  39          var widgetGuid = Y.stamp(this, true);
  40  
  41          Y.each(_uievts, function (info, key) {
  42              if (info.instances[widgetGuid]) {
  43                  //  Unregister this Widget instance as needing this delegated
  44                  //  event listener.
  45                  delete info.instances[widgetGuid];
  46  
  47                  //  There are no more Widget instances using this delegated
  48                  //  event listener, so detach it.
  49  
  50                  if (Y.Object.isEmpty(info.instances)) {
  51                      info.handle.detach();
  52  
  53                      if (_uievts[key]) {
  54                          delete _uievts[key];
  55                      }
  56                  }
  57              }
  58          });
  59      },
  60  
  61      /**
  62       * Map of DOM events that should be fired as Custom Events by the
  63       * Widget instance.
  64       *
  65       * @property UI_EVENTS
  66       * @for Widget
  67       * @type Object
  68       */
  69      UI_EVENTS: Y.Node.DOM_EVENTS,
  70  
  71      /**
  72       * Returns the node on which to bind delegate listeners.
  73       *
  74       * @method _getUIEventNode
  75       * @for Widget
  76       * @protected
  77       */
  78      _getUIEventNode: function () {
  79          return this.get(BOUNDING_BOX);
  80      },
  81  
  82      /**
  83       * Binds a delegated DOM event listener of the specified type to the
  84       * Widget's outtermost DOM element to facilitate the firing of a Custom
  85       * Event of the same type for the Widget instance.
  86       *
  87       * @method _createUIEvent
  88       * @for Widget
  89       * @param type {String} String representing the name of the event
  90       * @private
  91       */
  92      _createUIEvent: function (type) {
  93  
  94          var uiEvtNode = this._getUIEventNode(),
  95              key = (Y.stamp(uiEvtNode) + type),
  96              info = _uievts[key],
  97              handle;
  98  
  99          //  For each Node instance: Ensure that there is only one delegated
 100          //  event listener used to fire Widget UI events.
 101  
 102          if (!info) {
 103  
 104              handle = uiEvtNode.delegate(type, function (evt) {
 105  
 106                  var widget = Widget.getByNode(this);
 107  
 108                  // Widget could be null if node instance belongs to
 109                  // another Y instance.
 110  
 111                  if (widget) {
 112                      if (widget._filterUIEvent(evt)) {
 113                          widget.fire(evt.type, { domEvent: evt });
 114                      }
 115                  }
 116  
 117              }, "." + Y.Widget.getClassName());
 118  
 119              _uievts[key] = info = { instances: {}, handle: handle };
 120          }
 121  
 122          //  Register this Widget as using this Node as a delegation container.
 123          info.instances[Y.stamp(this)] = 1;
 124      },
 125  
 126      /**
 127       * This method is used to determine if we should fire
 128       * the UI Event or not. The default implementation makes sure
 129       * that for nested delegates (nested unrelated widgets), we don't
 130       * fire the UI event listener more than once at each level.
 131       *
 132       * <p>For example, without the additional filter, if you have nested
 133       * widgets, each widget will have a delegate listener. If you
 134       * click on the inner widget, the inner delegate listener's
 135       * filter will match once, but the outer will match twice
 136       * (based on delegate's design) - once for the inner widget,
 137       * and once for the outer.</p>
 138       *
 139       * @method _filterUIEvent
 140       * @for Widget
 141       * @param {DOMEventFacade} evt
 142       * @return {boolean} true if it's OK to fire the custom UI event, false if not.
 143       * @private
 144       *
 145       */
 146      _filterUIEvent: function(evt) {
 147          // Either it's hitting this widget's delegate container (and not some other widget's),
 148          // or the container it's hitting is handling this widget's ui events.
 149          return (evt.currentTarget.compareTo(evt.container) || evt.container.compareTo(this._getUIEventNode()));
 150      },
 151  
 152      /**
 153       * Determines if the specified event is a UI event.
 154       *
 155       * @private
 156       * @method _isUIEvent
 157       * @for Widget
 158       * @param type {String} String representing the name of the event
 159       * @return {String} Event Returns the name of the UI Event, otherwise
 160       * undefined.
 161       */
 162      _getUIEvent: function (type) {
 163  
 164          if (L.isString(type)) {
 165              var sType = this.parseType(type)[1],
 166                  iDelim,
 167                  returnVal;
 168  
 169              if (sType) {
 170                  // TODO: Get delimiter from ET, or have ET support this.
 171                  iDelim = sType.indexOf(EVENT_PREFIX_DELIMITER);
 172                  if (iDelim > -1) {
 173                      sType = sType.substring(iDelim + EVENT_PREFIX_DELIMITER.length);
 174                  }
 175  
 176                  if (this.UI_EVENTS[sType]) {
 177                      returnVal = sType;
 178                  }
 179              }
 180  
 181              return returnVal;
 182          }
 183      },
 184  
 185      /**
 186       * Sets up infrastructure required to fire a UI event.
 187       *
 188       * @private
 189       * @method _initUIEvent
 190       * @for Widget
 191       * @param type {String} String representing the name of the event
 192       * @return {String}
 193       */
 194      _initUIEvent: function (type) {
 195          var sType = this._getUIEvent(type),
 196              queue = this._uiEvtsInitQueue || {};
 197  
 198          if (sType && !queue[sType]) {
 199  
 200              this._uiEvtsInitQueue = queue[sType] = 1;
 201  
 202              this.after(RENDER, function() {
 203                  this._createUIEvent(sType);
 204                  delete this._uiEvtsInitQueue[sType];
 205              });
 206          }
 207      },
 208  
 209      //  Override of "on" from Base to facilitate the firing of Widget events
 210      //  based on DOM events of the same name/type (e.g. "click", "mouseover").
 211      //  Temporary solution until we have the ability to listen to when
 212      //  someone adds an event listener (bug 2528230)
 213      on: function (type) {
 214          this._initUIEvent(type);
 215          return Widget.superclass.on.apply(this, arguments);
 216      },
 217  
 218      //  Override of "publish" from Base to facilitate the firing of Widget events
 219      //  based on DOM events of the same name/type (e.g. "click", "mouseover").
 220      //  Temporary solution until we have the ability to listen to when
 221      //  someone publishes an event (bug 2528230)
 222      publish: function (type, config) {
 223          var sType = this._getUIEvent(type);
 224          if (sType && config && config.defaultFn) {
 225              this._initUIEvent(sType);
 226          }
 227          return Widget.superclass.publish.apply(this, arguments);
 228      }
 229  
 230  }, true); // overwrite existing EventTarget methods
 231  
 232  
 233  }, '3.17.2', {"requires": ["node-event-delegate", "widget-base"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1