2016-10-23 20:16:42 +02:00
|
|
|
/**
|
|
|
|
* Default settings for jQuery UI Autocomplete for use with non-hierarchical taxonomies.
|
|
|
|
*/
|
2016-10-15 00:40:28 +02:00
|
|
|
( function( $ ) {
|
2016-10-23 20:16:42 +02:00
|
|
|
if ( typeof window.tagsSuggestL10n === 'undefined' || typeof window.uiAutocompleteL10n === 'undefined' ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-10-15 00:40:28 +02:00
|
|
|
var tempID = 0;
|
2016-10-23 20:16:42 +02:00
|
|
|
var separator = window.tagsSuggestL10n.tagDelimiter || ',';
|
2016-10-15 00:40:28 +02:00
|
|
|
|
|
|
|
function split( val ) {
|
|
|
|
return val.split( new RegExp( separator + '\\s*' ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
function getLast( term ) {
|
|
|
|
return split( term ).pop();
|
|
|
|
}
|
|
|
|
|
2016-10-23 20:16:42 +02:00
|
|
|
/**
|
|
|
|
* Add UI Autocomplete to an input or textarea element with presets for use
|
|
|
|
* with non-hierarchical taxonomies.
|
|
|
|
*
|
|
|
|
* Example: `$( element ).wpTagsSuggest( options )`.
|
|
|
|
*
|
|
|
|
* The taxonomy can be passed in a `data-wp-taxonomy` attribute on the element or
|
|
|
|
* can be in `options.taxonomy`.
|
|
|
|
*
|
2016-11-17 19:28:30 +01:00
|
|
|
* @since 4.7.0
|
2016-10-23 20:16:42 +02:00
|
|
|
*
|
|
|
|
* @param {object} options Options that are passed to UI Autocomplete. Can be used to override the default settings.
|
|
|
|
* @returns {object} jQuery instance.
|
|
|
|
*/
|
2016-10-15 00:40:28 +02:00
|
|
|
$.fn.wpTagsSuggest = function( options ) {
|
|
|
|
var cache;
|
|
|
|
var last;
|
|
|
|
var $element = $( this );
|
|
|
|
|
|
|
|
options = options || {};
|
2016-10-23 20:16:42 +02:00
|
|
|
|
2016-10-15 00:40:28 +02:00
|
|
|
var taxonomy = options.taxonomy || $element.attr( 'data-wp-taxonomy' ) || 'post_tag';
|
2016-10-23 20:16:42 +02:00
|
|
|
|
2016-10-15 00:40:28 +02:00
|
|
|
delete( options.taxonomy );
|
|
|
|
|
|
|
|
options = $.extend( {
|
2016-10-23 20:16:42 +02:00
|
|
|
source: function( request, response ) {
|
2016-10-15 00:40:28 +02:00
|
|
|
var term;
|
|
|
|
|
|
|
|
if ( last === request.term ) {
|
|
|
|
response( cache );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
term = getLast( request.term );
|
|
|
|
|
|
|
|
$.get( window.ajaxurl, {
|
|
|
|
action: 'ajax-tag-search',
|
|
|
|
tax: taxonomy,
|
|
|
|
q: term
|
|
|
|
} ).always( function() {
|
|
|
|
$element.removeClass( 'ui-autocomplete-loading' ); // UI fails to remove this sometimes?
|
|
|
|
} ).done( function( data ) {
|
2016-10-23 20:16:42 +02:00
|
|
|
var tagName;
|
|
|
|
var tags = [];
|
2016-10-15 00:40:28 +02:00
|
|
|
|
|
|
|
if ( data ) {
|
|
|
|
data = data.split( '\n' );
|
|
|
|
|
2016-10-23 20:16:42 +02:00
|
|
|
for ( tagName in data ) {
|
2016-10-15 00:40:28 +02:00
|
|
|
var id = ++tempID;
|
|
|
|
|
2016-10-23 20:16:42 +02:00
|
|
|
tags.push({
|
2016-10-15 00:40:28 +02:00
|
|
|
id: id,
|
2016-10-23 20:16:42 +02:00
|
|
|
name: data[tagName]
|
2016-10-15 00:40:28 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-10-23 20:16:42 +02:00
|
|
|
cache = tags;
|
|
|
|
response( tags );
|
2016-10-15 00:40:28 +02:00
|
|
|
} else {
|
2016-10-23 20:16:42 +02:00
|
|
|
response( tags );
|
2016-10-15 00:40:28 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
|
|
|
last = request.term;
|
|
|
|
},
|
|
|
|
focus: function( event, ui ) {
|
|
|
|
$element.attr( 'aria-activedescendant', 'wp-tags-autocomplete-' + ui.item.id );
|
|
|
|
|
|
|
|
// Don't empty the input field when using the arrow keys to
|
|
|
|
// highlight items. See api.jqueryui.com/autocomplete/#event-focus
|
|
|
|
event.preventDefault();
|
|
|
|
},
|
|
|
|
select: function( event, ui ) {
|
|
|
|
var tags = split( $element.val() );
|
|
|
|
// Remove the last user input.
|
|
|
|
tags.pop();
|
|
|
|
// Append the new tag and an empty element to get one more separator at the end.
|
|
|
|
tags.push( ui.item.name, '' );
|
|
|
|
|
|
|
|
$element.val( tags.join( separator + ' ' ) );
|
|
|
|
|
|
|
|
if ( $.ui.keyCode.TAB === event.keyCode ) {
|
2016-10-23 20:16:42 +02:00
|
|
|
// Audible confirmation message when a tag has been selected.
|
|
|
|
window.wp.a11y.speak( window.tagsSuggestL10n.termSelected, 'assertive' );
|
2016-10-15 00:40:28 +02:00
|
|
|
event.preventDefault();
|
|
|
|
} else if ( $.ui.keyCode.ENTER === event.keyCode ) {
|
|
|
|
// Do not close Quick Edit / Bulk Edit
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
open: function() {
|
|
|
|
$element.attr( 'aria-expanded', 'true' );
|
|
|
|
},
|
|
|
|
close: function() {
|
|
|
|
$element.attr( 'aria-expanded', 'false' );
|
|
|
|
},
|
|
|
|
minLength: 2,
|
|
|
|
position: {
|
|
|
|
my: 'left top+2'
|
|
|
|
},
|
|
|
|
messages: {
|
2016-10-23 20:16:42 +02:00
|
|
|
noResults: window.uiAutocompleteL10n.noResults,
|
2016-10-15 00:40:28 +02:00
|
|
|
results: function( number ) {
|
2016-10-23 20:16:42 +02:00
|
|
|
if ( number > 1 ) {
|
|
|
|
return window.uiAutocompleteL10n.manyResults.replace( '%d', number );
|
2016-10-15 00:40:28 +02:00
|
|
|
}
|
2016-10-23 20:16:42 +02:00
|
|
|
|
|
|
|
return window.uiAutocompleteL10n.oneResult;
|
2016-10-15 00:40:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}, options );
|
|
|
|
|
|
|
|
$element.on( 'keydown', function() {
|
|
|
|
$element.removeAttr( 'aria-activedescendant' );
|
|
|
|
} )
|
|
|
|
.autocomplete( options )
|
|
|
|
.autocomplete( 'instance' )._renderItem = function( ul, item ) {
|
|
|
|
return $( '<li role="option" id="wp-tags-autocomplete-' + item.id + '">' )
|
|
|
|
.text( item.name )
|
|
|
|
.appendTo( ul );
|
|
|
|
};
|
|
|
|
|
|
|
|
$element.attr( {
|
|
|
|
'role': 'combobox',
|
|
|
|
'aria-autocomplete': 'list',
|
|
|
|
'aria-expanded': 'false',
|
|
|
|
'aria-owns': $element.autocomplete( 'widget' ).attr( 'id' )
|
|
|
|
} )
|
|
|
|
.on( 'focus', function() {
|
|
|
|
var inputValue = split( $element.val() ).pop();
|
|
|
|
|
|
|
|
// Don't trigger a search if the field is empty.
|
|
|
|
// Also, avoids screen readers announce `No search results`.
|
|
|
|
if ( inputValue ) {
|
|
|
|
$element.autocomplete( 'search' );
|
|
|
|
}
|
|
|
|
} )
|
|
|
|
// Returns a jQuery object containing the menu element.
|
|
|
|
.autocomplete( 'widget' )
|
|
|
|
.addClass( 'wp-tags-autocomplete' )
|
|
|
|
.attr( 'role', 'listbox' )
|
|
|
|
.removeAttr( 'tabindex' ) // Remove the `tabindex=0` attribute added by jQuery UI.
|
|
|
|
|
|
|
|
// Looks like Safari and VoiceOver need an `aria-selected` attribute. See ticket #33301.
|
|
|
|
// The `menufocus` and `menublur` events are the same events used to add and remove
|
|
|
|
// the `ui-state-focus` CSS class on the menu items. See jQuery UI Menu Widget.
|
|
|
|
.on( 'menufocus', function( event, ui ) {
|
|
|
|
ui.item.attr( 'aria-selected', 'true' );
|
|
|
|
})
|
|
|
|
.on( 'menublur', function() {
|
|
|
|
// The `menublur` event returns an object where the item is `null`
|
|
|
|
// so we need to find the active item with other means.
|
|
|
|
$( this ).find( '[aria-selected="true"]' ).removeAttr( 'aria-selected' );
|
|
|
|
});
|
2016-10-23 20:16:42 +02:00
|
|
|
|
2016-10-15 00:40:28 +02:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
}( jQuery ) );
|