[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
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 ) );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 25 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |