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