root / drupal7 / sites / all / modules / jquery_update / replace / ui / ui / jquery.ui.tooltip.js @ 503b3f7b
1 | 503b3f7b | Assos Assos | /*!
|
---|---|---|---|
2 | * jQuery UI Tooltip 1.10.2
|
||
3 | * http://jqueryui.com
|
||
4 | *
|
||
5 | * Copyright 2013 jQuery Foundation and other contributors
|
||
6 | * Released under the MIT license.
|
||
7 | * http://jquery.org/license
|
||
8 | *
|
||
9 | * http://api.jqueryui.com/tooltip/
|
||
10 | *
|
||
11 | * Depends:
|
||
12 | * jquery.ui.core.js
|
||
13 | * jquery.ui.widget.js
|
||
14 | * jquery.ui.position.js
|
||
15 | */
|
||
16 | (function( $ ) { |
||
17 | |||
18 | var increments = 0; |
||
19 | |||
20 | function addDescribedBy( elem, id ) { |
||
21 | var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); |
||
22 | describedby.push( id ); |
||
23 | elem |
||
24 | .data( "ui-tooltip-id", id )
|
||
25 | .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); |
||
26 | } |
||
27 | |||
28 | function removeDescribedBy( elem ) { |
||
29 | var id = elem.data( "ui-tooltip-id" ), |
||
30 | describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), |
||
31 | index = $.inArray( id, describedby );
|
||
32 | if ( index !== -1 ) { |
||
33 | describedby.splice( index, 1 );
|
||
34 | } |
||
35 | |||
36 | elem.removeData( "ui-tooltip-id" );
|
||
37 | describedby = $.trim( describedby.join( " " ) ); |
||
38 | if ( describedby ) {
|
||
39 | elem.attr( "aria-describedby", describedby );
|
||
40 | } else {
|
||
41 | elem.removeAttr( "aria-describedby" );
|
||
42 | } |
||
43 | } |
||
44 | |||
45 | $.widget( "ui.tooltip", { |
||
46 | version: "1.10.2", |
||
47 | options: {
|
||
48 | content: function() { |
||
49 | // support: IE<9, Opera in jQuery <1.7
|
||
50 | // .text() can't accept undefined, so coerce to a string
|
||
51 | var title = $( this ).attr( "title" ) || ""; |
||
52 | // Escape title, since we're going from an attribute to raw HTML
|
||
53 | return $( "<a>" ).text( title ).html(); |
||
54 | }, |
||
55 | hide: true, |
||
56 | // Disabled elements have inconsistent behavior across browsers (#8661)
|
||
57 | items: "[title]:not([disabled])", |
||
58 | position: {
|
||
59 | my: "left top+15", |
||
60 | at: "left bottom", |
||
61 | collision: "flipfit flip" |
||
62 | }, |
||
63 | show: true, |
||
64 | tooltipClass: null, |
||
65 | track: false, |
||
66 | |||
67 | // callbacks
|
||
68 | close: null, |
||
69 | open: null |
||
70 | }, |
||
71 | |||
72 | _create: function() { |
||
73 | this._on({
|
||
74 | mouseover: "open", |
||
75 | focusin: "open" |
||
76 | }); |
||
77 | |||
78 | // IDs of generated tooltips, needed for destroy
|
||
79 | this.tooltips = {};
|
||
80 | // IDs of parent tooltips where we removed the title attribute
|
||
81 | this.parents = {};
|
||
82 | |||
83 | if ( this.options.disabled ) { |
||
84 | this._disable();
|
||
85 | } |
||
86 | }, |
||
87 | |||
88 | _setOption: function( key, value ) { |
||
89 | var that = this; |
||
90 | |||
91 | if ( key === "disabled" ) { |
||
92 | this[ value ? "_disable" : "_enable" ](); |
||
93 | this.options[ key ] = value;
|
||
94 | // disable element style changes
|
||
95 | return;
|
||
96 | } |
||
97 | |||
98 | this._super( key, value );
|
||
99 | |||
100 | if ( key === "content" ) { |
||
101 | $.each( this.tooltips, function( id, element ) { |
||
102 | that._updateContent( element ); |
||
103 | }); |
||
104 | } |
||
105 | }, |
||
106 | |||
107 | _disable: function() { |
||
108 | var that = this; |
||
109 | |||
110 | // close open tooltips
|
||
111 | $.each( this.tooltips, function( id, element ) { |
||
112 | var event = $.Event( "blur" ); |
||
113 | event.target = event.currentTarget = element[0];
|
||
114 | that.close( event, true );
|
||
115 | }); |
||
116 | |||
117 | // remove title attributes to prevent native tooltips
|
||
118 | this.element.find( this.options.items ).addBack().each(function() { |
||
119 | var element = $( this ); |
||
120 | if ( element.is( "[title]" ) ) { |
||
121 | element |
||
122 | .data( "ui-tooltip-title", element.attr( "title" ) ) |
||
123 | .attr( "title", "" ); |
||
124 | } |
||
125 | }); |
||
126 | }, |
||
127 | |||
128 | _enable: function() { |
||
129 | // restore title attributes
|
||
130 | this.element.find( this.options.items ).addBack().each(function() { |
||
131 | var element = $( this ); |
||
132 | if ( element.data( "ui-tooltip-title" ) ) { |
||
133 | element.attr( "title", element.data( "ui-tooltip-title" ) ); |
||
134 | } |
||
135 | }); |
||
136 | }, |
||
137 | |||
138 | open: function( event ) { |
||
139 | var that = this, |
||
140 | target = $( event ? event.target : this.element ) |
||
141 | // we need closest here due to mouseover bubbling,
|
||
142 | // but always pointing at the same event target
|
||
143 | .closest( this.options.items );
|
||
144 | |||
145 | // No element to show a tooltip for or the tooltip is already open
|
||
146 | if ( !target.length || target.data( "ui-tooltip-id" ) ) { |
||
147 | return;
|
||
148 | } |
||
149 | |||
150 | if ( target.attr( "title" ) ) { |
||
151 | target.data( "ui-tooltip-title", target.attr( "title" ) ); |
||
152 | } |
||
153 | |||
154 | target.data( "ui-tooltip-open", true ); |
||
155 | |||
156 | // kill parent tooltips, custom or native, for hover
|
||
157 | if ( event && event.type === "mouseover" ) { |
||
158 | target.parents().each(function() {
|
||
159 | var parent = $( this ), |
||
160 | blurEvent; |
||
161 | if ( parent.data( "ui-tooltip-open" ) ) { |
||
162 | blurEvent = $.Event( "blur" ); |
||
163 | blurEvent.target = blurEvent.currentTarget = this;
|
||
164 | that.close( blurEvent, true );
|
||
165 | } |
||
166 | if ( parent.attr( "title" ) ) { |
||
167 | parent.uniqueId(); |
||
168 | that.parents[ this.id ] = {
|
||
169 | element: this, |
||
170 | title: parent.attr( "title" ) |
||
171 | }; |
||
172 | parent.attr( "title", "" ); |
||
173 | } |
||
174 | }); |
||
175 | } |
||
176 | |||
177 | this._updateContent( target, event );
|
||
178 | }, |
||
179 | |||
180 | _updateContent: function( target, event ) { |
||
181 | var content,
|
||
182 | contentOption = this.options.content,
|
||
183 | that = this,
|
||
184 | eventType = event ? event.type : null;
|
||
185 | |||
186 | if ( typeof contentOption === "string" ) { |
||
187 | return this._open( event, target, contentOption ); |
||
188 | } |
||
189 | |||
190 | content = contentOption.call( target[0], function( response ) { |
||
191 | // ignore async response if tooltip was closed already
|
||
192 | if ( !target.data( "ui-tooltip-open" ) ) { |
||
193 | return;
|
||
194 | } |
||
195 | // IE may instantly serve a cached response for ajax requests
|
||
196 | // delay this call to _open so the other call to _open runs first
|
||
197 | that._delay(function() {
|
||
198 | // jQuery creates a special event for focusin when it doesn't
|
||
199 | // exist natively. To improve performance, the native event
|
||
200 | // object is reused and the type is changed. Therefore, we can't
|
||
201 | // rely on the type being correct after the event finished
|
||
202 | // bubbling, so we set it back to the previous value. (#8740)
|
||
203 | if ( event ) {
|
||
204 | event.type = eventType; |
||
205 | } |
||
206 | this._open( event, target, response );
|
||
207 | }); |
||
208 | }); |
||
209 | if ( content ) {
|
||
210 | this._open( event, target, content );
|
||
211 | } |
||
212 | }, |
||
213 | |||
214 | _open: function( event, target, content ) { |
||
215 | var tooltip, events, delayedShow,
|
||
216 | positionOption = $.extend( {}, this.options.position ); |
||
217 | |||
218 | if ( !content ) {
|
||
219 | return;
|
||
220 | } |
||
221 | |||
222 | // Content can be updated multiple times. If the tooltip already
|
||
223 | // exists, then just update the content and bail.
|
||
224 | tooltip = this._find( target );
|
||
225 | if ( tooltip.length ) {
|
||
226 | tooltip.find( ".ui-tooltip-content" ).html( content );
|
||
227 | return;
|
||
228 | } |
||
229 | |||
230 | // if we have a title, clear it to prevent the native tooltip
|
||
231 | // we have to check first to avoid defining a title if none exists
|
||
232 | // (we don't want to cause an element to start matching [title])
|
||
233 | //
|
||
234 | // We use removeAttr only for key events, to allow IE to export the correct
|
||
235 | // accessible attributes. For mouse events, set to empty string to avoid
|
||
236 | // native tooltip showing up (happens only when removing inside mouseover).
|
||
237 | if ( target.is( "[title]" ) ) { |
||
238 | if ( event && event.type === "mouseover" ) { |
||
239 | target.attr( "title", "" ); |
||
240 | } else {
|
||
241 | target.removeAttr( "title" );
|
||
242 | } |
||
243 | } |
||
244 | |||
245 | tooltip = this._tooltip( target );
|
||
246 | addDescribedBy( target, tooltip.attr( "id" ) );
|
||
247 | tooltip.find( ".ui-tooltip-content" ).html( content );
|
||
248 | |||
249 | function position( event ) { |
||
250 | positionOption.of = event; |
||
251 | if ( tooltip.is( ":hidden" ) ) { |
||
252 | return;
|
||
253 | } |
||
254 | tooltip.position( positionOption ); |
||
255 | } |
||
256 | if ( this.options.track && event && /^mouse/.test( event.type ) ) { |
||
257 | this._on( this.document, { |
||
258 | mousemove: position
|
||
259 | }); |
||
260 | // trigger once to override element-relative positioning
|
||
261 | position( event ); |
||
262 | } else {
|
||
263 | tooltip.position( $.extend({
|
||
264 | of: target
|
||
265 | }, this.options.position ) );
|
||
266 | } |
||
267 | |||
268 | tooltip.hide(); |
||
269 | |||
270 | this._show( tooltip, this.options.show ); |
||
271 | // Handle tracking tooltips that are shown with a delay (#8644). As soon
|
||
272 | // as the tooltip is visible, position the tooltip using the most recent
|
||
273 | // event.
|
||
274 | if ( this.options.show && this.options.show.delay ) { |
||
275 | delayedShow = this.delayedShow = setInterval(function() { |
||
276 | if ( tooltip.is( ":visible" ) ) { |
||
277 | position( positionOption.of ); |
||
278 | clearInterval( delayedShow ); |
||
279 | } |
||
280 | }, $.fx.interval );
|
||
281 | } |
||
282 | |||
283 | this._trigger( "open", event, { tooltip: tooltip } ); |
||
284 | |||
285 | events = { |
||
286 | keyup: function( event ) { |
||
287 | if ( event.keyCode === $.ui.keyCode.ESCAPE ) { |
||
288 | var fakeEvent = $.Event(event); |
||
289 | fakeEvent.currentTarget = target[0];
|
||
290 | this.close( fakeEvent, true ); |
||
291 | } |
||
292 | }, |
||
293 | remove: function() { |
||
294 | this._removeTooltip( tooltip );
|
||
295 | } |
||
296 | }; |
||
297 | if ( !event || event.type === "mouseover" ) { |
||
298 | events.mouseleave = "close";
|
||
299 | } |
||
300 | if ( !event || event.type === "focusin" ) { |
||
301 | events.focusout = "close";
|
||
302 | } |
||
303 | this._on( true, target, events ); |
||
304 | }, |
||
305 | |||
306 | close: function( event ) { |
||
307 | var that = this, |
||
308 | target = $( event ? event.currentTarget : this.element ), |
||
309 | tooltip = this._find( target );
|
||
310 | |||
311 | // disabling closes the tooltip, so we need to track when we're closing
|
||
312 | // to avoid an infinite loop in case the tooltip becomes disabled on close
|
||
313 | if ( this.closing ) { |
||
314 | return;
|
||
315 | } |
||
316 | |||
317 | // Clear the interval for delayed tracking tooltips
|
||
318 | clearInterval( this.delayedShow );
|
||
319 | |||
320 | // only set title if we had one before (see comment in _open())
|
||
321 | if ( target.data( "ui-tooltip-title" ) ) { |
||
322 | target.attr( "title", target.data( "ui-tooltip-title" ) ); |
||
323 | } |
||
324 | |||
325 | removeDescribedBy( target ); |
||
326 | |||
327 | tooltip.stop( true );
|
||
328 | this._hide( tooltip, this.options.hide, function() { |
||
329 | that._removeTooltip( $( this ) ); |
||
330 | }); |
||
331 | |||
332 | target.removeData( "ui-tooltip-open" );
|
||
333 | this._off( target, "mouseleave focusout keyup" ); |
||
334 | // Remove 'remove' binding only on delegated targets
|
||
335 | if ( target[0] !== this.element[0] ) { |
||
336 | this._off( target, "remove" ); |
||
337 | } |
||
338 | this._off( this.document, "mousemove" ); |
||
339 | |||
340 | if ( event && event.type === "mouseleave" ) { |
||
341 | $.each( this.parents, function( id, parent ) { |
||
342 | $( parent.element ).attr( "title", parent.title ); |
||
343 | delete that.parents[ id ];
|
||
344 | }); |
||
345 | } |
||
346 | |||
347 | this.closing = true; |
||
348 | this._trigger( "close", event, { tooltip: tooltip } ); |
||
349 | this.closing = false; |
||
350 | }, |
||
351 | |||
352 | _tooltip: function( element ) { |
||
353 | var id = "ui-tooltip-" + increments++, |
||
354 | tooltip = $( "<div>" ) |
||
355 | .attr({ |
||
356 | id: id,
|
||
357 | role: "tooltip" |
||
358 | }) |
||
359 | .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
|
||
360 | ( this.options.tooltipClass || "" ) ); |
||
361 | $( "<div>" ) |
||
362 | .addClass( "ui-tooltip-content" )
|
||
363 | .appendTo( tooltip ); |
||
364 | tooltip.appendTo( this.document[0].body ); |
||
365 | this.tooltips[ id ] = element;
|
||
366 | return tooltip;
|
||
367 | }, |
||
368 | |||
369 | _find: function( target ) { |
||
370 | var id = target.data( "ui-tooltip-id" ); |
||
371 | return id ? $( "#" + id ) : $(); |
||
372 | }, |
||
373 | |||
374 | _removeTooltip: function( tooltip ) { |
||
375 | tooltip.remove(); |
||
376 | delete this.tooltips[ tooltip.attr( "id" ) ]; |
||
377 | }, |
||
378 | |||
379 | _destroy: function() { |
||
380 | var that = this; |
||
381 | |||
382 | // close open tooltips
|
||
383 | $.each( this.tooltips, function( id, element ) { |
||
384 | // Delegate to close method to handle common cleanup
|
||
385 | var event = $.Event( "blur" ); |
||
386 | event.target = event.currentTarget = element[0];
|
||
387 | that.close( event, true );
|
||
388 | |||
389 | // Remove immediately; destroying an open tooltip doesn't use the
|
||
390 | // hide animation
|
||
391 | $( "#" + id ).remove(); |
||
392 | |||
393 | // Restore the title
|
||
394 | if ( element.data( "ui-tooltip-title" ) ) { |
||
395 | element.attr( "title", element.data( "ui-tooltip-title" ) ); |
||
396 | element.removeData( "ui-tooltip-title" );
|
||
397 | } |
||
398 | }); |
||
399 | } |
||
400 | }); |
||
401 | |||
402 | }( jQuery ) ); |