[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-admin/js/ -> tags-suggest.js (source)

   1  /**
   2   * Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies.
   3   *
   4   * @output wp-admin/js/tags-suggest.js
   5   */
   6  ( function( $ ) {
   7      if ( typeof window.uiAutocompleteL10n === 'undefined' ) {
   8          return;
   9      }
  10  
  11      var tempID = 0;
  12      var separator = wp.i18n._x( ',', 'tag delimiter' ) || ',';
  13  
  14  	function split( val ) {
  15          return val.split( new RegExp( separator + '\\s*' ) );
  16      }
  17  
  18  	function getLast( term ) {
  19          return split( term ).pop();
  20      }
  21  
  22      /**
  23       * Add UI Autocomplete to an input or textarea element with presets for use
  24       * with non-hierarchical taxonomies.
  25       *
  26       * Example: `$( element ).wpTagsSuggest( options )`.
  27       *
  28       * The taxonomy can be passed in a `data-wp-taxonomy` attribute on the element or
  29       * can be in `options.taxonomy`.
  30       *
  31       * @since 4.7.0
  32       *
  33       * @param {Object} options Options that are passed to UI Autocomplete. Can be used to override the default settings.
  34       * @return {Object} jQuery instance.
  35       */
  36      $.fn.wpTagsSuggest = function( options ) {
  37          var cache;
  38          var last;
  39          var $element = $( this );
  40  
  41          // Do not initialize if the element doesn't exist.
  42          if ( ! $element.length ) {
  43              return this;
  44          }
  45  
  46          options = options || {};
  47  
  48          var taxonomy = options.taxonomy || $element.attr( 'data-wp-taxonomy' ) || 'post_tag';
  49  
  50          delete( options.taxonomy );
  51  
  52          options = $.extend( {
  53              source: function( request, response ) {
  54                  var term;
  55  
  56                  if ( last === request.term ) {
  57                      response( cache );
  58                      return;
  59                  }
  60  
  61                  term = getLast( request.term );
  62  
  63                  $.get( window.ajaxurl, {
  64                      action: 'ajax-tag-search',
  65                      tax: taxonomy,
  66                      q: term,
  67                      number: 20
  68                  } ).always( function() {
  69                      $element.removeClass( 'ui-autocomplete-loading' ); // UI fails to remove this sometimes?
  70                  } ).done( function( data ) {
  71                      var tagName;
  72                      var tags = [];
  73  
  74                      if ( data ) {
  75                          data = data.split( '\n' );
  76  
  77                          for ( tagName in data ) {
  78                              var id = ++tempID;
  79  
  80                              tags.push({
  81                                  id: id,
  82                                  name: data[tagName]
  83                              });
  84                          }
  85  
  86                          cache = tags;
  87                          response( tags );
  88                      } else {
  89                          response( tags );
  90                      }
  91                  } );
  92  
  93                  last = request.term;
  94              },
  95              focus: function( event, ui ) {
  96                  $element.attr( 'aria-activedescendant', 'wp-tags-autocomplete-' + ui.item.id );
  97  
  98                  // Don't empty the input field when using the arrow keys
  99                  // to highlight items. See api.jqueryui.com/autocomplete/#event-focus
 100                  event.preventDefault();
 101              },
 102              select: function( event, ui ) {
 103                  var tags = split( $element.val() );
 104                  // Remove the last user input.
 105                  tags.pop();
 106                  // Append the new tag and an empty element to get one more separator at the end.
 107                  tags.push( ui.item.name, '' );
 108  
 109                  $element.val( tags.join( separator + ' ' ) );
 110  
 111                  if ( $.ui.keyCode.TAB === event.keyCode ) {
 112                      // Audible confirmation message when a tag has been selected.
 113                      window.wp.a11y.speak( wp.i18n.__( 'Term selected.' ), 'assertive' );
 114                      event.preventDefault();
 115                  } else if ( $.ui.keyCode.ENTER === event.keyCode ) {
 116                      // If we're in the edit post Tags meta box, add the tag.
 117                      if ( window.tagBox ) {
 118                          window.tagBox.userAction = 'add';
 119                          window.tagBox.flushTags( $( this ).closest( '.tagsdiv' ) );
 120                      }
 121  
 122                      // Do not close Quick Edit / Bulk Edit.
 123                      event.preventDefault();
 124                      event.stopPropagation();
 125                  }
 126  
 127                  return false;
 128              },
 129              open: function() {
 130                  $element.attr( 'aria-expanded', 'true' );
 131              },
 132              close: function() {
 133                  $element.attr( 'aria-expanded', 'false' );
 134              },
 135              minLength: 2,
 136              position: {
 137                  my: 'left top+2',
 138                  at: 'left bottom',
 139                  collision: 'none'
 140              },
 141              messages: {
 142                  noResults: window.uiAutocompleteL10n.noResults,
 143                  results: function( number ) {
 144                      if ( number > 1 ) {
 145                          return window.uiAutocompleteL10n.manyResults.replace( '%d', number );
 146                      }
 147  
 148                      return window.uiAutocompleteL10n.oneResult;
 149                  }
 150              }
 151          }, options );
 152  
 153          $element.on( 'keydown', function() {
 154              $element.removeAttr( 'aria-activedescendant' );
 155          } );
 156  
 157          $element.autocomplete( options );
 158  
 159          // Ensure the autocomplete instance exists.
 160          if ( ! $element.autocomplete( 'instance' ) ) {
 161              return this;
 162          }
 163  
 164          $element.autocomplete( 'instance' )._renderItem = function( ul, item ) {
 165              return $( '<li role="option" id="wp-tags-autocomplete-' + item.id + '">' )
 166                  .text( item.name )
 167                  .appendTo( ul );
 168          };
 169  
 170          $element.attr( {
 171              'role': 'combobox',
 172              'aria-autocomplete': 'list',
 173              'aria-expanded': 'false',
 174              'aria-owns': $element.autocomplete( 'widget' ).attr( 'id' )
 175          } )
 176          .on( 'focus', function() {
 177              var inputValue = split( $element.val() ).pop();
 178  
 179              // Don't trigger a search if the field is empty.
 180              // Also, avoids screen readers announce `No search results`.
 181              if ( inputValue ) {
 182                  $element.autocomplete( 'search' );
 183              }
 184          } );
 185  
 186          // Returns a jQuery object containing the menu element.
 187          $element.autocomplete( 'widget' )
 188              .addClass( 'wp-tags-autocomplete' )
 189              .attr( 'role', 'listbox' )
 190              .removeAttr( 'tabindex' ) // Remove the `tabindex=0` attribute added by jQuery UI.
 191  
 192              /*
 193               * Looks like Safari and VoiceOver need an `aria-selected` attribute. See ticket #33301.
 194               * The `menufocus` and `menublur` events are the same events used to add and remove
 195               * the `ui-state-focus` CSS class on the menu items. See jQuery UI Menu Widget.
 196               */
 197              .on( 'menufocus', function( event, ui ) {
 198                  ui.item.attr( 'aria-selected', 'true' );
 199              })
 200              .on( 'menublur', function() {
 201                  // The `menublur` event returns an object where the item is `null`,
 202                  // so we need to find the active item with other means.
 203                  $( this ).find( '[aria-selected="true"]' ).removeAttr( 'aria-selected' );
 204              });
 205  
 206          return this;
 207      };
 208  
 209  }( jQuery ) );


Generated: Sat Apr 20 01:00:03 2024 Cross-referenced by PHPXref 0.7.1