PageSourceSearch

https://www.libriincantina.it/wp-includes/js/jquery/ui/autocomplete.js?ver=1.14.2

js libriincantina.it collected 2026-10-02 07:12:44 UTC 16,181 bytes, 640 lines download raw bytes

vendor: 16,181 bytes, lines 1-640
1/*!
2 * jQuery UI Autocomplete 1.14.2
3 * https://jqueryui.com
4 *
5 * Copyright OpenJS Foundation and other contributors
6 * Released under the MIT license.
7 * https://jquery.org/license
8 */
9
10//>>label: Autocomplete
11//>>group: Widgets
12//>>description: Lists suggested words as the user is typing.
13//>>docs: https://api.jqueryui.com/autocomplete/
14//>>demos: https://jqueryui.com/autocomplete/
15//>>css.structure: ../../themes/base/core.css
16//>>css.structure: ../../themes/base/autocomplete.css
17//>>css.theme: ../../themes/base/theme.css
18
19( function( factory ) {
20	"use strict";
21
22	if ( typeof define === "function" && define.amd ) {
23
24		// AMD. Register as an anonymous module.
25		define( [
26			"jquery",
27			"./menu",
28			"../keycode",
29			"../position",
30			"../version",
31			"../widget"
32		], factory );
33	} else {
34
35		// Browser globals
36		factory( jQuery );
37	}
38} )( function( $ ) {
39"use strict";
40
41$.widget( "ui.autocomplete", {
42	version: "1.14.2",
43	defaultElement: "<input>",
44	options: {
45		appendTo: null,
46		autoFocus: false,
47		delay: 300,
48		minLength: 1,
49		position: {
50			my: "left top",
51			at: "left bottom",
52			collision: "none"
53		},
54		source: null,
55
56		// Callbacks
57		change: null,
58		close: null,
59		focus: null,
60		open: null,
61		response: null,
62		search: null,
63		select: null
64	},
65
66	requestIndex: 0,
67	pending: 0,
68	liveRegionTimer: null,
69
70	_create: function() {
71
72		// Some browsers only repeat keydown events, not keypress events,
73		// so we use the suppressKeyPress flag to determine if we've already
74		// handled the keydown event. #7269
75		// Unfortunately the code for & in keypress is the same as the up arrow,
76		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
77		// events when we know the keydown event was used to modify the
78		// search term. #7799
79		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
80			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
81			isTextarea = nodeName === "textarea",
82			isInput = nodeName === "input";
83
84		// Textareas are always multi-line
85		// Inputs are always single-line, even if inside a contentEditable element
86		// All other element types are determined by whether they're contentEditable
87		this.isMultiLine = isTextarea ||
88			!isInput && this.element.prop( "contentEditable" ) === "true";
89
90		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
91		this.isNewMenu = true;
92
93		this._addClass( "ui-autocomplete-input" );
94		this.element.attr( "autocomplete", "off" );
95
96		this._on( this.element, {
97			keydown: function( event ) {
98				if ( this.element.prop( "readOnly" ) ) {
99					suppressKeyPress = true;
100					suppressInput = true;
101					suppressKeyPressRepeat = true;
102					return;
103				}
104
105				suppressKeyPress = false;
106				suppressInput = false;
107				suppressKeyPressRepeat = false;
108				var keyCode = $.ui.keyCode;
109				switch ( event.keyCode ) {
110				case keyCode.PAGE_UP:
111					suppressKeyPress = true;
112					this._move( "previousPage", event );
113					break;
114				case keyCode.PAGE_DOWN:
115					suppressKeyPress = true;
116					this._move( "nextPage", event );
117					break;
118				case keyCode.UP:
119					suppressKeyPress = true;
120					this._keyEvent( "previous", event );
121					break;
122				case keyCode.DOWN:
123					suppressKeyPress = true;
124					this._keyEvent( "next", event );
125					break;
126				case keyCode.ENTER:
127
128					// when menu is open and has focus
129					if ( this.menu.active ) {
130
131						// #6055 - Opera still allows the keypress to occur
132						// which causes forms to submit
133						suppressKeyPress = true;
134						event.preventDefault();
135						this.menu.select( event );
136					}
137					break;
138				case keyCode.TAB:
139					if ( this.menu.active ) {
140						this.menu.select( event );
141					}
142					break;
143				case keyCode.ESCAPE:
144					if ( this.menu.element.is( ":visible" ) ) {
145						if ( !this.isMultiLine ) {
146							this._value( this.term );
147						}
148						this.close( event );
149
150						// Different browsers have different default behavior for escape
151						// Single press can mean undo or clear
152						event.preventDefault();
153					}
154					break;
155				default:
156					suppressKeyPressRepeat = true;
157
158					// search timeout should be triggered before the input value is changed
159					this._searchTimeout( event );
160					break;
161				}
162			},
163			keypress: function( event ) {
164				if ( suppressKeyPress ) {
165					suppressKeyPress = false;
166					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
167						event.preventDefault();
168					}
169					return;
170				}
171				if ( suppressKeyPressRepeat ) {
172					return;
173				}
174
175				// Replicate some key handlers to allow them to repeat in Firefox and Opera
176				var keyCode = $.ui.keyCode;
177				switch ( event.keyCode ) {
178				case keyCode.PAGE_UP:
179					this._move( "previousPage", event );
180					break;
181				case keyCode.PAGE_DOWN:
182					this._move( "nextPage", event );
183					break;
184				case keyCode.UP:
185					this._keyEvent( "previous", event );
186					break;
187				case keyCode.DOWN:
188					this._keyEvent( "next", event );
189					break;
190				}
191			},
192			input: function( event ) {
193				if ( suppressInput ) {
194					suppressInput = false;
195					event.preventDefault();
196					return;
197				}
198				this._searchTimeout( event );
199			},
200			focus: function() {
201				this.selectedItem = null;
202				this.previous = this._value();
203			},
204			blur: function( event ) {
205				clearTimeout( this.searching );
206				this.close( event );
207				this._change( event );
208			}
209		} );
210
211		this._initSource();
212		this.menu = $( "<ul>" )
213			.appendTo( this._appendTo() )
214			.menu( {
215
216				// disable ARIA support, the live region takes care of that
217				role: null
218			} )
219			.hide()
220			.menu( "instance" );
221
222		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
223		this._on( this.menu.element, {
224			mousedown: function( event ) {
225
226				// Prevent moving focus out of the text field
227				event.preventDefault();
228			},
229			menufocus: function( event, ui ) {
230				var label, item;
231
232				// Support: Firefox
233				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
234				if ( this.isNewMenu ) {
235					this.isNewMenu = false;
236					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
237						this.menu.blur();
238
239						this.document.one( "mousemove", function() {
240							$( event.target ).trigger( event.originalEvent );
241						} );
242
243						return;
244					}
245				}
246
247				item = ui.item.data( "ui-autocomplete-item" );
248				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
249
250					// use value to match what will end up in the input, if it was a key event
251					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
252						this._value( item.value );
253					}
254				}
255
256				// Announce the value in the liveRegion
257				label = ui.item.attr( "aria-label" ) || item.value;
258				if ( label && String.prototype.trim.call( label ).length ) {
259					clearTimeout( this.liveRegionTimer );
260					this.liveRegionTimer = this._delay( function() {
261						this.liveRegion.html( $( "<div>" ).text( label ) );
262					}, 100 );
263				}
264			},
265			menuselect: function( event, ui ) {
266				var item = ui.item.data( "ui-autocomplete-item" ),
267					previous = this.previous;
268
269				// Only trigger when focus was lost (click on menu)
270				if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
271					this.element.trigger( "focus" );
272					this.previous = previous;
273				}
274
275				if ( false !== this._trigger( "select", event, { item: item } ) ) {
276					this._value( item.value );
277				}
278
279				// reset the term after the select event
280				// this allows custom select handling to work properly
281				this.term = this._value();
282
283				this.close( event );
284				this.selectedItem = item;
285			}
286		} );
287
288		this.liveRegion = $( "<div>", {
289			role: "status",
290			"aria-live": "assertive",
291			"aria-relevant": "additions"
292		} )
293			.appendTo( this.document[ 0 ].body );
294
295		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
296
297		// Turning off autocomplete prevents the browser from remembering the
298		// value when navigating through history, so we re-enable autocomplete
299		// if the page is unloaded before the widget is destroyed. #7790
300		this._on( this.window, {
301			beforeunload: function() {
302				this.element.removeAttr( "autocomplete" );
303			}
304		} );
305	},
306
307	_destroy: function() {
308		clearTimeout( this.searching );
309		this.element.removeAttr( "autocomplete" );
310		this.menu.element.remove();
311		this.liveRegion.remove();
312	},
313
314	_setOption: function( key, value ) {
315		this._super( key, value );
316		if ( key === "source" ) {
317			this._initSource();
318		}
319		if ( key === "appendTo" ) {
320			this.menu.element.appendTo( this._appendTo() );
321		}
322		if ( key === "disabled" && value && this.xhr ) {
323			this.xhr.abort();
324		}
325	},
326
327	_isEventTargetInWidget: function( event ) {
328		var menuElement = this.menu.element[ 0 ];
329
330		return event.target === this.element[ 0 ] ||
331			event.target === menuElement ||
332			$.contains( menuElement, event.target );
333	},
334
335	_closeOnClickOutside: function( event ) {
336		if ( !this._isEventTargetInWidget( event ) ) {
337			this.close();
338		}
339	},
340
341	_appendTo: function() {
342		var element = this.options.appendTo;
343
344		if ( element ) {
345			element = element.jquery || element.nodeType ?
346				$( element ) :
347				this.document.find( element ).eq( 0 );
348		}
349
350		if ( !element || !element[ 0 ] ) {
351			element = this.element.closest( ".ui-front, dialog" );
352		}
353
354		if ( !element.length ) {
355			element = this.document[ 0 ].body;
356		}
357
358		return element;
359	},
360
361	_initSource: function() {
362		var array, url,
363			that = this;
364		if ( Array.isArray( this.options.source ) ) {
365			array = this.options.source;
366			this.source = function( request, response ) {
367				response( $.ui.autocomplete.filter( array, request.term ) );
368			};
369		} else if ( typeof this.options.source === "string" ) {
370			url = this.options.source;
371			this.source = function( request, response ) {
372				if ( that.xhr ) {
373					that.xhr.abort();
374				}
375				that.xhr = $.ajax( {
376					url: url,
377					data: request,
378					dataType: "json",
379					success: function( data ) {
380						response( data );
381					},
382					error: function() {
383						response( [] );
384					}
385				} );
386			};
387		} else {
388			this.source = this.options.source;
389		}
390	},
391
392	_searchTimeout: function( event ) {
393		clearTimeout( this.searching );
394		this.searching = this._delay( function() {
395
396			// Search if the value has changed, or if the user retypes the same value (see #7434)
397			var equalValues = this.term === this._value(),
398				menuVisible = this.menu.element.is( ":visible" ),
399				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
400
401			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
402				this.selectedItem = null;
403				this.search( null, event );
404			}
405		}, this.options.delay );
406	},
407
408	search: function( value, event ) {
409		value = value != null ? value : this._value();
410
411		// Always save the actual value, not the one passed as an argument
412		this.term = this._value();
413
414		if ( value.length < this.options.minLength ) {
415			return this.close( event );
416		}
417
418		if ( this._trigger( "search", event ) === false ) {
419			return;
420		}
421
422		return this._search( value );
423	},
424
425	_search: function( value ) {
426		this.pending++;
427		this._addClass( "ui-autocomplete-loading" );
428		this.cancelSearch = false;
429
430		this.source( { term: value }, this._response() );
431	},
432
433	_response: function() {
434		var index = ++this.requestIndex;
435
436		return function( content ) {
437			if ( index === this.requestIndex ) {
438				this.__response( content );
439			}
440
441			this.pending--;
442			if ( !this.pending ) {
443				this._removeClass( "ui-autocomplete-loading" );
444			}
445		}.bind( this );
446	},
447
448	__response: function( content ) {
449		if ( content ) {
450			content = this._normalize( content );
451		}
452		this._trigger( "response", null, { content: content } );
453		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
454			this._suggest( content );
455			this._trigger( "open" );
456		} else {
457
458			// use ._close() instead of .close() so we don't cancel future searches
459			this._close();
460		}
461	},
462
463	close: function( event ) {
464		this.cancelSearch = true;
465		this._close( event );
466	},
467
468	_close: function( event ) {
469
470		// Remove the handler that closes the menu on outside clicks
471		this._off( this.document, "mousedown" );
472
473		if ( this.menu.element.is( ":visible" ) ) {
474			this.menu.element.hide();
475			this.menu.blur();
476			this.isNewMenu = true;
477			this._trigger( "close", event );
478		}
479	},
480
481	_change: function( event ) {
482		if ( this.previous !== this._value() ) {
483			this._trigger( "change", event, { item: this.selectedItem } );
484		}
485	},
486
487	_normalize: function( items ) {
488
489		// assume all items have the right format when the first item is complete
490		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
491			return items;
492		}
493		return $.map( items, function( item ) {
494			if ( typeof item === "string" ) {
495				return {
496					label: item,
497					value: item
498				};
499			}
500			return $.extend( {}, item, {
501				label: item.label || item.value,
502				value: item.value || item.label
503			} );
504		} );
505	},
506
507	_suggest: function( items ) {
508		var ul = this.menu.element.empty();
509		this._renderMenu( ul, items );
510		this.isNewMenu = true;
511		this.menu.refresh();
512
513		// Size and position menu
514		ul.show();
515		this._resizeMenu();
516		ul.position( $.extend( {
517			of: this.element
518		}, this.options.position ) );
519
520		if ( this.options.autoFocus ) {
521			this.menu.next();
522		}
523
524		// Listen for interactions outside of the widget (#6642)
525		this._on( this.document, {
526			mousedown: "_closeOnClickOutside"
527		} );
528	},
529
530	_resizeMenu: function() {
531		var ul = this.menu.element;
532		ul.outerWidth( Math.max(
533
534			// Firefox wraps long text (possibly a rounding bug)
535			// so we add 1px to avoid the wrapping (#7513)
536			ul.width( "" ).outerWidth() + 1,
537			this.element.outerWidth()
538		) );
539	},
540
541	_renderMenu: function( ul, items ) {
542		var that = this;
543		$.each( items, function( index, item ) {
544			that._renderItemData( ul, item );
545		} );
546	},
547
548	_renderItemData: function( ul, item ) {
549		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
550	},
551
552	_renderItem: function( ul, item ) {
553		return $( "<li>" )
554			.append( $( "<div>" ).text( item.label ) )
555			.appendTo( ul );
556	},
557
558	_move: function( direction, event ) {
559		if ( !this.menu.element.is( ":visible" ) ) {
560			this.search( null, event );
561			return;
562		}
563		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
564				this.menu.isLastItem() && /^next/.test( direction ) ) {
565
566			if ( !this.isMultiLine ) {
567				this._value( this.term );
568			}
569
570			this.menu.blur();
571			return;
572		}
573		this.menu[ direction ]( event );
574	},
575
576	widget: function() {
577		return this.menu.element;
578	},
579
580	_value: function() {
581		return this.valueMethod.apply( this.element, arguments );
582	},
583
584	_keyEvent: function( keyEvent, event ) {
585		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
586			this._move( keyEvent, event );
587
588			// Prevents moving cursor to beginning/end of the text field in some browsers
589			event.preventDefault();
590		}
591	}
592} );
593
594$.extend( $.ui.autocomplete, {
595	escapeRegex: function( value ) {
596		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
597	},
598	filter: function( array, term ) {
599		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
600		return $.grep( array, function( value ) {
601			return matcher.test( value.label || value.value || value );
602		} );
603	}
604} );
605
606// Live region extension, adding a `messages` option
607// NOTE: This is an experimental API. We are still investigating
608// a full solution for string manipulation and internationalization.
609$.widget( "ui.autocomplete", $.ui.autocomplete, {
610	options: {
611		messages: {
612			noResults: "No search results.",
613			results: function( amount ) {
614				return amount + ( amount > 1 ? " results are" : " result is" ) +
615					" available, use up and down arrow keys to navigate.";
616			}
617		}
618	},
619
620	__response: function( content ) {
621		var message;
622		this._superApply( arguments );
623		if ( this.options.disabled || this.cancelSearch ) {
624			return;
625		}
626		if ( content && content.length ) {
627			message = this.options.messages.results( content.length );
628		} else {
629			message = this.options.messages.noResults;
630		}
631		clearTimeout( this.liveRegionTimer );
632		this.liveRegionTimer = this._delay( function() {
633			this.liveRegion.html( $( "<div>" ).text( message ) );
634		}, 100 );
635	}
636} );
637
638return $.ui.autocomplete;
639
640} );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.