PageSourceSearch

https://www.alfredstreet.org/wp-includes/js/jquery/ui/tooltip.js?ver=1.13.3

js alfredstreet.org collected 2026-09-24 09:57:26 UTC 14,476 bytes, 527 lines download raw bytes

vendor: 7,539 bytes, lines 1-281
1/*!
2 * jQuery UI Tooltip 1.13.3
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: Tooltip
11//>>group: Widgets
12//>>description: Shows additional information for any element on hover or focus.
13//>>docs: https://api.jqueryui.com/tooltip/
14//>>demos: https://jqueryui.com/tooltip/
15//>>css.structure: ../../themes/base/core.css
16//>>css.structure: ../../themes/base/tooltip.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			"../keycode",
28			"../position",
29			"../unique-id",
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.tooltip", {
42	version: "1.13.3",
43	options: {
44		classes: {
45			"ui-tooltip": "ui-corner-all ui-widget-shadow"
46		},
47		content: function() {
48			var title = $( this ).attr( "title" );
49
50			// Escape title, since we're going from an attribute to raw HTML
51			return $( "<a>" ).text( title ).html();
52		},
53		hide: true,
54
55		// Disabled elements have inconsistent behavior across browsers (#8661)
56		items: "[title]:not([disabled])",
57		position: {
58			my: "left top+15",
59			at: "left bottom",
60			collision: "flipfit flip"
61		},
62		show: true,
63		track: false,
64
65		// Callbacks
66		close: null,
67		open: null
68	},
69
70	_addDescribedBy: function( elem, id ) {
71		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
72		describedby.push( id );
73		elem
74			.data( "ui-tooltip-id", id )
75			.attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) );
76	},
77
78	_removeDescribedBy: function( elem ) {
79		var id = elem.data( "ui-tooltip-id" ),
80			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
81			index = $.inArray( id, describedby );
82
83		if ( index !== -1 ) {
84			describedby.splice( index, 1 );
85		}
86
87		elem.removeData( "ui-tooltip-id" );
88		describedby = String.prototype.trim.call( describedby.join( " " ) );
89		if ( describedby ) {
90			elem.attr( "aria-describedby", describedby );
91		} else {
92			elem.removeAttr( "aria-describedby" );
93		}
94	},
95
96	_create: function() {
97		this._on( {
98			mouseover: "open",
99			focusin: "open"
100		} );
101
102		// IDs of generated tooltips, needed for destroy
103		this.tooltips = {};
104
105		// IDs of parent tooltips where we removed the title attribute
106		this.parents = {};
107
108		// Append the aria-live region so tooltips announce correctly
109		this.liveRegion = $( "<div>" )
110			.attr( {
111				role: "log",
112				"aria-live": "assertive",
113				"aria-relevant": "additions"
114			} )
115			.appendTo( this.document[ 0 ].body );
116		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
117
118		this.disabledTitles = $( [] );
119	},
120
121	_setOption: function( key, value ) {
122		var that = this;
123
124		this._super( key, value );
125
126		if ( key === "content" ) {
127			$.each( this.tooltips, function( id, tooltipData ) {
128				that._updateContent( tooltipData.element );
129			} );
130		}
131	},
132
133	_setOptionDisabled: function( value ) {
134		this[ value ? "_disable" : "_enable" ]();
135	},
136
137	_disable: function() {
138		var that = this;
139
140		// Close open tooltips
141		$.each( this.tooltips, function( id, tooltipData ) {
142			var event = $.Event( "blur" );
143			event.target = event.currentTarget = tooltipData.element[ 0 ];
144			that.close( event, true );
145		} );
146
147		// Remove title attributes to prevent native tooltips
148		this.disabledTitles = this.disabledTitles.add(
149			this.element.find( this.options.items ).addBack()
150				.filter( function() {
151					var element = $( this );
152					if ( element.is( "[title]" ) ) {
153						return element
154							.data( "ui-tooltip-title", element.attr( "title" ) )
155							.removeAttr( "title" );
156					}
157				} )
158		);
159	},
160
161	_enable: function() {
162
163		// restore title attributes
164		this.disabledTitles.each( function() {
165			var element = $( this );
166			if ( element.data( "ui-tooltip-title" ) ) {
167				element.attr( "title", element.data( "ui-tooltip-title" ) );
168			}
169		} );
170		this.disabledTitles = $( [] );
171	},
172
173	open: function( event ) {
174		var that = this,
175			target = $( event ? event.target : this.element )
176
177				// we need closest here due to mouseover bubbling,
178				// but always pointing at the same event target
179				.closest( this.options.items );
180
181		// No element to show a tooltip for or the tooltip is already open
182		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
183			return;
184		}
185
186		if ( target.attr( "title" ) ) {
187			target.data( "ui-tooltip-title", target.attr( "title" ) );
188		}
189
190		target.data( "ui-tooltip-open", true );
191
192		// Kill parent tooltips, custom or native, for hover
193		if ( event && event.type === "mouseover" ) {
194			target.parents().each( function() {
195				var parent = $( this ),
196					blurEvent;
197				if ( parent.data( "ui-tooltip-open" ) ) {
198					blurEvent = $.Event( "blur" );
199					blurEvent.target = blurEvent.currentTarget = this;
200					that.close( blurEvent, true );
201				}
202				if ( parent.attr( "title" ) ) {
203					parent.uniqueId();
204					that.parents[ this.id ] = {
205						element: this,
206						title: parent.attr( "title" )
207					};
208					parent.attr( "title", "" );
209				}
210			} );
211		}
212
213		this._registerCloseHandlers( event, target );
214		this._updateContent( target, event );
215	},
216
217	_updateContent: function( target, event ) {
218		var content,
219			contentOption = this.options.content,
220			that = this,
221			eventType = event ? event.type : null;
222
223		if ( typeof contentOption === "string" || contentOption.nodeType ||
224				contentOption.jquery ) {
225			return this._open( event, target, contentOption );
226		}
227
228		content = contentOption.call( target[ 0 ], function( response ) {
229
230			// IE may instantly serve a cached response for ajax requests
231			// delay this call to _open so the other call to _open runs first
232			that._delay( function() {
233
234				// Ignore async response if tooltip was closed already
235				if ( !target.data( "ui-tooltip-open" ) ) {
236					return;
237				}
238
239				// JQuery creates a special event for focusin when it doesn't
240				// exist natively. To improve performance, the native event
241				// object is reused and the type is changed. Therefore, we can't
242				// rely on the type being correct after the event finished
243				// bubbling, so we set it back to the previous value. (#8740)
244				if ( event ) {
245					event.type = eventType;
246				}
247				this._open( event, target, response );
248			} );
249		} );
250		if ( content ) {
251			this._open( event, target, content );
252		}
253	},
254
255	_open: function( event, target, content ) {
256		var tooltipData, tooltip, delayedShow, a11yContent,
257			positionOption = $.extend( {}, this.options.position );
258
259		if ( !content ) {
260			return;
261		}
262
263		// Content can be updated multiple times. If the tooltip already
264		// exists, then just update the content and bail.
265		tooltipData = this._find( target );
266		if ( tooltipData ) {
267			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
268			return;
269		}
270
271		// If we have a title, clear it to prevent the native tooltip
272		// we have to check first to avoid defining a title if none exists
273		// (we don't want to cause an element to start matching [title])
274		//
275		// We use removeAttr only for key events, to allow IE to export the correct
276		// accessible attributes. For mouse events, set to empty string to avoid
277		// native tooltip showing up (happens only when removing inside mouseover).
278		if ( target.is( "[title]" ) ) {
279			if ( event && event.type === "mouseover" ) {
280				target.attr( "title", "" );
281			} else {
vendor: 4,683 bytes, lines 282-432
282				target.removeAttr( "title" );
283			}
284		}
285
286		tooltipData = this._tooltip( target );
287		tooltip = tooltipData.tooltip;
288		this._addDescribedBy( target, tooltip.attr( "id" ) );
289		tooltip.find( ".ui-tooltip-content" ).html( content );
290
291		// Support: Voiceover on OS X, JAWS on IE <= 9
292		// JAWS announces deletions even when aria-relevant="additions"
293		// Voiceover will sometimes re-read the entire log region's contents from the beginning
294		this.liveRegion.children().hide();
295		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
296		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
297		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
298		a11yContent.appendTo( this.liveRegion );
299
300		function position( event ) {
301			positionOption.of = event;
302			if ( tooltip.is( ":hidden" ) ) {
303				return;
304			}
305			tooltip.position( positionOption );
306		}
307		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
308			this._on( this.document, {
309				mousemove: position
310			} );
311
312			// trigger once to override element-relative positioning
313			position( event );
314		} else {
315			tooltip.position( $.extend( {
316				of: target
317			}, this.options.position ) );
318		}
319
320		tooltip.hide();
321
322		this._show( tooltip, this.options.show );
323
324		// Handle tracking tooltips that are shown with a delay (#8644). As soon
325		// as the tooltip is visible, position the tooltip using the most recent
326		// event.
327		// Adds the check to add the timers only when both delay and track options are set (#14682)
328		if ( this.options.track && this.options.show && this.options.show.delay ) {
329			delayedShow = this.delayedShow = setInterval( function() {
330				if ( tooltip.is( ":visible" ) ) {
331					position( positionOption.of );
332					clearInterval( delayedShow );
333				}
334			}, 13 );
335		}
336
337		this._trigger( "open", event, { tooltip: tooltip } );
338	},
339
340	_registerCloseHandlers: function( event, target ) {
341		var events = {
342			keyup: function( event ) {
343				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
344					var fakeEvent = $.Event( event );
345					fakeEvent.currentTarget = target[ 0 ];
346					this.close( fakeEvent, true );
347				}
348			}
349		};
350
351		// Only bind remove handler for delegated targets. Non-delegated
352		// tooltips will handle this in destroy.
353		if ( target[ 0 ] !== this.element[ 0 ] ) {
354			events.remove = function() {
355				var targetElement = this._find( target );
356				if ( targetElement ) {
357					this._removeTooltip( targetElement.tooltip );
358				}
359			};
360		}
361
362		if ( !event || event.type === "mouseover" ) {
363			events.mouseleave = "close";
364		}
365		if ( !event || event.type === "focusin" ) {
366			events.focusout = "close";
367		}
368		this._on( true, target, events );
369	},
370
371	close: function( event ) {
372		var tooltip,
373			that = this,
374			target = $( event ? event.currentTarget : this.element ),
375			tooltipData = this._find( target );
376
377		// The tooltip may already be closed
378		if ( !tooltipData ) {
379
380			// We set ui-tooltip-open immediately upon open (in open()), but only set the
381			// additional data once there's actually content to show (in _open()). So even if the
382			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
383			// the period between open() and _open().
384			target.removeData( "ui-tooltip-open" );
385			return;
386		}
387
388		tooltip = tooltipData.tooltip;
389
390		// Disabling closes the tooltip, so we need to track when we're closing
391		// to avoid an infinite loop in case the tooltip becomes disabled on close
392		if ( tooltipData.closing ) {
393			return;
394		}
395
396		// Clear the interval for delayed tracking tooltips
397		clearInterval( this.delayedShow );
398
399		// Only set title if we had one before (see comment in _open())
400		// If the title attribute has changed since open(), don't restore
401		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
402			target.attr( "title", target.data( "ui-tooltip-title" ) );
403		}
404
405		this._removeDescribedBy( target );
406
407		tooltipData.hiding = true;
408		tooltip.stop( true );
409		this._hide( tooltip, this.options.hide, function() {
410			that._removeTooltip( $( this ) );
411		} );
412
413		target.removeData( "ui-tooltip-open" );
414		this._off( target, "mouseleave focusout keyup" );
415
416		// Remove 'remove' binding only on delegated targets
417		if ( target[ 0 ] !== this.element[ 0 ] ) {
418			this._off( target, "remove" );
419		}
420		this._off( this.document, "mousemove" );
421
422		if ( event && event.type === "mouseleave" ) {
423			$.each( this.parents, function( id, parent ) {
424				$( parent.element ).attr( "title", parent.title );
425				delete that.parents[ id ];
426			} );
427		}
428
429		tooltipData.closing = true;
430		this._trigger( "close", event, { tooltip: tooltip } );
431		if ( !tooltipData.hiding ) {
432			tooltipData.closing = false;
vendor: 2,254 bytes, lines 433-527
433		}
434	},
435
436	_tooltip: function( element ) {
437		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
438			content = $( "<div>" ).appendTo( tooltip ),
439			id = tooltip.uniqueId().attr( "id" );
440
441		this._addClass( content, "ui-tooltip-content" );
442		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
443
444		tooltip.appendTo( this._appendTo( element ) );
445
446		return this.tooltips[ id ] = {
447			element: element,
448			tooltip: tooltip
449		};
450	},
451
452	_find: function( target ) {
453		var id = target.data( "ui-tooltip-id" );
454		return id ? this.tooltips[ id ] : null;
455	},
456
457	_removeTooltip: function( tooltip ) {
458
459		// Clear the interval for delayed tracking tooltips
460		clearInterval( this.delayedShow );
461
462		tooltip.remove();
463		delete this.tooltips[ tooltip.attr( "id" ) ];
464	},
465
466	_appendTo: function( target ) {
467		var element = target.closest( ".ui-front, dialog" );
468
469		if ( !element.length ) {
470			element = this.document[ 0 ].body;
471		}
472
473		return element;
474	},
475
476	_destroy: function() {
477		var that = this;
478
479		// Close open tooltips
480		$.each( this.tooltips, function( id, tooltipData ) {
481
482			// Delegate to close method to handle common cleanup
483			var event = $.Event( "blur" ),
484				element = tooltipData.element;
485			event.target = event.currentTarget = element[ 0 ];
486			that.close( event, true );
487
488			// Remove immediately; destroying an open tooltip doesn't use the
489			// hide animation
490			$( "#" + id ).remove();
491
492			// Restore the title
493			if ( element.data( "ui-tooltip-title" ) ) {
494
495				// If the title attribute has changed since open(), don't restore
496				if ( !element.attr( "title" ) ) {
497					element.attr( "title", element.data( "ui-tooltip-title" ) );
498				}
499				element.removeData( "ui-tooltip-title" );
500			}
501		} );
502		this.liveRegion.remove();
503	}
504} );
505
506// DEPRECATED
507// TODO: Switch return back to widget declaration at top of file when this is removed
508if ( $.uiBackCompat !== false ) {
509
510	// Backcompat for tooltipClass option
511	$.widget( "ui.tooltip", $.ui.tooltip, {
512		options: {
513			tooltipClass: null
514		},
515		_tooltip: function() {
516			var tooltipData = this._superApply( arguments );
517			if ( this.options.tooltipClass ) {
518				tooltipData.tooltip.addClass( this.options.tooltipClass );
519			}
520			return tooltipData;
521		}
522	} );
523}
524
525return $.ui.tooltip;
526
527} );

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.