[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 Y.log("Deferring creation of " + type + " delegate until render.", "info", "widget"); 200 201 this._uiEvtsInitQueue = queue[sType] = 1; 202 203 this.after(RENDER, function() { 204 this._createUIEvent(sType); 205 delete this._uiEvtsInitQueue[sType]; 206 }); 207 } 208 }, 209 210 // Override of "on" from Base to facilitate the firing of Widget events 211 // based on DOM events of the same name/type (e.g. "click", "mouseover"). 212 // Temporary solution until we have the ability to listen to when 213 // someone adds an event listener (bug 2528230) 214 on: function (type) { 215 this._initUIEvent(type); 216 return Widget.superclass.on.apply(this, arguments); 217 }, 218 219 // Override of "publish" from Base to facilitate the firing of Widget events 220 // based on DOM events of the same name/type (e.g. "click", "mouseover"). 221 // Temporary solution until we have the ability to listen to when 222 // someone publishes an event (bug 2528230) 223 publish: function (type, config) { 224 var sType = this._getUIEvent(type); 225 if (sType && config && config.defaultFn) { 226 this._initUIEvent(sType); 227 } 228 return Widget.superclass.publish.apply(this, arguments); 229 } 230 231 }, true); // overwrite existing EventTarget methods 232 233 234 }, '3.17.2', {"requires": ["node-event-delegate", "widget-base"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |