diff -r 322d0feea350 -r 89ef5ed3c48b src/cm/media/js/lib/yui/yui_3.10.3/build/widget-uievents/widget-uievents.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui_3.10.3/build/widget-uievents/widget-uievents.js Tue Jul 16 14:29:46 2013 +0200 @@ -0,0 +1,233 @@ +/* +YUI 3.10.3 (build 2fb5187) +Copyright 2013 Yahoo! Inc. All rights reserved. +Licensed under the BSD License. +http://yuilibrary.com/license/ +*/ + +YUI.add('widget-uievents', function (Y, NAME) { + +/** + * Support for Widget UI Events (Custom Events fired by the widget, which wrap the underlying DOM events - e.g. widget:click, widget:mousedown) + * + * @module widget + * @submodule widget-uievents + */ + +var BOUNDING_BOX = "boundingBox", + Widget = Y.Widget, + RENDER = "render", + L = Y.Lang, + EVENT_PREFIX_DELIMITER = ":", + + // Map of Node instances serving as a delegation containers for a specific + // event type to Widget instances using that delegation container. + _uievts = Y.Widget._uievts = Y.Widget._uievts || {}; + +Y.mix(Widget.prototype, { + + /** + * Destructor logic for UI event infrastructure, + * invoked during Widget destruction. + * + * @method _destroyUIEvents + * @for Widget + * @private + */ + _destroyUIEvents: function() { + + var widgetGuid = Y.stamp(this, true); + + Y.each(_uievts, function (info, key) { + if (info.instances[widgetGuid]) { + // Unregister this Widget instance as needing this delegated + // event listener. + delete info.instances[widgetGuid]; + + // There are no more Widget instances using this delegated + // event listener, so detach it. + + if (Y.Object.isEmpty(info.instances)) { + info.handle.detach(); + + if (_uievts[key]) { + delete _uievts[key]; + } + } + } + }); + }, + + /** + * Map of DOM events that should be fired as Custom Events by the + * Widget instance. + * + * @property UI_EVENTS + * @for Widget + * @type Object + */ + UI_EVENTS: Y.Node.DOM_EVENTS, + + /** + * Returns the node on which to bind delegate listeners. + * + * @method _getUIEventNode + * @for Widget + * @protected + */ + _getUIEventNode: function () { + return this.get(BOUNDING_BOX); + }, + + /** + * Binds a delegated DOM event listener of the specified type to the + * Widget's outtermost DOM element to facilitate the firing of a Custom + * Event of the same type for the Widget instance. + * + * @method _createUIEvent + * @for Widget + * @param type {String} String representing the name of the event + * @private + */ + _createUIEvent: function (type) { + + var uiEvtNode = this._getUIEventNode(), + key = (Y.stamp(uiEvtNode) + type), + info = _uievts[key], + handle; + + // For each Node instance: Ensure that there is only one delegated + // event listener used to fire Widget UI events. + + if (!info) { + + handle = uiEvtNode.delegate(type, function (evt) { + + var widget = Widget.getByNode(this); + + // Widget could be null if node instance belongs to + // another Y instance. + + if (widget) { + if (widget._filterUIEvent(evt)) { + widget.fire(evt.type, { domEvent: evt }); + } + } + + }, "." + Y.Widget.getClassName()); + + _uievts[key] = info = { instances: {}, handle: handle }; + } + + // Register this Widget as using this Node as a delegation container. + info.instances[Y.stamp(this)] = 1; + }, + + /** + * This method is used to determine if we should fire + * the UI Event or not. The default implementation makes sure + * that for nested delegates (nested unrelated widgets), we don't + * fire the UI event listener more than once at each level. + * + *

For example, without the additional filter, if you have nested + * widgets, each widget will have a delegate listener. If you + * click on the inner widget, the inner delegate listener's + * filter will match once, but the outer will match twice + * (based on delegate's design) - once for the inner widget, + * and once for the outer.

+ * + * @method _filterUIEvent + * @for Widget + * @param {DOMEventFacade} evt + * @return {boolean} true if it's OK to fire the custom UI event, false if not. + * @private + * + */ + _filterUIEvent: function(evt) { + // Either it's hitting this widget's delegate container (and not some other widget's), + // or the container it's hitting is handling this widget's ui events. + return (evt.currentTarget.compareTo(evt.container) || evt.container.compareTo(this._getUIEventNode())); + }, + + /** + * Determines if the specified event is a UI event. + * + * @private + * @method _isUIEvent + * @for Widget + * @param type {String} String representing the name of the event + * @return {String} Event Returns the name of the UI Event, otherwise + * undefined. + */ + _getUIEvent: function (type) { + + if (L.isString(type)) { + var sType = this.parseType(type)[1], + iDelim, + returnVal; + + if (sType) { + // TODO: Get delimiter from ET, or have ET support this. + iDelim = sType.indexOf(EVENT_PREFIX_DELIMITER); + if (iDelim > -1) { + sType = sType.substring(iDelim + EVENT_PREFIX_DELIMITER.length); + } + + if (this.UI_EVENTS[sType]) { + returnVal = sType; + } + } + + return returnVal; + } + }, + + /** + * Sets up infrastructure required to fire a UI event. + * + * @private + * @method _initUIEvent + * @for Widget + * @param type {String} String representing the name of the event + * @return {String} + */ + _initUIEvent: function (type) { + var sType = this._getUIEvent(type), + queue = this._uiEvtsInitQueue || {}; + + if (sType && !queue[sType]) { + + this._uiEvtsInitQueue = queue[sType] = 1; + + this.after(RENDER, function() { + this._createUIEvent(sType); + delete this._uiEvtsInitQueue[sType]; + }); + } + }, + + // Override of "on" from Base to facilitate the firing of Widget events + // based on DOM events of the same name/type (e.g. "click", "mouseover"). + // Temporary solution until we have the ability to listen to when + // someone adds an event listener (bug 2528230) + on: function (type) { + this._initUIEvent(type); + return Widget.superclass.on.apply(this, arguments); + }, + + // Override of "publish" from Base to facilitate the firing of Widget events + // based on DOM events of the same name/type (e.g. "click", "mouseover"). + // Temporary solution until we have the ability to listen to when + // someone publishes an event (bug 2528230) + publish: function (type, config) { + var sType = this._getUIEvent(type); + if (sType && config && config.defaultFn) { + this._initUIEvent(sType); + } + return Widget.superclass.publish.apply(this, arguments); + } + +}, true); // overwrite existing EventTarget methods + + +}, '3.10.3', {"requires": ["node-event-delegate", "widget-base"]});