autocomplete-list-debug.js revision c0486d6f93858a5de5737e65f736d40e4b0feed5
b32d148b0052e1f874e9bc9803bef729bf859d97Luke SmithYUI.add('autocomplete-list', function(Y) {
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith/**
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke SmithTraditional autocomplete dropdown list widget, just like Mom used to make.
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith@module autocomplete
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith@submodule autocomplete-list
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith**/
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith/**
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke SmithTraditional autocomplete dropdown list widget, just like Mom used to make.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith@class AutoCompleteList
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith@extends Widget
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith@uses AutoCompleteBase
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith@uses WidgetPosition
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith@uses WidgetPositionAlign
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith@constructor
01a9f856a72f90fbb8197384630b97bb93dc7473Luke Smith@param {Object} config Configuration object.
01a9f856a72f90fbb8197384630b97bb93dc7473Luke Smith**/
01a9f856a72f90fbb8197384630b97bb93dc7473Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithvar Lang = Y.Lang,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Node = Y.Node,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith YArray = Y.Array,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // Whether or not we need an iframe shim.
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith useShim = Y.UA.ie && Y.UA.ie < 7,
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // keyCode constants.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith KEY_TAB = 9,
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith // String shorthand.
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith _CLASS_ITEM = '_CLASS_ITEM',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith _CLASS_ITEM_ACTIVE = '_CLASS_ITEM_ACTIVE',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith _CLASS_ITEM_HOVER = '_CLASS_ITEM_HOVER',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith _SELECTOR_ITEM = '_SELECTOR_ITEM',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith ACTIVE_ITEM = 'activeItem',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith ALWAYS_SHOW_LIST = 'alwaysShowList',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith CIRCULAR = 'circular',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith HOVERED_ITEM = 'hoveredItem',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith ID = 'id',
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith ITEM = 'item',
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith LIST = 'list',
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith RESULT = 'result',
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith RESULTS = 'results',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith VISIBLE = 'visible',
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith WIDTH = 'width',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith // Event names.
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith EVT_SELECT = 'select',
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke SmithList = Y.Base.create('autocompleteList', Y.Widget, [
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Y.AutoCompleteBase,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Y.WidgetPosition,
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith Y.WidgetPositionAlign
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith], {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith // -- Prototype Properties -------------------------------------------------
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith ARIA_TEMPLATE: '<div/>',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith ITEM_TEMPLATE: '<li/>',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith LIST_TEMPLATE: '<ul/>',
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith // -- Lifecycle Prototype Methods ------------------------------------------
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith initializer: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var inputNode = this.get('inputNode');
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!inputNode) {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith Y.error('No inputNode specified.');
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith this._inputNode = inputNode;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._listEvents = [];
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith // This ensures that the list is rendered inside the same parent as the
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith // input node by default, which is necessary for proper ARIA support.
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith this.DEF_PARENT_NODE = inputNode.get('parentNode');
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith // Cache commonly used classnames and selectors for performance.
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith this[_CLASS_ITEM] = this.getClassName(ITEM);
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith this[_CLASS_ITEM_ACTIVE] = this.getClassName(ITEM, 'active');
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith this[_CLASS_ITEM_HOVER] = this.getClassName(ITEM, 'hover');
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith this[_SELECTOR_ITEM] = '.' + this[_CLASS_ITEM];
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith /**
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith Fires when an autocomplete suggestion is selected from the list,
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith typically via a keyboard action or mouse click.
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @event select
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith @param {Node} itemNode List item node that was selected.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {Object} result AutoComplete result object.
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith @preventable _defSelectFn
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith this.publish(EVT_SELECT, {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith defaultFn: this._defSelectFn
9327ef7ad1fee11b0e494b97cc07386565326c03Luke Smith });
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith destructor: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith while (this._listEvents.length) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._listEvents.pop().detach();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (this._ariaNode) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._ariaNode.remove().destroy(true);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith bindUI: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._bindInput();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._bindList();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith renderUI: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var ariaNode = this._createAriaNode(),
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith boundingBox = this.get('boundingBox'),
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith contentBox = this.get('contentBox'),
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith inputNode = this._inputNode,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith listNode = this._createListNode(),
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith parentNode = inputNode.get('parentNode');
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith inputNode.addClass(this.getClassName('input')).setAttrs({
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith 'aria-autocomplete': LIST,
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith 'aria-expanded' : false,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith 'aria-owns' : listNode.get('id')
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith });
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // ARIA node must be outside the widget or announcements won't be made
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // when the widget is hidden.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith parentNode.append(ariaNode);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // Add an iframe shim for IE6.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (useShim) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith boundingBox.plug(Y.Plugin.Shim);
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // Force position: absolute on the boundingBox. This works around a
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith // potential CSS loading race condition in Gecko that can cause the
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // boundingBox to become relatively positioned, which is all kinds of
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // no good.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith boundingBox.setStyle('position', 'absolute');
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._ariaNode = ariaNode;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._boundingBox = boundingBox;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._contentBox = contentBox;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._listNode = listNode;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._parentNode = parentNode;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith syncUI: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // No need to call _syncPosition() here; the other _sync methods will
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // call it when necessary.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._syncResults();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._syncVisibility();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // -- Public Prototype Methods ---------------------------------------------
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Hides the list, unless the `alwaysShowList` attribute is `true`.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method hide
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @see show
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @chainable
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith hide: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return this.get(ALWAYS_SHOW_LIST) ? this : this.set(VISIBLE, false);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Selects the specified _itemNode_, or the current `activeItem` if _itemNode_
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith is not specified.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method selectItem
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {Node} [itemNode] Item node to select.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {EventFacade} [originEvent] Event that triggered the selection, if
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith any.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @chainable
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith selectItem: function (itemNode, originEvent) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (itemNode) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!itemNode.hasClass(this[_CLASS_ITEM])) {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith return this;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith } else {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith itemNode = this.get(ACTIVE_ITEM);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!itemNode) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return this;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.fire(EVT_SELECT, {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith itemNode : itemNode,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith originEvent: originEvent || null,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith result : itemNode.getData(RESULT)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith });
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return this;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // -- Protected Prototype Methods ------------------------------------------
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Activates the next item after the currently active item. If there is no next
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith item and the `circular` attribute is `true`, focus will wrap back to the
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith input node.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _activateNextItem
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @chainable
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith @protected
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _activateNextItem: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var item = this.get(ACTIVE_ITEM),
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith nextItem;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (item) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith nextItem = item.next(this[_SELECTOR_ITEM]) ||
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith (this.get(CIRCULAR) ? null : item);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith } else {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith nextItem = this._getFirstItemNode();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.set(ACTIVE_ITEM, nextItem);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith return this;
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith },
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Activates the item previous to the currently active item. If there is no
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith previous item and the `circular` attribute is `true`, focus will wrap back
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith to the input node.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _activatePrevItem
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @chainable
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _activatePrevItem: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var item = this.get(ACTIVE_ITEM),
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith prevItem = item ? item.previous(this[_SELECTOR_ITEM]) :
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.get(CIRCULAR) && this._getLastItemNode();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.set(ACTIVE_ITEM, prevItem || null);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return this;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Appends the specified result _items_ to the list inside a new item node.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _add
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {Array|Node|HTMLElement|String} items Result item or array of
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith result items.
0cd29719d36de1f7e3d0043f5d6fafb990a7b9e0Luke Smith @return {NodeList} Added nodes.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _add: function (items) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var itemNodes = [];
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith YArray.each(Lang.isArray(items) ? items : [items], function (item) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith itemNodes.push(this._createItemNode(item).setData(RESULT, item));
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith }, this);
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith itemNodes = Y.all(itemNodes);
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith this._listNode.append(itemNodes.toFrag());
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith return itemNodes;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Updates the ARIA live region with the specified message.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _ariaSay
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {String} stringId String id (from the `strings` attribute) of the
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith message to speak.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {Object} [subs] Substitutions for placeholders in the string.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _ariaSay: function (stringId, subs) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var message = this.get('strings.' + stringId);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._ariaNode.setContent(subs ? Lang.sub(message, subs) : message);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Binds `inputNode` events and behavior.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _bindInput
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _bindInput: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var inputNode = this._inputNode,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith alignNode, alignWidth, tokenInput;
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // Null align means we can auto-align. Set align to false to prevent
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // auto-alignment, or a valid alignment config to customize the
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // alignment.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (this.get('align') === null) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // If this is a tokenInput, align with its bounding box.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // Otherwise, align with the inputNode. Bit of a cheat.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith tokenInput = this.get('tokenInput');
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith alignNode = (tokenInput && tokenInput.get('boundingBox')) || inputNode;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.set('align', {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith node : alignNode,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith points: ['tl', 'bl']
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith });
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // If no width config is set, attempt to set the list's width to the
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // width of the alignment node. If the alignment node's width is
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // falsy, do nothing.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!this.get(WIDTH) && (alignWidth = alignNode.get('offsetWidth'))) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.set(WIDTH, alignWidth);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // Attach inputNode events.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._listEvents.concat([
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith inputNode.after('blur', this._afterListInputBlur, this),
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith inputNode.after('focus', this._afterListInputFocus, this)
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith ]);
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith },
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith /**
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith Binds list events.
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith @method _bindList
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith @protected
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith **/
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith _bindList: function () {
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith this._listEvents.concat([
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith Y.on('windowresize', this._syncPosition, this),
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith this.after({
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith blur : this._afterListBlur,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith focus : this._afterListFocus,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith mouseover: this._afterMouseOver,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith mouseout : this._afterMouseOut,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith activeItemChange : this._afterActiveItemChange,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith alwaysShowListChange: this._afterAlwaysShowListChange,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith hoveredItemChange : this._afterHoveredItemChange,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith resultsChange : this._afterResultsChange,
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith visibleChange : this._afterVisibleChange
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith }),
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._listNode.delegate('click', this._onItemClick,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this[_SELECTOR_ITEM], this)
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith ]);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Clears the contents of the tray.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith @method _clear
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith @protected
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _clear: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.set(ACTIVE_ITEM, null);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._set(HOVERED_ITEM, null);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._listNode.get('children').remove(true);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Creates and returns an ARIA live region node.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _createAriaNode
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @return {Node} ARIA node.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _createAriaNode: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var ariaNode = Node.create(this.ARIA_TEMPLATE);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return ariaNode.addClass(this.getClassName('aria')).setAttrs({
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith 'aria-live': 'polite',
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith role : 'status'
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith });
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Creates and returns an item node with the specified _content_.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _createItemNode
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {Object} result Result object.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @return {Node} Item node.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _createItemNode: function (result) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var itemNode = Node.create(this.ITEM_TEMPLATE);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return itemNode.addClass(this[_CLASS_ITEM]).setAttrs({
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith id : Y.stamp(itemNode),
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith role: 'option'
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }).setAttribute('data-text', result.text).append(result.display);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Creates and returns a list node. If the `listNode` attribute is already set
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith to an existing node, that node will be used.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _createListNode
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @return {Node} List node.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith _createListNode: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var listNode = this.get('listNode') || Node.create(this.LIST_TEMPLATE);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
abf34f3b3d65331ec654c9980a6d60d7f9701bfeLuke Smith listNode.addClass(this.getClassName(LIST)).setAttrs({
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith id : Y.stamp(listNode),
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith role: 'listbox'
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith });
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._set('listNode', listNode);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.get('contentBox').append(listNode);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return listNode;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Gets the first item node in the list, or `null` if the list is empty.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _getFirstItemNode
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith @return {Node|null}
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _getFirstItemNode: function () {
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith return this._listNode.one(this[_SELECTOR_ITEM]);
9327ef7ad1fee11b0e494b97cc07386565326c03Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Gets the last item node in the list, or `null` if the list is empty.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _getLastItemNode
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith @return {Node|null}
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _getLastItemNode: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return this._listNode.one(this[_SELECTOR_ITEM] + ':last-child');
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Synchronizes the result list's position and alignment.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _syncPosition
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith **/
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith _syncPosition: function () {
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith // Force WidgetPositionAlign to refresh its alignment.
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith this._syncUIPosAlign();
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith // Resize the IE6 iframe shim to match the list's dimensions.
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith this._syncShim();
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith },
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith /**
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith Synchronizes the results displayed in the list with those in the _results_
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith argument, or with the `results` attribute if an argument is not provided.
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _syncResults
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {Array} [results] Results.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _syncResults: function (results) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!results) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith results = this.get(RESULTS);
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._clear();
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (results.length) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._add(results);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._ariaSay('items_available');
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._syncPosition();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (this.get('activateFirstItem') && !this.get(ACTIVE_ITEM)) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.set(ACTIVE_ITEM, this._getFirstItemNode());
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Synchronizes the size of the iframe shim used for IE6 and lower. In other
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith browsers, this method is a noop.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _syncShim
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _syncShim: useShim ? function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._boundingBox.shim.sync();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith } : function () {},
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Synchronizes the visibility of the tray with the _visible_ argument, or with
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith the `visible` attribute if an argument is not provided.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _syncVisibility
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {Boolean} [visible] Visibility.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _syncVisibility: function (visible) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (this.get(ALWAYS_SHOW_LIST)) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith visible = true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.set(VISIBLE, visible);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (typeof visible === 'undefined') {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith visible = this.get(VISIBLE);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._inputNode.set('aria-expanded', visible);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._boundingBox.set('aria-hidden', !visible);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (visible) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._syncPosition();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith } else {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.set(ACTIVE_ITEM, null);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._set(HOVERED_ITEM, null);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // Force a reflow to work around a glitch in IE6 and 7 where some of
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // the contents of the list will sometimes remain visible after the
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith // container is hidden.
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith this._boundingBox.get('offsetWidth');
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith }
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith // In some pages, IE7 fails to repaint the contents of the list after it
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith // becomes visible. Toggling a bogus class on the body forces a repaint
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith // that fixes the issue.
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith if (Y.UA.ie === 7) {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith Y.one('body')
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith .addClass('yui3-ie7-sucks')
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith .removeClass('yui3-ie7-sucks');
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith }
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith },
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith // -- Protected Event Handlers ---------------------------------------------
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith /**
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith Handles `activeItemChange` events.
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith @method _afterActiveItemChange
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith @param {EventTarget} e
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith @protected
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith **/
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith _afterActiveItemChange: function (e) {
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith var inputNode = this._inputNode,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith newVal = e.newVal,
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith prevVal = e.prevVal,
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith node;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith // The previous item may have disappeared by the time this handler runs,
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith // so we need to be careful.
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith if (prevVal && prevVal._node) {
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith prevVal.removeClass(this[_CLASS_ITEM_ACTIVE]);
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith }
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith if (newVal) {
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith newVal.addClass(this[_CLASS_ITEM_ACTIVE]);
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith inputNode.set('aria-activedescendant', newVal.get(ID));
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith } else {
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith inputNode.removeAttribute('aria-activedescendant');
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith }
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith if (this.get('scrollIntoView')) {
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith node = newVal || inputNode;
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith if (!node.inRegion(Y.DOM.viewportRegion(), true)
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith || !node.inRegion(this._contentBox, true)) {
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith node.scrollIntoView();
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith }
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith }
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith },
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith /**
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith Handles `alwaysShowListChange` events.
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith @method _afterAlwaysShowListChange
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith @param {EventTarget} e
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith @protected
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith **/
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith _afterAlwaysShowListChange: function (e) {
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith this.set(VISIBLE, e.newVal || this.get(RESULTS).length > 0);
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith },
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith /**
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith Handles `hoveredItemChange` events.
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith
e0faaaef9dd138950007532eac3754c0290039b4Luke Smith @method _afterHoveredItemChange
8652e2d20f8ea9c9bfe21217ba427cf0d85ada9aLuke Smith @param {EventTarget} e
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _afterHoveredItemChange: function (e) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var newVal = e.newVal,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith prevVal = e.prevVal;
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith if (prevVal) {
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith prevVal.removeClass(this[_CLASS_ITEM_HOVER]);
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith }
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith if (newVal) {
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith newVal.addClass(this[_CLASS_ITEM_HOVER]);
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith }
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith },
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith Handles list blur events.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _afterListBlur
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _afterListBlur: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._listFocused = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // Hide the list unless focus switched to the input node.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!this._listInputFocused) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.hide();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Handles list focus events.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _afterListFocus
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _afterListFocus: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._listFocused = true;
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Handles `inputNode` blur events.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _afterListInputBlur
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith _afterListInputBlur: function () {
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith this._listInputFocused = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
35eeab4975a1c9e62cf466455a59e80ba5e00fb0Luke Smith // Hide the list on inputNode blur events, unless the mouse is currently
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // over the list (which indicates that the user is probably interacting
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // with it). The _lastInputKey property comes from the
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // autocomplete-list-keys module.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if ((!this._mouseOverList && !this._listFocused)
35eeab4975a1c9e62cf466455a59e80ba5e00fb0Luke Smith || this._lastInputKey === KEY_TAB) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.hide();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Handles `inputNode` focus events.
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _afterListInputFocus
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _afterListInputFocus: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._listInputFocused = true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith /**
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith Handles `mouseover` events.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _afterMouseOver
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith @param {EventTarget} e
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith @protected
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _afterMouseOver: function (e) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var itemNode = e.domEvent.target.ancestor(this[_SELECTOR_ITEM], true);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._mouseOverList = true;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (itemNode) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._set(HOVERED_ITEM, itemNode);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Handles `mouseout` events.
35eeab4975a1c9e62cf466455a59e80ba5e00fb0Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @method _afterMouseOut
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @param {EventTarget} e
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @protected
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _afterMouseOut: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._mouseOverList = false;
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this._set(HOVERED_ITEM, null);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // This takes care of the edge case where the user right-clicks on a
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // list item, then clicks elsewhere in the document.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith if (!this._listFocused && !this._listInputFocused) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.hide();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Handles `resultsChange` events.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith @method _afterResultsChange
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith @param {EventFacade} e
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith @protected
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith **/
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith _afterResultsChange: function (e) {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith this._syncResults(e.newVal);
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith if (!this.get(ALWAYS_SHOW_LIST)) {
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith this.set(VISIBLE, !!e.newVal.length);
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith }
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith },
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith /**
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith Handles `visibleChange` events.
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith @method _afterVisibleChange
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith @param {EventFacade} e
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith @protected
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith **/
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith _afterVisibleChange: function (e) {
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith this._syncVisibility(!!e.newVal);
5800f4bbed853824dd8797caae32f78bcc9ef09bLuke Smith },
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Delegated event handler for item `click` events.
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith @method _onItemClick
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith @param {EventTarget} e
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith @protected
3cefe5340bfed84038e5816dbfbe7cec44f0df31Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith _onItemClick: function (e) {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith var itemNode = e.currentTarget;
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.set(ACTIVE_ITEM, itemNode);
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.selectItem(itemNode, e);
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith },
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith // -- Protected Default Event Handlers -------------------------------------
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith /**
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith Default `select` event handler.
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith @method _defSelectFn
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith @param {EventTarget} e
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith @protected
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith **/
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith _defSelectFn: function (e) {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith var text = e.result.text;
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith
d7a66fe2de41baa56b41e8b7b254d1f6a50a5135Luke Smith // TODO: support typeahead completion, etc.
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith this._inputNode.focus();
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith this._updateValue(text);
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith this._ariaSay('item_selected', {item: text});
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith this.hide();
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith}, {
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith ATTRS: {
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith /**
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith If `true`, the first item in the list will be activated by default when
c31ae0e3c3d2726907b1876b5fe81cfd94527d5dLuke Smith the list is initially displayed and when results change.
35eeab4975a1c9e62cf466455a59e80ba5e00fb0Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @attribute activateFirstItem
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @type Boolean
776dbe951677142d852d930b593a8ab05c406e83Luke Smith @default false
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith **/
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith activateFirstItem: {
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith value: false
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith },
12193f069c735c9fa68aa22d6b4a8ff1fc5b83f1Luke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith /**
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith Item that's currently active, if any. When the user presses enter, this
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith is the item that will be selected.
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @attribute activeItem
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith @type Node
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith activeItem: {
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith setter: Y.one,
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith value: null
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith If `true`, the list will remain visible even when there are no results
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith to display.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @attribute alwaysShowList
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @type Boolean
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @default false
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith alwaysShowList: {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith value: false
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith /**
4db02d4b38afe802ad625f6c389e106fdc7c26faLuke Smith If `true`, keyboard navigation will wrap around to the opposite end of
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith the list when navigating past the first or last item.
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
35eeab4975a1c9e62cf466455a59e80ba5e00fb0Luke Smith @attribute circular
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @type Boolean
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @default true
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith **/
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith circular: {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith value: true
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Item currently being hovered over by the mouse, if any.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @attribute hoveredItem
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @type Node|null
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @readOnly
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith hoveredItem: {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith readOnly: true,
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith value: null
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith Node that will contain result items.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @attribute listNode
35eeab4975a1c9e62cf466455a59e80ba5e00fb0Luke Smith @type Node|null
35eeab4975a1c9e62cf466455a59e80ba5e00fb0Luke Smith @initOnly
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith listNode: {
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith writeOnce: 'initOnly',
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith value: null
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith },
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith /**
c36390194c43d30adc1059a74fdf9f51a235b8a9Luke Smith If `true`, the viewport will be scrolled to ensure that the active list
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith item is visible when necessary.
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith @attribute scrollIntoView
35eeab4975a1c9e62cf466455a59e80ba5e00fb0Luke Smith @type Boolean
35eeab4975a1c9e62cf466455a59e80ba5e00fb0Luke Smith @default false
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith **/
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith scrollIntoView: {
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith value: false
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith },
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith /**
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith Translatable strings used by the AutoCompleteList widget.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @attribute strings
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @type Object
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith strings: {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith valueFn: function () {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith return Y.Intl.get('autocomplete-list');
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith /**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith If `true`, pressing the tab key while the list is visible will select
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith the active item, if any.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @attribute tabSelect
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @type Boolean
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith @default true
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith **/
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith tabSelect: {
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith value: true
d463aba91a07cde67f9ec9382bce464db5bcc9d3Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith // The "visible" attribute is documented in Widget.
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith visible: {
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith value: false
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith }
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith },
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith CSS_PREFIX: Y.ClassNameManager.getClassName('aclist')
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith});
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke SmithY.AutoCompleteList = List;
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith/**
b32d148b0052e1f874e9bc9803bef729bf859d97Luke SmithAlias for <a href="AutoCompleteList.html">`AutoCompleteList`</a>. See that class
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smithfor API docs.
ed51daad3a3ab15255ca10edef69d5f703d69adbLuke Smith
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith@class AutoComplete
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith**/
b32d148b0052e1f874e9bc9803bef729bf859d97Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke SmithY.AutoComplete = List;
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith}, '@VERSION@' ,{lang:['en'], skinnable:true, after:['autocomplete-sources'], requires:['autocomplete-base', 'event-resize', 'node-screen', 'selector-css3', 'shim-plugin', 'widget', 'widget-position', 'widget-position-align']});
16479f9c396537f36d0d9c5633b24df618eee1e6Luke Smith