[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/autocomplete-list/ -> autocomplete-list-debug.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('autocomplete-list', function (Y, NAME) {
   9  
  10  /**
  11  Traditional autocomplete dropdown list widget, just like Mom used to make.
  12  
  13  @module autocomplete
  14  @submodule autocomplete-list
  15  **/
  16  
  17  /**
  18  Traditional autocomplete dropdown list widget, just like Mom used to make.
  19  
  20  @class AutoCompleteList
  21  @extends Widget
  22  @uses AutoCompleteBase
  23  @uses WidgetPosition
  24  @uses WidgetPositionAlign
  25  @constructor
  26  @param {Object} config Configuration object.
  27  **/
  28  
  29  var Lang   = Y.Lang,
  30      Node   = Y.Node,
  31      YArray = Y.Array,
  32  
  33      // Whether or not we need an iframe shim.
  34      useShim = Y.UA.ie && Y.UA.ie < 7,
  35  
  36      // keyCode constants.
  37      KEY_TAB = 9,
  38  
  39      // String shorthand.
  40      _CLASS_ITEM        = '_CLASS_ITEM',
  41      _CLASS_ITEM_ACTIVE = '_CLASS_ITEM_ACTIVE',
  42      _CLASS_ITEM_HOVER  = '_CLASS_ITEM_HOVER',
  43      _SELECTOR_ITEM     = '_SELECTOR_ITEM',
  44  
  45      ACTIVE_ITEM      = 'activeItem',
  46      ALWAYS_SHOW_LIST = 'alwaysShowList',
  47      CIRCULAR         = 'circular',
  48      HOVERED_ITEM     = 'hoveredItem',
  49      ID               = 'id',
  50      ITEM             = 'item',
  51      LIST             = 'list',
  52      RESULT           = 'result',
  53      RESULTS          = 'results',
  54      VISIBLE          = 'visible',
  55      WIDTH            = 'width',
  56  
  57      // Event names.
  58      EVT_SELECT = 'select',
  59  
  60  List = Y.Base.create('autocompleteList', Y.Widget, [
  61      Y.AutoCompleteBase,
  62      Y.WidgetPosition,
  63      Y.WidgetPositionAlign
  64  ], {
  65      // -- Prototype Properties -------------------------------------------------
  66      ARIA_TEMPLATE: '<div/>',
  67      ITEM_TEMPLATE: '<li/>',
  68      LIST_TEMPLATE: '<ul/>',
  69  
  70      // Widget automatically attaches delegated event handlers to everything in
  71      // Y.Node.DOM_EVENTS, including synthetic events. Since Widget's event
  72      // delegation won't work for the synthetic valuechange event, and since
  73      // it creates a name collision between the backcompat "valueChange" synth
  74      // event alias and AutoCompleteList's "valueChange" event for the "value"
  75      // attr, this hack is necessary in order to prevent Widget from attaching
  76      // valuechange handlers.
  77      UI_EVENTS: (function () {
  78          var uiEvents = Y.merge(Y.Node.DOM_EVENTS);
  79  
  80          delete uiEvents.valuechange;
  81          delete uiEvents.valueChange;
  82  
  83          return uiEvents;
  84      }()),
  85  
  86      // -- Lifecycle Prototype Methods ------------------------------------------
  87      initializer: function () {
  88          var inputNode = this.get('inputNode');
  89  
  90          if (!inputNode) {
  91              Y.error('No inputNode specified.');
  92              return;
  93          }
  94  
  95          this._inputNode  = inputNode;
  96          this._listEvents = [];
  97  
  98          // This ensures that the list is rendered inside the same parent as the
  99          // input node by default, which is necessary for proper ARIA support.
 100          this.DEF_PARENT_NODE = inputNode.get('parentNode');
 101  
 102          // Cache commonly used classnames and selectors for performance.
 103          this[_CLASS_ITEM]        = this.getClassName(ITEM);
 104          this[_CLASS_ITEM_ACTIVE] = this.getClassName(ITEM, 'active');
 105          this[_CLASS_ITEM_HOVER]  = this.getClassName(ITEM, 'hover');
 106          this[_SELECTOR_ITEM]     = '.' + this[_CLASS_ITEM];
 107  
 108          /**
 109          Fires when an autocomplete suggestion is selected from the list,
 110          typically via a keyboard action or mouse click.
 111  
 112          @event select
 113          @param {Node} itemNode List item node that was selected.
 114          @param {Object} result AutoComplete result object.
 115          @preventable _defSelectFn
 116          **/
 117          this.publish(EVT_SELECT, {
 118              defaultFn: this._defSelectFn
 119          });
 120      },
 121  
 122      destructor: function () {
 123          while (this._listEvents.length) {
 124              this._listEvents.pop().detach();
 125          }
 126  
 127          if (this._ariaNode) {
 128              this._ariaNode.remove().destroy(true);
 129          }
 130      },
 131  
 132      bindUI: function () {
 133          this._bindInput();
 134          this._bindList();
 135      },
 136  
 137      renderUI: function () {
 138          var ariaNode    = this._createAriaNode(),
 139              boundingBox = this.get('boundingBox'),
 140              contentBox  = this.get('contentBox'),
 141              inputNode   = this._inputNode,
 142              listNode    = this._createListNode(),
 143              parentNode  = inputNode.get('parentNode');
 144  
 145          inputNode.addClass(this.getClassName('input')).setAttrs({
 146              'aria-autocomplete': LIST,
 147              'aria-expanded'    : false,
 148              'aria-owns'        : listNode.get('id')
 149          });
 150  
 151          // ARIA node must be outside the widget or announcements won't be made
 152          // when the widget is hidden.
 153          parentNode.append(ariaNode);
 154  
 155          // Add an iframe shim for IE6.
 156          if (useShim) {
 157              boundingBox.plug(Y.Plugin.Shim);
 158          }
 159  
 160          this._ariaNode    = ariaNode;
 161          this._boundingBox = boundingBox;
 162          this._contentBox  = contentBox;
 163          this._listNode    = listNode;
 164          this._parentNode  = parentNode;
 165      },
 166  
 167      syncUI: function () {
 168          // No need to call _syncPosition() here; the other _sync methods will
 169          // call it when necessary.
 170          this._syncResults();
 171          this._syncVisibility();
 172      },
 173  
 174      // -- Public Prototype Methods ---------------------------------------------
 175  
 176      /**
 177      Hides the list, unless the `alwaysShowList` attribute is `true`.
 178  
 179      @method hide
 180      @see show
 181      @chainable
 182      **/
 183      hide: function () {
 184          return this.get(ALWAYS_SHOW_LIST) ? this : this.set(VISIBLE, false);
 185      },
 186  
 187      /**
 188      Selects the specified _itemNode_, or the current `activeItem` if _itemNode_
 189      is not specified.
 190  
 191      @method selectItem
 192      @param {Node} [itemNode] Item node to select.
 193      @param {EventFacade} [originEvent] Event that triggered the selection, if
 194          any.
 195      @chainable
 196      **/
 197      selectItem: function (itemNode, originEvent) {
 198          if (itemNode) {
 199              if (!itemNode.hasClass(this[_CLASS_ITEM])) {
 200                  return this;
 201              }
 202          } else {
 203              itemNode = this.get(ACTIVE_ITEM);
 204  
 205              if (!itemNode) {
 206                  return this;
 207              }
 208          }
 209  
 210          this.fire(EVT_SELECT, {
 211              itemNode   : itemNode,
 212              originEvent: originEvent || null,
 213              result     : itemNode.getData(RESULT)
 214          });
 215  
 216          return this;
 217      },
 218  
 219      // -- Protected Prototype Methods ------------------------------------------
 220  
 221      /**
 222      Activates the next item after the currently active item. If there is no next
 223      item and the `circular` attribute is `true`, focus will wrap back to the
 224      input node.
 225  
 226      @method _activateNextItem
 227      @chainable
 228      @protected
 229      **/
 230      _activateNextItem: function () {
 231          var item = this.get(ACTIVE_ITEM),
 232              nextItem;
 233  
 234          if (item) {
 235              nextItem = item.next(this[_SELECTOR_ITEM]) ||
 236                      (this.get(CIRCULAR) ? null : item);
 237          } else {
 238              nextItem = this._getFirstItemNode();
 239          }
 240  
 241          this.set(ACTIVE_ITEM, nextItem);
 242  
 243          return this;
 244      },
 245  
 246      /**
 247      Activates the item previous to the currently active item. If there is no
 248      previous item and the `circular` attribute is `true`, focus will wrap back
 249      to the input node.
 250  
 251      @method _activatePrevItem
 252      @chainable
 253      @protected
 254      **/
 255      _activatePrevItem: function () {
 256          var item     = this.get(ACTIVE_ITEM),
 257              prevItem = item ? item.previous(this[_SELECTOR_ITEM]) :
 258                      this.get(CIRCULAR) && this._getLastItemNode();
 259  
 260          this.set(ACTIVE_ITEM, prevItem || null);
 261  
 262          return this;
 263      },
 264  
 265      /**
 266      Appends the specified result _items_ to the list inside a new item node.
 267  
 268      @method _add
 269      @param {Array|Node|HTMLElement|String} items Result item or array of
 270          result items.
 271      @return {NodeList} Added nodes.
 272      @protected
 273      **/
 274      _add: function (items) {
 275          var itemNodes = [];
 276  
 277          YArray.each(Lang.isArray(items) ? items : [items], function (item) {
 278              itemNodes.push(this._createItemNode(item).setData(RESULT, item));
 279          }, this);
 280  
 281          itemNodes = Y.all(itemNodes);
 282          this._listNode.append(itemNodes.toFrag());
 283  
 284          return itemNodes;
 285      },
 286  
 287      /**
 288      Updates the ARIA live region with the specified message.
 289  
 290      @method _ariaSay
 291      @param {String} stringId String id (from the `strings` attribute) of the
 292          message to speak.
 293      @param {Object} [subs] Substitutions for placeholders in the string.
 294      @protected
 295      **/
 296      _ariaSay: function (stringId, subs) {
 297          var message = this.get('strings.' + stringId);
 298          this._ariaNode.set('text', subs ? Lang.sub(message, subs) : message);
 299      },
 300  
 301      /**
 302      Binds `inputNode` events and behavior.
 303  
 304      @method _bindInput
 305      @protected
 306      **/
 307      _bindInput: function () {
 308          var inputNode = this._inputNode,
 309              alignNode, alignWidth, tokenInput;
 310  
 311          // Null align means we can auto-align. Set align to false to prevent
 312          // auto-alignment, or a valid alignment config to customize the
 313          // alignment.
 314          if (this.get('align') === null) {
 315              // If this is a tokenInput, align with its bounding box.
 316              // Otherwise, align with the inputNode. Bit of a cheat.
 317              tokenInput = this.get('tokenInput');
 318              alignNode  = (tokenInput && tokenInput.get('boundingBox')) || inputNode;
 319  
 320              this.set('align', {
 321                  node  : alignNode,
 322                  points: ['tl', 'bl']
 323              });
 324  
 325              // If no width config is set, attempt to set the list's width to the
 326              // width of the alignment node. If the alignment node's width is
 327              // falsy, do nothing.
 328              if (!this.get(WIDTH) && (alignWidth = alignNode.get('offsetWidth'))) {
 329                  this.set(WIDTH, alignWidth);
 330              }
 331          }
 332  
 333          // Attach inputNode events.
 334          this._listEvents = this._listEvents.concat([
 335              inputNode.after('blur',  this._afterListInputBlur, this),
 336              inputNode.after('focus', this._afterListInputFocus, this)
 337          ]);
 338      },
 339  
 340      /**
 341      Binds list events.
 342  
 343      @method _bindList
 344      @protected
 345      **/
 346      _bindList: function () {
 347          this._listEvents = this._listEvents.concat([
 348              Y.one('doc').after('click', this._afterDocClick, this),
 349              Y.one('win').after('windowresize', this._syncPosition, this),
 350  
 351              this.after({
 352                  mouseover: this._afterMouseOver,
 353                  mouseout : this._afterMouseOut,
 354  
 355                  activeItemChange    : this._afterActiveItemChange,
 356                  alwaysShowListChange: this._afterAlwaysShowListChange,
 357                  hoveredItemChange   : this._afterHoveredItemChange,
 358                  resultsChange       : this._afterResultsChange,
 359                  visibleChange       : this._afterVisibleChange
 360              }),
 361  
 362              this._listNode.delegate('click', this._onItemClick,
 363                      this[_SELECTOR_ITEM], this)
 364          ]);
 365      },
 366  
 367      /**
 368      Clears the contents of the tray.
 369  
 370      @method _clear
 371      @protected
 372      **/
 373      _clear: function () {
 374          this.set(ACTIVE_ITEM, null);
 375          this._set(HOVERED_ITEM, null);
 376  
 377          this._listNode.get('children').remove(true);
 378      },
 379  
 380      /**
 381      Creates and returns an ARIA live region node.
 382  
 383      @method _createAriaNode
 384      @return {Node} ARIA node.
 385      @protected
 386      **/
 387      _createAriaNode: function () {
 388          var ariaNode = Node.create(this.ARIA_TEMPLATE);
 389  
 390          return ariaNode.addClass(this.getClassName('aria')).setAttrs({
 391              'aria-live': 'polite',
 392              role       : 'status'
 393          });
 394      },
 395  
 396      /**
 397      Creates and returns an item node with the specified _content_.
 398  
 399      @method _createItemNode
 400      @param {Object} result Result object.
 401      @return {Node} Item node.
 402      @protected
 403      **/
 404      _createItemNode: function (result) {
 405          var itemNode = Node.create(this.ITEM_TEMPLATE);
 406  
 407          return itemNode.addClass(this[_CLASS_ITEM]).setAttrs({
 408              id  : Y.stamp(itemNode),
 409              role: 'option'
 410          }).setAttribute('data-text', result.text).append(result.display);
 411      },
 412  
 413      /**
 414      Creates and returns a list node. If the `listNode` attribute is already set
 415      to an existing node, that node will be used.
 416  
 417      @method _createListNode
 418      @return {Node} List node.
 419      @protected
 420      **/
 421      _createListNode: function () {
 422          var listNode = this.get('listNode') || Node.create(this.LIST_TEMPLATE);
 423  
 424          listNode.addClass(this.getClassName(LIST)).setAttrs({
 425              id  : Y.stamp(listNode),
 426              role: 'listbox'
 427          });
 428  
 429          this._set('listNode', listNode);
 430          this.get('contentBox').append(listNode);
 431  
 432          return listNode;
 433      },
 434  
 435      /**
 436      Gets the first item node in the list, or `null` if the list is empty.
 437  
 438      @method _getFirstItemNode
 439      @return {Node|null}
 440      @protected
 441      **/
 442      _getFirstItemNode: function () {
 443          return this._listNode.one(this[_SELECTOR_ITEM]);
 444      },
 445  
 446      /**
 447      Gets the last item node in the list, or `null` if the list is empty.
 448  
 449      @method _getLastItemNode
 450      @return {Node|null}
 451      @protected
 452      **/
 453      _getLastItemNode: function () {
 454          return this._listNode.one(this[_SELECTOR_ITEM] + ':last-child');
 455      },
 456  
 457      /**
 458      Synchronizes the result list's position and alignment.
 459  
 460      @method _syncPosition
 461      @protected
 462      **/
 463      _syncPosition: function () {
 464          // Force WidgetPositionAlign to refresh its alignment.
 465          this._syncUIPosAlign();
 466  
 467          // Resize the IE6 iframe shim to match the list's dimensions.
 468          this._syncShim();
 469      },
 470  
 471      /**
 472      Synchronizes the results displayed in the list with those in the _results_
 473      argument, or with the `results` attribute if an argument is not provided.
 474  
 475      @method _syncResults
 476      @param {Array} [results] Results.
 477      @protected
 478      **/
 479      _syncResults: function (results) {
 480          if (!results) {
 481              results = this.get(RESULTS);
 482          }
 483  
 484          this._clear();
 485  
 486          if (results.length) {
 487              this._add(results);
 488              this._ariaSay('items_available');
 489          }
 490  
 491          this._syncPosition();
 492  
 493          if (this.get('activateFirstItem') && !this.get(ACTIVE_ITEM)) {
 494              this.set(ACTIVE_ITEM, this._getFirstItemNode());
 495          }
 496      },
 497  
 498      /**
 499      Synchronizes the size of the iframe shim used for IE6 and lower. In other
 500      browsers, this method is a noop.
 501  
 502      @method _syncShim
 503      @protected
 504      **/
 505      _syncShim: useShim ? function () {
 506          var shim = this._boundingBox.shim;
 507  
 508          if (shim) {
 509              shim.sync();
 510          }
 511      } : function () {},
 512  
 513      /**
 514      Synchronizes the visibility of the tray with the _visible_ argument, or with
 515      the `visible` attribute if an argument is not provided.
 516  
 517      @method _syncVisibility
 518      @param {Boolean} [visible] Visibility.
 519      @protected
 520      **/
 521      _syncVisibility: function (visible) {
 522          if (this.get(ALWAYS_SHOW_LIST)) {
 523              visible = true;
 524              this.set(VISIBLE, visible);
 525          }
 526  
 527          if (typeof visible === 'undefined') {
 528              visible = this.get(VISIBLE);
 529          }
 530  
 531          this._inputNode.set('aria-expanded', visible);
 532          this._boundingBox.set('aria-hidden', !visible);
 533  
 534          if (visible) {
 535              this._syncPosition();
 536          } else {
 537              this.set(ACTIVE_ITEM, null);
 538              this._set(HOVERED_ITEM, null);
 539  
 540              // Force a reflow to work around a glitch in IE6 and 7 where some of
 541              // the contents of the list will sometimes remain visible after the
 542              // container is hidden.
 543              this._boundingBox.get('offsetWidth');
 544          }
 545  
 546          // In some pages, IE7 fails to repaint the contents of the list after it
 547          // becomes visible. Toggling a bogus class on the body forces a repaint
 548          // that fixes the issue.
 549          if (Y.UA.ie === 7) {
 550              // Note: We don't actually need to use ClassNameManager here. This
 551              // class isn't applying any actual styles; it's just frobbing the
 552              // body element to force a repaint. The actual class name doesn't
 553              // really matter.
 554              Y.one('body')
 555                  .addClass('yui3-ie7-sucks')
 556                  .removeClass('yui3-ie7-sucks');
 557          }
 558      },
 559  
 560      // -- Protected Event Handlers ---------------------------------------------
 561  
 562      /**
 563      Handles `activeItemChange` events.
 564  
 565      @method _afterActiveItemChange
 566      @param {EventFacade} e
 567      @protected
 568      **/
 569      _afterActiveItemChange: function (e) {
 570          var inputNode = this._inputNode,
 571              newVal    = e.newVal,
 572              prevVal   = e.prevVal,
 573              node;
 574  
 575          // The previous item may have disappeared by the time this handler runs,
 576          // so we need to be careful.
 577          if (prevVal && prevVal._node) {
 578              prevVal.removeClass(this[_CLASS_ITEM_ACTIVE]);
 579          }
 580  
 581          if (newVal) {
 582              newVal.addClass(this[_CLASS_ITEM_ACTIVE]);
 583              inputNode.set('aria-activedescendant', newVal.get(ID));
 584          } else {
 585              inputNode.removeAttribute('aria-activedescendant');
 586          }
 587  
 588          if (this.get('scrollIntoView')) {
 589              node = newVal || inputNode;
 590  
 591              if (!node.inRegion(Y.DOM.viewportRegion(), true)
 592                      || !node.inRegion(this._contentBox, true)) {
 593  
 594                  node.scrollIntoView();
 595              }
 596          }
 597      },
 598  
 599      /**
 600      Handles `alwaysShowListChange` events.
 601  
 602      @method _afterAlwaysShowListChange
 603      @param {EventFacade} e
 604      @protected
 605      **/
 606      _afterAlwaysShowListChange: function (e) {
 607          this.set(VISIBLE, e.newVal || this.get(RESULTS).length > 0);
 608      },
 609  
 610      /**
 611      Handles click events on the document. If the click is outside both the
 612      input node and the bounding box, the list will be hidden.
 613  
 614      @method _afterDocClick
 615      @param {EventFacade} e
 616      @protected
 617      @since 3.5.0
 618      **/
 619      _afterDocClick: function (e) {
 620          var boundingBox = this._boundingBox,
 621              target      = e.target;
 622  
 623          if (target !== this._inputNode && target !== boundingBox &&
 624                  !target.ancestor('#' + boundingBox.get('id'), true)){
 625              this.hide();
 626          }
 627      },
 628  
 629      /**
 630      Handles `hoveredItemChange` events.
 631  
 632      @method _afterHoveredItemChange
 633      @param {EventFacade} e
 634      @protected
 635      **/
 636      _afterHoveredItemChange: function (e) {
 637          var newVal  = e.newVal,
 638              prevVal = e.prevVal;
 639  
 640          if (prevVal) {
 641              prevVal.removeClass(this[_CLASS_ITEM_HOVER]);
 642          }
 643  
 644          if (newVal) {
 645              newVal.addClass(this[_CLASS_ITEM_HOVER]);
 646          }
 647      },
 648  
 649      /**
 650      Handles `inputNode` blur events.
 651  
 652      @method _afterListInputBlur
 653      @protected
 654      **/
 655      _afterListInputBlur: function () {
 656          this._listInputFocused = false;
 657  
 658          if (this.get(VISIBLE) &&
 659                  !this._mouseOverList &&
 660                  (this._lastInputKey !== KEY_TAB ||
 661                      !this.get('tabSelect') ||
 662                      !this.get(ACTIVE_ITEM))) {
 663              this.hide();
 664          }
 665      },
 666  
 667      /**
 668      Handles `inputNode` focus events.
 669  
 670      @method _afterListInputFocus
 671      @protected
 672      **/
 673      _afterListInputFocus: function () {
 674          this._listInputFocused = true;
 675      },
 676  
 677      /**
 678      Handles `mouseover` events.
 679  
 680      @method _afterMouseOver
 681      @param {EventFacade} e
 682      @protected
 683      **/
 684      _afterMouseOver: function (e) {
 685          var itemNode = e.domEvent.target.ancestor(this[_SELECTOR_ITEM], true);
 686  
 687          this._mouseOverList = true;
 688  
 689          if (itemNode) {
 690              this._set(HOVERED_ITEM, itemNode);
 691          }
 692      },
 693  
 694      /**
 695      Handles `mouseout` events.
 696  
 697      @method _afterMouseOut
 698      @param {EventFacade} e
 699      @protected
 700      **/
 701      _afterMouseOut: function () {
 702          this._mouseOverList = false;
 703          this._set(HOVERED_ITEM, null);
 704      },
 705  
 706      /**
 707      Handles `resultsChange` events.
 708  
 709      @method _afterResultsChange
 710      @param {EventFacade} e
 711      @protected
 712      **/
 713      _afterResultsChange: function (e) {
 714          this._syncResults(e.newVal);
 715  
 716          if (!this.get(ALWAYS_SHOW_LIST)) {
 717              this.set(VISIBLE, !!e.newVal.length);
 718          }
 719      },
 720  
 721      /**
 722      Handles `visibleChange` events.
 723  
 724      @method _afterVisibleChange
 725      @param {EventFacade} e
 726      @protected
 727      **/
 728      _afterVisibleChange: function (e) {
 729          this._syncVisibility(!!e.newVal);
 730      },
 731  
 732      /**
 733      Delegated event handler for item `click` events.
 734  
 735      @method _onItemClick
 736      @param {EventFacade} e
 737      @protected
 738      **/
 739      _onItemClick: function (e) {
 740          var itemNode = e.currentTarget;
 741  
 742          this.set(ACTIVE_ITEM, itemNode);
 743          this.selectItem(itemNode, e);
 744      },
 745  
 746      // -- Protected Default Event Handlers -------------------------------------
 747  
 748      /**
 749      Default `select` event handler.
 750  
 751      @method _defSelectFn
 752      @param {EventFacade} e
 753      @protected
 754      **/
 755      _defSelectFn: function (e) {
 756          var text = e.result.text;
 757  
 758          // TODO: support typeahead completion, etc.
 759          this._inputNode.focus();
 760          this._updateValue(text);
 761          this._ariaSay('item_selected', {item: text});
 762          this.hide();
 763      }
 764  }, {
 765      ATTRS: {
 766          /**
 767          If `true`, the first item in the list will be activated by default when
 768          the list is initially displayed and when results change.
 769  
 770          @attribute activateFirstItem
 771          @type Boolean
 772          @default false
 773          **/
 774          activateFirstItem: {
 775              value: false
 776          },
 777  
 778          /**
 779          Item that's currently active, if any. When the user presses enter, this
 780          is the item that will be selected.
 781  
 782          @attribute activeItem
 783          @type Node
 784          **/
 785          activeItem: {
 786              setter: Y.one,
 787              value: null
 788          },
 789  
 790          /**
 791          If `true`, the list will remain visible even when there are no results
 792          to display.
 793  
 794          @attribute alwaysShowList
 795          @type Boolean
 796          @default false
 797          **/
 798          alwaysShowList: {
 799              value: false
 800          },
 801  
 802          /**
 803          If `true`, keyboard navigation will wrap around to the opposite end of
 804          the list when navigating past the first or last item.
 805  
 806          @attribute circular
 807          @type Boolean
 808          @default true
 809          **/
 810          circular: {
 811              value: true
 812          },
 813  
 814          /**
 815          Item currently being hovered over by the mouse, if any.
 816  
 817          @attribute hoveredItem
 818          @type Node|null
 819          @readOnly
 820          **/
 821          hoveredItem: {
 822              readOnly: true,
 823              value: null
 824          },
 825  
 826          /**
 827          Node that will contain result items.
 828  
 829          @attribute listNode
 830          @type Node|null
 831          @initOnly
 832          **/
 833          listNode: {
 834              writeOnce: 'initOnly',
 835              value: null
 836          },
 837  
 838          /**
 839          If `true`, the viewport will be scrolled to ensure that the active list
 840          item is visible when necessary.
 841  
 842          @attribute scrollIntoView
 843          @type Boolean
 844          @default false
 845          **/
 846          scrollIntoView: {
 847              value: false
 848          },
 849  
 850          /**
 851          Translatable strings used by the AutoCompleteList widget.
 852  
 853          @attribute strings
 854          @type Object
 855          **/
 856          strings: {
 857              valueFn: function () {
 858                  return Y.Intl.get('autocomplete-list');
 859              }
 860          },
 861  
 862          /**
 863          If `true`, pressing the tab key while the list is visible will select
 864          the active item, if any.
 865  
 866          @attribute tabSelect
 867          @type Boolean
 868          @default true
 869          **/
 870          tabSelect: {
 871              value: true
 872          },
 873  
 874          // The "visible" attribute is documented in Widget.
 875          visible: {
 876              value: false
 877          }
 878      },
 879  
 880      CSS_PREFIX: Y.ClassNameManager.getClassName('aclist')
 881  });
 882  
 883  Y.AutoCompleteList = List;
 884  
 885  /**
 886  Alias for <a href="AutoCompleteList.html">`AutoCompleteList`</a>. See that class
 887  for API docs.
 888  
 889  @class AutoComplete
 890  **/
 891  
 892  Y.AutoComplete = List;
 893  
 894  
 895  }, '3.17.2', {
 896      "lang": [
 897          "en",
 898          "es",
 899          "hu",
 900          "it"
 901      ],
 902      "requires": [
 903          "autocomplete-base",
 904          "event-resize",
 905          "node-screen",
 906          "selector-css3",
 907          "shim-plugin",
 908          "widget",
 909          "widget-position",
 910          "widget-position-align"
 911      ],
 912      "skinnable": true
 913  });


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1