3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
7 YUI.add('widget-base', function(Y) {
10 * Provides the base Widget class, with HTML Parser support
17 * Provides the base Widget class
20 * @submodule widget-base
25 ClassNameManager = Y.ClassNameManager,
27 _getClassName = ClassNameManager.getClassName,
30 _toInitialCap = Y.cached(function(str) {
31 return str.substring(0, 1).toUpperCase() + str.substring(1);
34 // K-Weight, IE GC optimizations
38 DISABLED = "disabled",
42 BOUNDING_BOX = "boundingBox",
43 CONTENT_BOX = "contentBox",
44 PARENT_NODE = "parentNode",
45 OWNER_DOCUMENT = "ownerDocument",
49 TAB_INDEX = "tabIndex",
52 RENDERED = "rendered",
53 DESTROYED = "destroyed",
62 EMPTY_FN = function() {},
69 UI_ATTRS = [VISIBLE, DISABLED, HEIGHT, WIDTH, FOCUSED, TAB_INDEX],
73 // Widget nodeid-to-instance map.
77 * A base class for widgets, providing:
79 * <li>The render lifecycle method, in addition to the init and destroy
80 * lifecycle methods provide by Base</li>
81 * <li>Abstract methods to support consistent MVC structure across
82 * widgets: renderer, renderUI, bindUI, syncUI</li>
83 * <li>Support for common widget attributes, such as boundingBox, contentBox, visible,
84 * disabled, focused, strings</li>
87 * @param config {Object} Object literal specifying widget configuration properties.
93 function Widget(config) {
94 Y.log('constructor called', 'life', 'widget');
100 constructor = widget.constructor;
103 widget._cssPrefix = constructor.CSS_PREFIX || _getClassName(constructor.NAME.toLowerCase());
105 // We need a config for HTML_PARSER to work.
106 config = config || {};
108 Widget.superclass.constructor.call(widget, config);
110 render = widget.get(RENDER);
113 // Render could be a node or boolean
114 if (render !== TRUE) {
117 widget.render(parentNode);
122 * Static property provides a string to identify the class.
124 * Currently used to apply class identifiers to the bounding box
125 * and to classify events fired by the widget.
132 Widget.NAME = "widget";
135 * Constant used to identify state changes originating from
136 * the DOM (as opposed to the JavaScript model).
143 UI = Widget.UI_SRC = "ui";
146 * Static property used to define the default attribute
147 * configuration for the Widget.
153 Widget.ATTRS = ATTRS;
155 // Trying to optimize kweight by setting up attrs this way saves about 0.4K min'd
160 * @default Generated using guid()
170 * Flag indicating whether or not this Widget
171 * has been through the render lifecycle phase.
173 * @attribute rendered
184 * @attribute boundingBox
185 * @description The outermost DOM node for the Widget, used for sizing and positioning
186 * of a Widget as well as a containing element for any decorator elements used
188 * @type String | Node
191 ATTRS[BOUNDING_BOX] = {
198 * @attribute contentBox
199 * @description A DOM node that is a direct descendant of a Widget's bounding box that
200 * houses its content.
201 * @type String | Node
204 ATTRS[CONTENT_BOX] = {
205 valueFn:"_defaultCB",
211 * @attribute tabIndex
212 * @description Number (between -32767 to 32767) indicating the widget's
213 * position in the default tab flow. The value is used to set the
214 * "tabIndex" attribute on the widget's bounding box. Negative values allow
215 * the widget to receive DOM focus programmatically (by calling the focus
216 * method), while being removed from the default tab flow. A value of
217 * null removes the "tabIndex" attribute from the widget's bounding box.
223 validator: "_validTabIndex"
228 * @description Boolean indicating if the Widget, or one of its descendants,
240 * @attribute disabled
241 * @description Boolean indicating if the Widget should be disabled. The disabled implementation
242 * is left to the specific classes extending widget.
252 * @description Boolean indicating weather or not the Widget is visible.
262 * @description String with units, or number, representing the height of the Widget. If a number is provided,
263 * the default unit, defined by the Widgets DEF_UNIT, property is used.
265 * @type {String | Number}
273 * @description String with units, or number, representing the width of the Widget. If a number is provided,
274 * the default unit, defined by the Widgets DEF_UNIT, property is used.
276 * @type {String | Number}
284 * @description Collection of strings used to label elements of the Widget's UI.
290 setter: "_strSetter",
295 * Whether or not to render the widget automatically after init, and optionally, to which parent node.
298 * @type boolean | Node
307 * The css prefix which the static Widget.getClassName method should use when constructing class names
309 * @property CSS_PREFIX
311 * @default Widget.NAME.toLowerCase()
315 Widget.CSS_PREFIX = _getClassName(Widget.NAME.toLowerCase());
318 * Generate a standard prefixed classname for the Widget, prefixed by the default prefix defined
319 * by the <code>Y.config.classNamePrefix</code> attribute used by <code>ClassNameManager</code> and
320 * <code>Widget.NAME.toLowerCase()</code> (e.g. "yui-widget-xxxxx-yyyyy", based on default values for
321 * the prefix and widget class name).
323 * The instance based version of this method can be used to generate standard prefixed classnames,
324 * based on the instances NAME, as opposed to Widget.NAME. This method should be used when you
325 * need to use a constant class name across different types instances.
327 * @method getClassName
328 * @param {String*} args* 0..n strings which should be concatenated, using the default separator defined by ClassNameManager, to create the class name
330 Widget.getClassName = function() {
331 // arguments needs to be array'fied to concat
332 return _getClassName.apply(ClassNameManager, [Widget.CSS_PREFIX].concat(Y.Array(arguments), true));
335 _getWidgetClassName = Widget.getClassName;
338 * Returns the widget instance whose bounding box contains, or is, the given node.
340 * In the case of nested widgets, the nearest bounding box ancestor is used to
341 * return the widget instance.
345 * @param node {Node | String} The node for which to return a Widget instance. If a selector
346 * string is passed in, which selects more than one node, the first node found is used.
347 * @return {Widget} Widget instance, or null if not found.
349 Widget.getByNode = function(node) {
352 widgetMarker = _getWidgetClassName();
354 node = Node.one(node);
356 node = node.ancestor("." + widgetMarker, true);
358 nodeid = node.get(ID);
359 widget = _instances[nodeid];
363 return widget || null;
366 Y.extend(Widget, Y.Base, {
369 * Returns a class name prefixed with the the value of the
370 * <code>YUI.config.classNamePrefix</code> attribute + the instances <code>NAME</code> property.
371 * Uses <code>YUI.config.classNameDelimiter</code> attribute to delimit the provided strings.
375 * // returns "yui-slider-foo-bar", for a slider instance
376 * var scn = slider.getClassName('foo','bar');
378 * // returns "yui-overlay-foo-bar", for an overlay instance
379 * var ocn = overlay.getClassName('foo','bar');
383 * @method getClassName
384 * @param {String}+ One or more classname bits to be joined and prefixed
386 getClassName: function () {
387 return _getClassName.apply(ClassNameManager, [this._cssPrefix].concat(Y.Array(arguments), true));
391 * Initializer lifecycle implementation for the Widget class. Registers the
392 * widget instance, and runs through the Widget's HTML_PARSER definition.
394 * @method initializer
396 * @param config {Object} Configuration object literal for the widget
398 initializer: function(config) {
399 Y.log('initializer called', 'life', 'widget');
401 var bb = this.get(BOUNDING_BOX);
402 if (bb instanceof Node) {
403 this._mapInstance(bb.get(ID));
407 * Notification event, which widget implementations can fire, when
408 * they change the content of the widget. This event has no default
409 * behavior and cannot be prevented, so the "on" or "after"
410 * moments are effectively equivalent (with on listeners being invoked before
413 * @event widget:contentUpdate
415 * @param {EventFacade} e The Event Facade
418 if (this._applyParser) {
419 this._applyParser(config);
424 * Utility method used to add an entry to the boundingBox id to instance map.
426 * This method can be used to populate the instance with lazily created boundingBox Node references.
428 * @method _mapInstance
429 * @param {String} The boundingBox id
432 _mapInstance : function(id) {
433 if (!(_instances[id])) {
434 _instances[id] = this;
439 * Destructor lifecycle implementation for the Widget class. Purges events attached
440 * to the bounding box and content box, removes them from the DOM and removes
441 * the Widget from the list of registered widgets.
446 destructor: function() {
447 Y.log('destructor called', 'life', 'widget');
449 var boundingBox = this.get(BOUNDING_BOX),
452 if (boundingBox instanceof Node) {
453 bbid = boundingBox.get(ID);
455 if (bbid in _instances) {
456 delete _instances[bbid];
465 * Destroy lifecycle method. Fires the destroy
466 * event, prior to invoking destructors for the
469 * Overrides Base's implementation, to support arguments to destroy
472 * Subscribers to the destroy
473 * event can invoke preventDefault on the event object, to prevent destruction
477 * @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.
478 * @return {Widget} A reference to this object
481 destroy: function(destroyAllNodes) {
482 this._destroyAllNodes = destroyAllNodes;
483 return Widget.superclass.destroy.apply(this);
487 * Removes and destroys the widgets rendered boundingBox, contentBox,
488 * and detaches bound UI events.
490 * @method _destroyBox
493 _destroyBox : function() {
495 var boundingBox = this.get(BOUNDING_BOX),
496 contentBox = this.get(CONTENT_BOX),
497 deep = this._destroyAllNodes,
500 same = boundingBox && boundingBox.compareTo(contentBox);
502 if (this.UI_EVENTS) {
503 this._destroyUIEvents();
506 this._unbindUI(boundingBox);
509 // Removes and destroys all child nodes.
511 boundingBox.remove(TRUE);
514 contentBox.remove(TRUE);
517 boundingBox.remove(TRUE);
523 * Establishes the initial DOM for the widget. Invoking this
524 * method will lead to the creating of all DOM elements for
525 * the widget (or the manipulation of existing DOM elements
526 * for the progressive enhancement use case).
528 * This method should only be invoked once for an initialized
532 * It delegates to the widget specific renderer method to do
539 * @param parentNode {Object | String} Optional. The Node under which the
540 * Widget is to be rendered. This can be a Node instance or a CSS selector string.
542 * If the selector string returns more than one Node, the first node will be used
543 * as the parentNode. NOTE: This argument is required if both the boundingBox and contentBox
544 * are not currently in the document. If it's not provided, the Widget will be rendered
545 * to the body of the current document in this case.
548 render: function(parentNode) {
549 if (this.get(DESTROYED)) { Y.log("Render failed; widget has been destroyed", "error", "widget"); }
551 if (!this.get(DESTROYED) && !this.get(RENDERED)) {
553 * Lifecycle event for the render phase, fired prior to rendering the UI
554 * for the widget (prior to invoking the widget's renderer method).
556 * Subscribers to the "on" moment of this event, will be notified
557 * before the widget is rendered.
560 * Subscribers to the "after" moment of this event, will be notified
561 * after rendering is complete.
564 * @event widget:render
565 * @preventable _defRenderFn
566 * @param {EventFacade} e The Event Facade
568 this.publish(RENDER, {
571 defaultTargetOnly:TRUE,
572 defaultFn: this._defRenderFn
575 this.fire(RENDER, {parentNode: (parentNode) ? Node.one(parentNode) : null});
581 * Default render handler
583 * @method _defRenderFn
585 * @param {EventFacade} e The Event object
586 * @param {Node} parentNode The parent node to render to, if passed in to the <code>render</code> method
588 _defRenderFn : function(e) {
589 this._parentNode = e.parentNode;
592 this._set(RENDERED, TRUE);
594 this._removeLoadingClassNames();
598 * Creates DOM (or manipulates DOM for progressive enhancement)
599 * This method is invoked by render() and is not chained
600 * automatically for the class hierarchy (unlike initializer, destructor)
601 * so it should be chained manually for subclasses if required.
606 renderer: function() {
621 * Configures/Sets up listeners to bind Widget State to UI/DOM
623 * This method is not called by framework and is not chained
624 * automatically for the class hierarchy.
632 * Adds nodes to the DOM
634 * This method is not called by framework and is not chained
635 * automatically for the class hierarchy.
643 * Refreshes the rendered UI, based on Widget State
645 * This method is not called by framework and is not chained
646 * automatically for the class hierarchy.
656 * @description Hides the Widget by setting the "visible" attribute to "false".
660 return this.set(VISIBLE, FALSE);
665 * @description Shows the Widget by setting the "visible" attribute to "true".
669 return this.set(VISIBLE, TRUE);
674 * @description Causes the Widget to receive the focus by setting the "focused"
675 * attribute to "true".
679 return this._set(FOCUSED, TRUE);
684 * @description Causes the Widget to lose focus by setting the "focused" attribute
689 return this._set(FOCUSED, FALSE);
694 * @description Set the Widget's "disabled" attribute to "false".
698 return this.set(DISABLED, FALSE);
703 * @description Set the Widget's "disabled" attribute to "true".
706 disable: function() {
707 return this.set(DISABLED, TRUE);
713 * @param {boolean} expand
715 _uiSizeCB : function(expand) {
716 this.get(CONTENT_BOX).toggleClass(_getWidgetClassName(CONTENT, "expanded"), expand);
720 * Helper method to collect the boundingBox and contentBox and append to the provided parentNode, if not
721 * already a child. The owner document of the boundingBox, or the owner document of the contentBox will be used
722 * as the document into which the Widget is rendered if a parentNode is node is not provided. If both the boundingBox and
723 * the contentBox are not currently in the document, and no parentNode is provided, the widget will be rendered
724 * to the current document's body.
728 * @param {Node} parentNode The parentNode to render the widget to. If not provided, and both the boundingBox and
729 * the contentBox are not currently in the document, the widget will be rendered to the current document's body.
731 _renderBox: function(parentNode) {
733 // TODO: Performance Optimization [ More effective algo to reduce Node refs, compares, replaces? ]
735 var widget = this, // kweight
736 contentBox = widget.get(CONTENT_BOX),
737 boundingBox = widget.get(BOUNDING_BOX),
738 srcNode = widget.get(SRC_NODE),
739 defParentNode = widget.DEF_PARENT_NODE,
741 doc = (srcNode && srcNode.get(OWNER_DOCUMENT)) || boundingBox.get(OWNER_DOCUMENT) || contentBox.get(OWNER_DOCUMENT);
743 // If srcNode (assume it's always in doc), have contentBox take its place (widget render responsible for re-use of srcNode contents)
744 if (srcNode && !srcNode.compareTo(contentBox) && !contentBox.inDoc(doc)) {
745 srcNode.replace(contentBox);
748 if (!boundingBox.compareTo(contentBox.get(PARENT_NODE)) && !boundingBox.compareTo(contentBox)) {
749 // If contentBox box is already in the document, have boundingBox box take it's place
750 if (contentBox.inDoc(doc)) {
751 contentBox.replace(boundingBox);
753 boundingBox.appendChild(contentBox);
756 parentNode = parentNode || (defParentNode && Node.one(defParentNode));
759 parentNode.appendChild(boundingBox);
760 } else if (!boundingBox.inDoc(doc)) {
761 Node.one(BODY).insert(boundingBox, 0);
766 * Setter for the boundingBox attribute
773 _setBB: function(node) {
774 return this._setBox(this.get(ID), node, this.BOUNDING_TEMPLATE);
778 * Setter for the contentBox attribute
782 * @param {Node|String} node
785 _setCB: function(node) {
786 return (this.CONTENT_TEMPLATE === null) ? this.get(BOUNDING_BOX) : this._setBox(null, node, this.CONTENT_TEMPLATE);
790 * Returns the default value for the contentBox attribute.
792 * For the Widget class, this will be the srcNode if provided, otherwise null (resulting in
793 * a new contentBox node instance being created)
798 _defaultCB : function(node) {
799 return this.get(SRC_NODE) || null;
803 * Helper method to set the bounding/content box, or create it from
804 * the provided template if not found.
809 * @param {String} id The node's id attribute
810 * @param {Node|String} node The node reference
811 * @param {String} template HTML string template for the node
812 * @return {Node} The node
814 _setBox : function(id, node, template) {
815 node = Node.one(node) || Node.create(template);
817 node.set(ID, id || Y.guid());
823 * Initializes the UI state for the Widget's bounding/content boxes.
828 _renderUI: function() {
829 this._renderBoxClassNames();
830 this._renderBox(this._parentNode);
834 * Applies standard class names to the boundingBox and contentBox
836 * @method _renderBoxClassNames
839 _renderBoxClassNames : function() {
840 var classes = this._getClasses(),
842 boundingBox = this.get(BOUNDING_BOX),
845 boundingBox.addClass(_getWidgetClassName());
847 // Start from Widget Sub Class
848 for (i = classes.length-3; i >= 0; i--) {
850 boundingBox.addClass(cl.CSS_PREFIX || _getClassName(cl.NAME.toLowerCase()));
853 // Use instance based name for content box
854 this.get(CONTENT_BOX).addClass(this.getClassName(CONTENT));
858 * Removes class names representative of the widget's loading state from
861 * @method _removeLoadingClassNames
864 _removeLoadingClassNames: function () {
866 var boundingBox = this.get(BOUNDING_BOX),
867 contentBox = this.get(CONTENT_BOX),
868 instClass = this.getClassName(LOADING),
869 widgetClass = _getWidgetClassName(LOADING);
871 boundingBox.removeClass(widgetClass)
872 .removeClass(instClass);
874 contentBox.removeClass(widgetClass)
875 .removeClass(instClass);
879 * Sets up DOM and CustomEvent listeners for the widget.
884 _bindUI: function() {
885 this._bindAttrUI(this._UI_ATTRS.BIND);
893 _unbindUI : function(boundingBox) {
894 this._unbindDOM(boundingBox);
898 * Sets up DOM listeners, on elements rendered by the widget.
903 _bindDOM : function() {
904 var oDocument = this.get(BOUNDING_BOX).get(OWNER_DOCUMENT),
905 focusHandle = Widget._hDocFocus;
907 // Shared listener across all Widgets.
909 focusHandle = Widget._hDocFocus = oDocument.on("focus", this._onDocFocus, this);
910 focusHandle.listeners = 1;
912 focusHandle.listeners++;
916 // Document doesn't receive focus in Webkit when the user mouses
917 // down on it, so the "focused" attribute won't get set to the
918 // correct value. Keeping this instance based for now, potential better performance.
919 // Otherwise we'll end up looking up widgets from the DOM on every mousedown.
921 this._hDocMouseDown = oDocument.on("mousedown", this._onDocMouseDown, this);
929 _unbindDOM : function(boundingBox) {
931 var focusHandle = Widget._hDocFocus,
932 mouseHandle = this._hDocMouseDown;
935 if (focusHandle.listeners > 0) {
936 focusHandle.listeners--;
938 focusHandle.detach();
939 Widget._hDocFocus = null;
943 if (WEBKIT && mouseHandle) {
944 mouseHandle.detach();
949 * Updates the widget UI to reflect the attribute state.
954 _syncUI: function() {
955 this._syncAttrUI(this._UI_ATTRS.SYNC);
959 * Sets the height on the widget's bounding box element
961 * @method _uiSetHeight
963 * @param {String | Number} val
965 _uiSetHeight: function(val) {
966 this._uiSetDim(HEIGHT, val);
967 this._uiSizeCB((val !== EMPTY_STR && val !== AUTO));
971 * Sets the width on the widget's bounding box element
973 * @method _uiSetWidth
975 * @param {String | Number} val
977 _uiSetWidth: function(val) {
978 this._uiSetDim(WIDTH, val);
984 * @param {String} dim The dimension - "width" or "height"
985 * @param {Number | String} val The value to set
987 _uiSetDim: function(dimension, val) {
988 this.get(BOUNDING_BOX).setStyle(dimension, L.isNumber(val) ? val + this.DEF_UNIT : val);
992 * Sets the visible state for the UI
994 * @method _uiSetVisible
996 * @param {boolean} val
998 _uiSetVisible: function(val) {
999 this.get(BOUNDING_BOX).toggleClass(this.getClassName(HIDDEN), !val);
1003 * Sets the disabled state for the UI
1005 * @method _uiSetDisabled
1007 * @param {boolean} val
1009 _uiSetDisabled: function(val) {
1010 this.get(BOUNDING_BOX).toggleClass(this.getClassName(DISABLED), val);
1014 * Sets the focused state for the UI
1016 * @method _uiSetFocused
1018 * @param {boolean} val
1019 * @param {string} src String representing the source that triggered an update to
1022 _uiSetFocused: function(val, src) {
1023 var boundingBox = this.get(BOUNDING_BOX);
1024 boundingBox.toggleClass(this.getClassName(FOCUSED), val);
1028 boundingBox.focus();
1036 * Set the tabIndex on the widget's rendered UI
1038 * @method _uiSetTabIndex
1042 _uiSetTabIndex: function(index) {
1043 var boundingBox = this.get(BOUNDING_BOX);
1045 if (L.isNumber(index)) {
1046 boundingBox.set(TAB_INDEX, index);
1048 boundingBox.removeAttribute(TAB_INDEX);
1053 * @method _onDocMouseDown
1054 * @description "mousedown" event handler for the owner document of the
1055 * widget's bounding box.
1057 * @param {EventFacade} evt The event facade for the DOM focus event
1059 _onDocMouseDown: function (evt) {
1060 if (this._domFocus) {
1061 this._onDocFocus(evt);
1066 * DOM focus event handler, used to sync the state of the Widget with the DOM
1068 * @method _onDocFocus
1070 * @param {EventFacade} evt The event facade for the DOM focus event
1072 _onDocFocus: function (evt) {
1073 var widget = Widget.getByNode(evt.target),
1074 activeWidget = Widget._active;
1076 if (activeWidget && (activeWidget !== widget)) {
1077 activeWidget._domFocus = false;
1078 activeWidget._set(FOCUSED, false, {src:UI});
1080 Widget._active = null;
1084 widget._domFocus = true;
1085 widget._set(FOCUSED, true, {src:UI});
1087 Widget._active = widget;
1092 * Generic toString implementation for all widgets.
1095 * @return {String} The default string value for the widget [ displays the NAME of the instance, and the unique id ]
1097 toString: function() {
1098 // Using deprecated name prop for kweight squeeze.
1099 return this.name + "[" + this.get(ID) + "]";
1103 * Default unit to use for dimension values
1105 * @property DEF_UNIT
1111 * Default node to render the bounding box to. If not set,
1112 * will default to the current document body.
1114 * @property DEF_PARENT_NODE
1115 * @type String | Node
1117 DEF_PARENT_NODE : null,
1120 * Property defining the markup template for content box. If your Widget doesn't
1121 * need the dual boundingBox/contentBox structure, set CONTENT_TEMPLATE to null,
1122 * and contentBox and boundingBox will both point to the same Node.
1124 * @property CONTENT_TEMPLATE
1127 CONTENT_TEMPLATE : DIV,
1130 * Property defining the markup template for bounding box.
1132 * @property BOUNDING_TEMPLATE
1135 BOUNDING_TEMPLATE : DIV,
1141 _guid : function() {
1146 * @method _validTabIndex
1148 * @param {Number} tabIndex
1150 _validTabIndex : function (tabIndex) {
1151 return (L.isNumber(tabIndex) || L.isNull(tabIndex));
1155 * Binds after listeners for the list of attributes provided
1157 * @method _bindAttrUI
1159 * @param {Array} attrs
1161 _bindAttrUI : function(attrs) {
1165 for (i = 0; i < l; i++) {
1166 this.after(attrs[i] + CHANGE, this._setAttrUI);
1171 * Invokes the _uiSet=ATTR NAME> method for the list of attributes provided
1173 * @method _syncAttrUI
1175 * @param {Array} attrs
1177 _syncAttrUI : function(attrs) {
1178 var i, l = attrs.length, attr;
1179 for (i = 0; i < l; i++) {
1181 this[_UISET + _toInitialCap(attr)](this.get(attr));
1186 * @method _setAttrUI
1188 * @param {EventFacade} e
1190 _setAttrUI : function(e) {
1191 if (e.target === this) {
1192 this[_UISET + _toInitialCap(e.attrName)](e.newVal, e.src);
1197 * The default setter for the strings attribute. Merges partial sets
1198 * into the full string set, to allow users to partial sets of strings
1200 * @method _strSetter
1202 * @param {Object} strings
1203 * @return {String} The full set of strings to set
1205 _strSetter : function(strings) {
1206 return Y.merge(this.get(STRINGS), strings);
1210 * Helper method to get a specific string value
1212 * @deprecated Used by deprecated WidgetLocale implementations.
1214 * @param {String} key
1215 * @return {String} The string
1217 getString : function(key) {
1218 return this.get(STRINGS)[key];
1222 * Helper method to get the complete set of strings for the widget
1224 * @deprecated Used by deprecated WidgetLocale implementations.
1225 * @method getStrings
1226 * @param {String} key
1227 * @return {String} The strings
1229 getStrings : function() {
1230 return this.get(STRINGS);
1234 * The lists of UI attributes to bind and sync for widget's _bindUI and _syncUI implementations
1236 * @property _UI_ATTRS
1249 }, '3.5.0' ,{requires:['attribute', 'event-focus', 'base-base', 'base-pluginhost', 'node-base', 'node-style', 'classnamemanager'], skinnable:true});