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