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