diff -r d334a616c023 -r e16a97fb364a src/cm/media/js/lib/yui/yui3-3.15.0/build/widget-base/widget-base-debug.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui3-3.15.0/build/widget-base/widget-base-debug.js Mon Mar 10 15:19:48 2014 +0100 @@ -0,0 +1,1293 @@ +YUI.add('widget-base', function (Y, NAME) { + +/** + * Provides the base Widget class, with HTML Parser support + * + * @module widget + * @main widget + */ + +/** + * Provides the base Widget class + * + * @module widget + * @submodule widget-base + */ +var L = Y.Lang, + Node = Y.Node, + + ClassNameManager = Y.ClassNameManager, + + _getClassName = ClassNameManager.getClassName, + _getWidgetClassName, + + _toInitialCap = Y.cached(function(str) { + return str.substring(0, 1).toUpperCase() + str.substring(1); + }), + + // K-Weight, IE GC optimizations + CONTENT = "content", + VISIBLE = "visible", + HIDDEN = "hidden", + DISABLED = "disabled", + FOCUSED = "focused", + WIDTH = "width", + HEIGHT = "height", + BOUNDING_BOX = "boundingBox", + CONTENT_BOX = "contentBox", + PARENT_NODE = "parentNode", + OWNER_DOCUMENT = "ownerDocument", + AUTO = "auto", + SRC_NODE = "srcNode", + BODY = "body", + TAB_INDEX = "tabIndex", + ID = "id", + RENDER = "render", + RENDERED = "rendered", + DESTROYED = "destroyed", + STRINGS = "strings", + DIV = "
", + CHANGE = "Change", + LOADING = "loading", + + _UISET = "_uiSet", + + EMPTY_STR = "", + EMPTY_FN = function() {}, + + TRUE = true, + FALSE = false, + + UI, + ATTRS = {}, + UI_ATTRS = [VISIBLE, DISABLED, HEIGHT, WIDTH, FOCUSED, TAB_INDEX], + + WEBKIT = Y.UA.webkit, + + // Widget nodeid-to-instance map. + _instances = {}; + +/** + * A base class for widgets, providing: + * + * + * @param config {Object} Object literal specifying widget configuration properties. + * + * @class Widget + * @constructor + * @extends Base + */ +function Widget(config) { + Y.log('constructor called', 'life', 'widget'); + + // kweight + var widget = this, + parentNode, + render, + constructor = widget.constructor; + + widget._strs = {}; + widget._cssPrefix = constructor.CSS_PREFIX || _getClassName(constructor.NAME.toLowerCase()); + + // We need a config for HTML_PARSER to work. + config = config || {}; + + Widget.superclass.constructor.call(widget, config); + + render = widget.get(RENDER); + + if (render) { + // Render could be a node or boolean + if (render !== TRUE) { + parentNode = render; + } + widget.render(parentNode); + } +} + +/** + * Static property provides a string to identify the class. + *

+ * Currently used to apply class identifiers to the bounding box + * and to classify events fired by the widget. + *

+ * + * @property NAME + * @type String + * @static + */ +Widget.NAME = "widget"; + +/** + * Constant used to identify state changes originating from + * the DOM (as opposed to the JavaScript model). + * + * @property UI_SRC + * @type String + * @static + * @final + */ +UI = Widget.UI_SRC = "ui"; + +/** + * Static property used to define the default attribute + * configuration for the Widget. + * + * @property ATTRS + * @type Object + * @static + */ +Widget.ATTRS = ATTRS; + +// Trying to optimize kweight by setting up attrs this way saves about 0.4K min'd + +/** + * @attribute id + * @writeOnce + * @default Generated using guid() + * @type String + */ + +ATTRS[ID] = { + valueFn: "_guid", + writeOnce: TRUE +}; + +/** + * Flag indicating whether or not this Widget + * has been through the render lifecycle phase. + * + * @attribute rendered + * @readOnly + * @default false + * @type boolean + */ +ATTRS[RENDERED] = { + value:FALSE, + readOnly: TRUE +}; + +/** + * @attribute boundingBox + * @description The outermost DOM node for the Widget, used for sizing and positioning + * of a Widget as well as a containing element for any decorator elements used + * for skinning. + * @type String | Node + * @writeOnce + */ +ATTRS[BOUNDING_BOX] = { + valueFn:"_defaultBB", + setter: "_setBB", + writeOnce: TRUE +}; + +/** + * @attribute contentBox + * @description A DOM node that is a direct descendant of a Widget's bounding box that + * houses its content. + * @type String | Node + * @writeOnce + */ +ATTRS[CONTENT_BOX] = { + valueFn:"_defaultCB", + setter: "_setCB", + writeOnce: TRUE +}; + +/** + * @attribute tabIndex + * @description Number (between -32767 to 32767) indicating the widget's + * position in the default tab flow. The value is used to set the + * "tabIndex" attribute on the widget's bounding box. Negative values allow + * the widget to receive DOM focus programmatically (by calling the focus + * method), while being removed from the default tab flow. A value of + * null removes the "tabIndex" attribute from the widget's bounding box. + * @type Number + * @default null + */ +ATTRS[TAB_INDEX] = { + value: null, + validator: "_validTabIndex" +}; + +/** + * @attribute focused + * @description Boolean indicating if the Widget, or one of its descendants, + * has focus. + * @readOnly + * @default false + * @type boolean + */ +ATTRS[FOCUSED] = { + value: FALSE, + readOnly:TRUE +}; + +/** + * @attribute disabled + * @description Boolean indicating if the Widget should be disabled. The disabled implementation + * is left to the specific classes extending widget. + * @default false + * @type boolean + */ +ATTRS[DISABLED] = { + value: FALSE +}; + +/** + * @attribute visible + * @description Boolean indicating whether or not the Widget is visible. + * @default TRUE + * @type boolean + */ +ATTRS[VISIBLE] = { + value: TRUE +}; + +/** + * @attribute height + * @description String with units, or number, representing the height of the Widget. If a number is provided, + * the default unit, defined by the Widgets DEF_UNIT, property is used. + * @default EMPTY_STR + * @type {String | Number} + */ +ATTRS[HEIGHT] = { + value: EMPTY_STR +}; + +/** + * @attribute width + * @description String with units, or number, representing the width of the Widget. If a number is provided, + * the default unit, defined by the Widgets DEF_UNIT, property is used. + * @default EMPTY_STR + * @type {String | Number} + */ +ATTRS[WIDTH] = { + value: EMPTY_STR +}; + +/** + * @attribute strings + * @description Collection of strings used to label elements of the Widget's UI. + * @default null + * @type Object + */ +ATTRS[STRINGS] = { + value: {}, + setter: "_strSetter", + getter: "_strGetter" +}; + +/** + * Whether or not to render the widget automatically after init, and optionally, to which parent node. + * + * @attribute render + * @type boolean | Node + * @writeOnce + */ +ATTRS[RENDER] = { + value:FALSE, + writeOnce:TRUE +}; + +/** + * The css prefix which the static Widget.getClassName method should use when constructing class names + * + * @property CSS_PREFIX + * @type String + * @default Widget.NAME.toLowerCase() + * @private + * @static + */ +Widget.CSS_PREFIX = _getClassName(Widget.NAME.toLowerCase()); + +/** + * Generate a standard prefixed classname for the Widget, prefixed by the default prefix defined + * by the Y.config.classNamePrefix attribute used by ClassNameManager and + * Widget.NAME.toLowerCase() (e.g. "yui-widget-xxxxx-yyyyy", based on default values for + * the prefix and widget class name). + *

+ * The instance based version of this method can be used to generate standard prefixed classnames, + * based on the instances NAME, as opposed to Widget.NAME. This method should be used when you + * need to use a constant class name across different types instances. + *

+ * @method getClassName + * @param {String*} args* 0..n strings which should be concatenated, using the default separator defined by ClassNameManager, to create the class name + */ +Widget.getClassName = function() { + // arguments needs to be array'fied to concat + return _getClassName.apply(ClassNameManager, [Widget.CSS_PREFIX].concat(Y.Array(arguments), true)); +}; + +_getWidgetClassName = Widget.getClassName; + +/** + * Returns the widget instance whose bounding box contains, or is, the given node. + *

+ * In the case of nested widgets, the nearest bounding box ancestor is used to + * return the widget instance. + *

+ * @method getByNode + * @static + * @param node {Node | String} The node for which to return a Widget instance. If a selector + * string is passed in, which selects more than one node, the first node found is used. + * @return {Widget} Widget instance, or null if not found. + */ +Widget.getByNode = function(node) { + var widget, + widgetMarker = _getWidgetClassName(); + + node = Node.one(node); + if (node) { + node = node.ancestor("." + widgetMarker, true); + if (node) { + widget = _instances[Y.stamp(node, true)]; + } + } + + return widget || null; +}; + +Y.extend(Widget, Y.Base, { + + /** + * Returns a class name prefixed with the the value of the + * YUI.config.classNamePrefix attribute + the instances NAME property. + * Uses YUI.config.classNameDelimiter attribute to delimit the provided strings. + * e.g. + * + *
+     *    // returns "yui-slider-foo-bar", for a slider instance
+     *    var scn = slider.getClassName('foo','bar');
+     *
+     *    // returns "yui-overlay-foo-bar", for an overlay instance
+     *    var ocn = overlay.getClassName('foo','bar');
+     * 
+ *
+ * + * @method getClassName + * @param {String} [classnames*] One or more classname bits to be joined and prefixed + */ + getClassName: function () { + return _getClassName.apply(ClassNameManager, [this._cssPrefix].concat(Y.Array(arguments), true)); + }, + + /** + * Initializer lifecycle implementation for the Widget class. Registers the + * widget instance, and runs through the Widget's HTML_PARSER definition. + * + * @method initializer + * @protected + * @param config {Object} Configuration object literal for the widget + */ + initializer: function(config) { + Y.log('initializer called', 'life', 'widget'); + + var bb = this.get(BOUNDING_BOX); + + if (bb instanceof Node) { + this._mapInstance(Y.stamp(bb)); + } + + /** + * Notification event, which widget implementations can fire, when + * they change the content of the widget. This event has no default + * behavior and cannot be prevented, so the "on" or "after" + * moments are effectively equivalent (with on listeners being invoked before + * after listeners). + * + * @event widget:contentUpdate + * @preventable false + * @param {EventFacade} e The Event Facade + */ + }, + + /** + * Utility method used to add an entry to the boundingBox id to instance map. + * + * This method can be used to populate the instance with lazily created boundingBox Node references. + * + * @method _mapInstance + * @param {String} The boundingBox id + * @protected + */ + _mapInstance : function(id) { + _instances[id] = this; + }, + + /** + * Destructor lifecycle implementation for the Widget class. Purges events attached + * to the bounding box and content box, removes them from the DOM and removes + * the Widget from the list of registered widgets. + * + * @method destructor + * @protected + */ + destructor: function() { + Y.log('destructor called', 'life', 'widget'); + + var boundingBox = this.get(BOUNDING_BOX), + bbGuid; + + if (boundingBox instanceof Node) { + bbGuid = Y.stamp(boundingBox,true); + + if (bbGuid in _instances) { + delete _instances[bbGuid]; + } + + this._destroyBox(); + } + }, + + /** + *

+ * Destroy lifecycle method. Fires the destroy + * event, prior to invoking destructors for the + * class hierarchy. + * + * Overrides Base's implementation, to support arguments to destroy + *

+ *

+ * Subscribers to the destroy + * event can invoke preventDefault on the event object, to prevent destruction + * from proceeding. + *

+ * @method destroy + * @param destroyAllNodes {Boolean} If true, all nodes contained within the Widget are + * removed and destroyed. Defaults to false due to potentially high run-time cost. + * @return {Widget} A reference to this object + * @chainable + */ + destroy: function(destroyAllNodes) { + this._destroyAllNodes = destroyAllNodes; + return Widget.superclass.destroy.apply(this); + }, + + /** + * Removes and destroys the widgets rendered boundingBox, contentBox, + * and detaches bound UI events. + * + * @method _destroyBox + * @protected + */ + _destroyBox : function() { + + var boundingBox = this.get(BOUNDING_BOX), + contentBox = this.get(CONTENT_BOX), + deep = this._destroyAllNodes, + same; + + same = boundingBox && boundingBox.compareTo(contentBox); + + if (this.UI_EVENTS) { + this._destroyUIEvents(); + } + + this._unbindUI(boundingBox); + + if (contentBox) { + if (deep) { + contentBox.empty(); + } + contentBox.remove(TRUE); + } + + if (!same) { + if (deep) { + boundingBox.empty(); + } + boundingBox.remove(TRUE); + } + }, + + /** + * Establishes the initial DOM for the widget. Invoking this + * method will lead to the creating of all DOM elements for + * the widget (or the manipulation of existing DOM elements + * for the progressive enhancement use case). + *

+ * This method should only be invoked once for an initialized + * widget. + *

+ *

+ * It delegates to the widget specific renderer method to do + * the actual work. + *

+ * + * @method render + * @chainable + * @final + * @param parentNode {Object | String} Optional. The Node under which the + * Widget is to be rendered. This can be a Node instance or a CSS selector string. + *

+ * If the selector string returns more than one Node, the first node will be used + * as the parentNode. NOTE: This argument is required if both the boundingBox and contentBox + * are not currently in the document. If it's not provided, the Widget will be rendered + * to the body of the current document in this case. + *

+ */ + render: function(parentNode) { + if (this.get(DESTROYED)) { Y.log("Render failed; widget has been destroyed", "error", "widget"); } + + if (!this.get(DESTROYED) && !this.get(RENDERED)) { + /** + * Lifecycle event for the render phase, fired prior to rendering the UI + * for the widget (prior to invoking the widget's renderer method). + *

+ * Subscribers to the "on" moment of this event, will be notified + * before the widget is rendered. + *

+ *

+ * Subscribers to the "after" moment of this event, will be notified + * after rendering is complete. + *

+ * + * @event render + * @preventable _defRenderFn + * @param {EventFacade} e The Event Facade + */ + this.publish(RENDER, { + queuable:FALSE, + fireOnce:TRUE, + defaultTargetOnly:TRUE, + defaultFn: this._defRenderFn + }); + + this.fire(RENDER, {parentNode: (parentNode) ? Node.one(parentNode) : null}); + } + return this; + }, + + /** + * Default render handler + * + * @method _defRenderFn + * @protected + * @param {EventFacade} e The Event object + * @param {Node} parentNode The parent node to render to, if passed in to the render method + */ + _defRenderFn : function(e) { + this._parentNode = e.parentNode; + + this.renderer(); + this._set(RENDERED, TRUE); + + this._removeLoadingClassNames(); + }, + + /** + * Creates DOM (or manipulates DOM for progressive enhancement) + * This method is invoked by render() and is not chained + * automatically for the class hierarchy (unlike initializer, destructor) + * so it should be chained manually for subclasses if required. + * + * @method renderer + * @protected + */ + renderer: function() { + // kweight + var widget = this; + + widget._renderUI(); + widget.renderUI(); + + widget._bindUI(); + widget.bindUI(); + + widget._syncUI(); + widget.syncUI(); + }, + + /** + * Configures/Sets up listeners to bind Widget State to UI/DOM + * + * This method is not called by framework and is not chained + * automatically for the class hierarchy. + * + * @method bindUI + * @protected + */ + bindUI: EMPTY_FN, + + /** + * Adds nodes to the DOM + * + * This method is not called by framework and is not chained + * automatically for the class hierarchy. + * + * @method renderUI + * @protected + */ + renderUI: EMPTY_FN, + + /** + * Refreshes the rendered UI, based on Widget State + * + * This method is not called by framework and is not chained + * automatically for the class hierarchy. + * + * @method syncUI + * @protected + * + */ + syncUI: EMPTY_FN, + + /** + * @method hide + * @description Hides the Widget by setting the "visible" attribute to "false". + * @chainable + */ + hide: function() { + return this.set(VISIBLE, FALSE); + }, + + /** + * @method show + * @description Shows the Widget by setting the "visible" attribute to "true". + * @chainable + */ + show: function() { + return this.set(VISIBLE, TRUE); + }, + + /** + * @method focus + * @description Causes the Widget to receive the focus by setting the "focused" + * attribute to "true". + * @chainable + */ + focus: function () { + return this._set(FOCUSED, TRUE); + }, + + /** + * @method blur + * @description Causes the Widget to lose focus by setting the "focused" attribute + * to "false" + * @chainable + */ + blur: function () { + return this._set(FOCUSED, FALSE); + }, + + /** + * @method enable + * @description Set the Widget's "disabled" attribute to "false". + * @chainable + */ + enable: function() { + return this.set(DISABLED, FALSE); + }, + + /** + * @method disable + * @description Set the Widget's "disabled" attribute to "true". + * @chainable + */ + disable: function() { + return this.set(DISABLED, TRUE); + }, + + /** + * @method _uiSizeCB + * @protected + * @param {boolean} expand + */ + _uiSizeCB : function(expand) { + this.get(CONTENT_BOX).toggleClass(_getWidgetClassName(CONTENT, "expanded"), expand); + }, + + /** + * Helper method to collect the boundingBox and contentBox and append to the provided parentNode, if not + * already a child. The owner document of the boundingBox, or the owner document of the contentBox will be used + * as the document into which the Widget is rendered if a parentNode is node is not provided. If both the boundingBox and + * the contentBox are not currently in the document, and no parentNode is provided, the widget will be rendered + * to the current document's body. + * + * @method _renderBox + * @private + * @param {Node} parentNode The parentNode to render the widget to. If not provided, and both the boundingBox and + * the contentBox are not currently in the document, the widget will be rendered to the current document's body. + */ + _renderBox: function(parentNode) { + + // TODO: Performance Optimization [ More effective algo to reduce Node refs, compares, replaces? ] + + var widget = this, // kweight + contentBox = widget.get(CONTENT_BOX), + boundingBox = widget.get(BOUNDING_BOX), + srcNode = widget.get(SRC_NODE), + defParentNode = widget.DEF_PARENT_NODE, + + doc = (srcNode && srcNode.get(OWNER_DOCUMENT)) || boundingBox.get(OWNER_DOCUMENT) || contentBox.get(OWNER_DOCUMENT); + + // If srcNode (assume it's always in doc), have contentBox take its place (widget render responsible for re-use of srcNode contents) + if (srcNode && !srcNode.compareTo(contentBox) && !contentBox.inDoc(doc)) { + srcNode.replace(contentBox); + } + + if (!boundingBox.compareTo(contentBox.get(PARENT_NODE)) && !boundingBox.compareTo(contentBox)) { + // If contentBox box is already in the document, have boundingBox box take it's place + if (contentBox.inDoc(doc)) { + contentBox.replace(boundingBox); + } + boundingBox.appendChild(contentBox); + } + + parentNode = parentNode || (defParentNode && Node.one(defParentNode)); + + if (parentNode) { + parentNode.appendChild(boundingBox); + } else if (!boundingBox.inDoc(doc)) { + Node.one(BODY).insert(boundingBox, 0); + } + }, + + /** + * Setter for the boundingBox attribute + * + * @method _setBB + * @private + * @param {Node|String} node + * @return Node + */ + _setBB: function(node) { + return this._setBox(this.get(ID), node, this.BOUNDING_TEMPLATE, true); + }, + + /** + * Setter for the contentBox attribute + * + * @method _setCB + * @private + * @param {Node|String} node + * @return Node + */ + _setCB: function(node) { + return (this.CONTENT_TEMPLATE === null) ? this.get(BOUNDING_BOX) : this._setBox(null, node, this.CONTENT_TEMPLATE, false); + }, + + /** + * Returns the default value for the boundingBox attribute. + * + * For the Widget class, this will most commonly be null (resulting in a new + * boundingBox node instance being created), unless a srcNode was provided + * and CONTENT_TEMPLATE is null, in which case it will be srcNode. + * This behavior was introduced in @VERSION@ to accomodate single-box widgets + * whose BB & CB both point to srcNode (e.g. Y.Button). + * + * @method _defaultBB + * @protected + */ + _defaultBB : function() { + var node = this.get(SRC_NODE), + nullCT = (this.CONTENT_TEMPLATE === null); + + return ((node && nullCT) ? node : null); + }, + + /** + * Returns the default value for the contentBox attribute. + * + * For the Widget class, this will be the srcNode if provided, otherwise null (resulting in + * a new contentBox node instance being created) + * + * @method _defaultCB + * @protected + */ + _defaultCB : function(node) { + return this.get(SRC_NODE) || null; + }, + + /** + * Helper method to set the bounding/content box, or create it from + * the provided template if not found. + * + * @method _setBox + * @private + * + * @param {String} id The node's id attribute + * @param {Node|String} node The node reference + * @param {String} template HTML string template for the node + * @param {boolean} isBounding true if this is the boundingBox, false if it's the contentBox + * @return {Node} The node + */ + _setBox : function(id, node, template, isBounding) { + + node = Node.one(node); + + if (!node) { + node = Node.create(template); + + if (isBounding) { + this._bbFromTemplate = true; + } else { + this._cbFromTemplate = true; + } + } + + if (!node.get(ID)) { + node.set(ID, id || Y.guid()); + } + + return node; + }, + + /** + * Initializes the UI state for the Widget's bounding/content boxes. + * + * @method _renderUI + * @protected + */ + _renderUI: function() { + this._renderBoxClassNames(); + this._renderBox(this._parentNode); + }, + + /** + * Applies standard class names to the boundingBox and contentBox + * + * @method _renderBoxClassNames + * @protected + */ + _renderBoxClassNames : function() { + var classes = this._getClasses(), + cl, + boundingBox = this.get(BOUNDING_BOX), + i; + + boundingBox.addClass(_getWidgetClassName()); + + // Start from Widget Sub Class + for (i = classes.length-3; i >= 0; i--) { + cl = classes[i]; + boundingBox.addClass(cl.CSS_PREFIX || _getClassName(cl.NAME.toLowerCase())); + } + + // Use instance based name for content box + this.get(CONTENT_BOX).addClass(this.getClassName(CONTENT)); + }, + + /** + * Removes class names representative of the widget's loading state from + * the boundingBox. + * + * @method _removeLoadingClassNames + * @protected + */ + _removeLoadingClassNames: function () { + + var boundingBox = this.get(BOUNDING_BOX), + contentBox = this.get(CONTENT_BOX), + instClass = this.getClassName(LOADING), + widgetClass = _getWidgetClassName(LOADING); + + boundingBox.removeClass(widgetClass) + .removeClass(instClass); + + contentBox.removeClass(widgetClass) + .removeClass(instClass); + }, + + /** + * Sets up DOM and CustomEvent listeners for the widget. + * + * @method _bindUI + * @protected + */ + _bindUI: function() { + this._bindAttrUI(this._UI_ATTRS.BIND); + this._bindDOM(); + }, + + /** + * @method _unbindUI + * @protected + */ + _unbindUI : function(boundingBox) { + this._unbindDOM(boundingBox); + }, + + /** + * Sets up DOM listeners, on elements rendered by the widget. + * + * @method _bindDOM + * @protected + */ + _bindDOM : function() { + var oDocument = this.get(BOUNDING_BOX).get(OWNER_DOCUMENT), + focusHandle = Widget._hDocFocus; + + // Shared listener across all Widgets. + if (!focusHandle) { + focusHandle = Widget._hDocFocus = oDocument.on("focus", this._onDocFocus, this); + focusHandle.listeners = { + count: 0 + }; + } + + focusHandle.listeners[Y.stamp(this, true)] = true; + focusHandle.listeners.count++; + + // Fix for Webkit: + // Document doesn't receive focus in Webkit when the user mouses + // down on it, so the "focused" attribute won't get set to the + // correct value. Keeping this instance based for now, potential better performance. + // Otherwise we'll end up looking up widgets from the DOM on every mousedown. + if (WEBKIT){ + this._hDocMouseDown = oDocument.on("mousedown", this._onDocMouseDown, this); + } + }, + + /** + * @method _unbindDOM + * @protected + */ + _unbindDOM : function(boundingBox) { + + var focusHandle = Widget._hDocFocus, + yuid = Y.stamp(this, true), + focusListeners, + mouseHandle = this._hDocMouseDown; + + if (focusHandle) { + + focusListeners = focusHandle.listeners; + + if (focusListeners[yuid]) { + delete focusListeners[yuid]; + focusListeners.count--; + } + + if (focusListeners.count === 0) { + focusHandle.detach(); + Widget._hDocFocus = null; + } + } + + if (WEBKIT && mouseHandle) { + mouseHandle.detach(); + } + }, + + /** + * Updates the widget UI to reflect the attribute state. + * + * @method _syncUI + * @protected + */ + _syncUI: function() { + this._syncAttrUI(this._UI_ATTRS.SYNC); + }, + + /** + * Sets the height on the widget's bounding box element + * + * @method _uiSetHeight + * @protected + * @param {String | Number} val + */ + _uiSetHeight: function(val) { + this._uiSetDim(HEIGHT, val); + this._uiSizeCB((val !== EMPTY_STR && val !== AUTO)); + }, + + /** + * Sets the width on the widget's bounding box element + * + * @method _uiSetWidth + * @protected + * @param {String | Number} val + */ + _uiSetWidth: function(val) { + this._uiSetDim(WIDTH, val); + }, + + /** + * @method _uiSetDim + * @private + * @param {String} dim The dimension - "width" or "height" + * @param {Number | String} val The value to set + */ + _uiSetDim: function(dimension, val) { + this.get(BOUNDING_BOX).setStyle(dimension, L.isNumber(val) ? val + this.DEF_UNIT : val); + }, + + /** + * Sets the visible state for the UI + * + * @method _uiSetVisible + * @protected + * @param {boolean} val + */ + _uiSetVisible: function(val) { + this.get(BOUNDING_BOX).toggleClass(this.getClassName(HIDDEN), !val); + }, + + /** + * Sets the disabled state for the UI + * + * @method _uiSetDisabled + * @protected + * @param {boolean} val + */ + _uiSetDisabled: function(val) { + this.get(BOUNDING_BOX).toggleClass(this.getClassName(DISABLED), val); + }, + + /** + * Sets the focused state for the UI + * + * @method _uiSetFocused + * @protected + * @param {boolean} val + * @param {string} src String representing the source that triggered an update to + * the UI. + */ + _uiSetFocused: function(val, src) { + var boundingBox = this.get(BOUNDING_BOX); + boundingBox.toggleClass(this.getClassName(FOCUSED), val); + + if (src !== UI) { + if (val) { + boundingBox.focus(); + } else { + boundingBox.blur(); + } + } + }, + + /** + * Set the tabIndex on the widget's rendered UI + * + * @method _uiSetTabIndex + * @protected + * @param Number + */ + _uiSetTabIndex: function(index) { + var boundingBox = this.get(BOUNDING_BOX); + + if (L.isNumber(index)) { + boundingBox.set(TAB_INDEX, index); + } else { + boundingBox.removeAttribute(TAB_INDEX); + } + }, + + /** + * @method _onDocMouseDown + * @description "mousedown" event handler for the owner document of the + * widget's bounding box. + * @protected + * @param {EventFacade} evt The event facade for the DOM focus event + */ + _onDocMouseDown: function (evt) { + if (this._domFocus) { + this._onDocFocus(evt); + } + }, + + /** + * DOM focus event handler, used to sync the state of the Widget with the DOM + * + * @method _onDocFocus + * @protected + * @param {EventFacade} evt The event facade for the DOM focus event + */ + _onDocFocus: function (evt) { + var widget = Widget.getByNode(evt.target), + activeWidget = Widget._active; + + if (activeWidget && (activeWidget !== widget)) { + activeWidget._domFocus = false; + activeWidget._set(FOCUSED, false, {src:UI}); + + Widget._active = null; + } + + if (widget) { + widget._domFocus = true; + widget._set(FOCUSED, true, {src:UI}); + + Widget._active = widget; + } + }, + + /** + * Generic toString implementation for all widgets. + * + * @method toString + * @return {String} The default string value for the widget [ displays the NAME of the instance, and the unique id ] + */ + toString: function() { + // Using deprecated name prop for kweight squeeze. + return this.name + "[" + this.get(ID) + "]"; + }, + + /** + * Default unit to use for dimension values + * + * @property DEF_UNIT + * @type String + */ + DEF_UNIT : "px", + + /** + * Default node to render the bounding box to. If not set, + * will default to the current document body. + * + * @property DEF_PARENT_NODE + * @type String | Node + */ + DEF_PARENT_NODE : null, + + /** + * Property defining the markup template for content box. If your Widget doesn't + * need the dual boundingBox/contentBox structure, set CONTENT_TEMPLATE to null, + * and contentBox and boundingBox will both point to the same Node. + * + * @property CONTENT_TEMPLATE + * @type String + */ + CONTENT_TEMPLATE : DIV, + + /** + * Property defining the markup template for bounding box. + * + * @property BOUNDING_TEMPLATE + * @type String + */ + BOUNDING_TEMPLATE : DIV, + + /** + * @method _guid + * @protected + */ + _guid : function() { + return Y.guid(); + }, + + /** + * @method _validTabIndex + * @protected + * @param {Number} tabIndex + */ + _validTabIndex : function (tabIndex) { + return (L.isNumber(tabIndex) || L.isNull(tabIndex)); + }, + + /** + * Binds after listeners for the list of attributes provided + * + * @method _bindAttrUI + * @private + * @param {Array} attrs + */ + _bindAttrUI : function(attrs) { + var i, + l = attrs.length; + + for (i = 0; i < l; i++) { + this.after(attrs[i] + CHANGE, this._setAttrUI); + } + }, + + /** + * Invokes the _uiSet=ATTR NAME> method for the list of attributes provided + * + * @method _syncAttrUI + * @private + * @param {Array} attrs + */ + _syncAttrUI : function(attrs) { + var i, l = attrs.length, attr; + for (i = 0; i < l; i++) { + attr = attrs[i]; + this[_UISET + _toInitialCap(attr)](this.get(attr)); + } + }, + + /** + * @method _setAttrUI + * @private + * @param {EventFacade} e + */ + _setAttrUI : function(e) { + if (e.target === this) { + this[_UISET + _toInitialCap(e.attrName)](e.newVal, e.src); + } + }, + + /** + * The default setter for the strings attribute. Merges partial sets + * into the full string set, to allow users to partial sets of strings + * + * @method _strSetter + * @protected + * @param {Object} strings + * @return {String} The full set of strings to set + */ + _strSetter : function(strings) { + return Y.merge(this.get(STRINGS), strings); + }, + + /** + * Helper method to get a specific string value + * + * @deprecated Used by deprecated WidgetLocale implementations. + * @method getString + * @param {String} key + * @return {String} The string + */ + getString : function(key) { + return this.get(STRINGS)[key]; + }, + + /** + * Helper method to get the complete set of strings for the widget + * + * @deprecated Used by deprecated WidgetLocale implementations. + * @method getStrings + * @param {String} key + * @return {String} The strings + */ + getStrings : function() { + return this.get(STRINGS); + }, + + /** + * The lists of UI attributes to bind and sync for widget's _bindUI and _syncUI implementations + * + * @property _UI_ATTRS + * @type Object + * @private + */ + _UI_ATTRS : { + BIND: UI_ATTRS, + SYNC: UI_ATTRS + } +}); + +Y.Widget = Widget; + + +}, '@VERSION@', { + "requires": [ + "attribute", + "base-base", + "base-pluginhost", + "classnamemanager", + "event-focus", + "node-base", + "node-style" + ], + "skinnable": true +});