AutorÃa | Ultima modificación | Ver Log |
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 optimizationsCONTENT = "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 = "<div></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:* <ul>* <li>The render lifecycle method, in addition to the init and destroy* lifecycle methods provide by Base</li>* <li>Abstract methods to support consistent MVC structure across* widgets: renderer, renderUI, bindUI, syncUI</li>* <li>Support for common widget attributes, such as boundingBox, contentBox, visible,* disabled, focused, strings</li>* </ul>** @param config {Object} Object literal specifying widget configuration properties.** @class Widget* @constructor* @extends Base*/function Widget(config) {// kweightvar 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 booleanif (render !== TRUE) {parentNode = render;}widget.render(parentNode);}}/*** Static property provides a string to identify the class.* <p>* Currently used to apply class identifiers to the bounding box* and to classify events fired by the widget.* </p>** @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 <code>Y.config.classNamePrefix</code> attribute used by <code>ClassNameManager</code> and* <code>Widget.NAME.toLowerCase()</code> (e.g. "yui-widget-xxxxx-yyyyy", based on default values for* the prefix and widget class name).* <p>* 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.* </p>* @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 concatreturn _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.* <p>* In the case of nested widgets, the nearest bounding box ancestor is used to* return the widget instance.* </p>* @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* <code>YUI.config.classNamePrefix</code> attribute + the instances <code>NAME</code> property.* Uses <code>YUI.config.classNameDelimiter</code> attribute to delimit the provided strings.* e.g.* <code>* <pre>* // 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');* </pre>* </code>** @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) {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() {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();}},/*** <p>* Destroy lifecycle method. Fires the destroy* event, prior to invoking destructors for the* class hierarchy.** Overrides Base's implementation, to support arguments to destroy* </p>* <p>* Subscribers to the destroy* event can invoke preventDefault on the event object, to prevent destruction* from proceeding.* </p>* @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).* <p>* This method should only be invoked once for an initialized* widget.* </p>* <p>* It delegates to the widget specific renderer method to do* the actual work.* </p>** @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.* <p>* 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.* </p>*/render: function(parentNode) {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).* <p>* Subscribers to the "on" moment of this event, will be notified* before the widget is rendered.* </p>* <p>* Subscribers to the "after" moment of this event, will be notified* after rendering is complete.* </p>** @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 <code>render</code> 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() {// kweightvar 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, // kweightcontentBox = 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 placeif (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 3.18.1 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 Classfor (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 boxthis.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;}, '3.18.1', {"requires": ["attribute","base-base","base-pluginhost","classnamemanager","event-focus","node-base","node-style"],"skinnable": true});