commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-old / civicrm / packages / jquery / jquery-ui-1.9.0 / development-bundle / ui / jquery.ui.tooltip.js
CommitLineData
5a920362 1/*!
2 * jQuery UI Tooltip 1.9.0
3 * http://jqueryui.com
4 *
5 * Copyright 2012 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
18var increments = 0;
19
20function 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
28function 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.9.0",
47 options: {
48 content: function() {
49 return $( this ).attr( "title" );
50 },
51 hide: true,
52 items: "[title]",
53 position: {
54 my: "left+15 center",
55 at: "right center",
56 collision: "flipfit flipfit"
57 },
58 show: true,
59 tooltipClass: null,
60 track: false,
61
62 // callbacks
63 close: null,
64 open: null
65 },
66
67 _create: function() {
68 this._on({
69 mouseover: "open",
70 focusin: "open"
71 });
72
73 // IDs of generated tooltips, needed for destroy
74 this.tooltips = {};
75 },
76
77 _setOption: function( key, value ) {
78 var that = this;
79
80 if ( key === "disabled" ) {
81 this[ value ? "_disable" : "_enable" ]();
82 this.options[ key ] = value;
83 // disable element style changes
84 return;
85 }
86
87 this._super( key, value );
88
89 if ( key === "content" ) {
90 $.each( this.tooltips, function( id, element ) {
91 that._updateContent( element );
92 });
93 }
94 },
95
96 _disable: function() {
97 var that = this;
98
99 // close open tooltips
100 $.each( this.tooltips, function( id, element ) {
101 var event = $.Event( "blur" );
102 event.target = event.currentTarget = element[0];
103 that.close( event, true );
104 });
105
106 // remove title attributes to prevent native tooltips
107 this.element.find( this.options.items ).andSelf().each(function() {
108 var element = $( this );
109 if ( element.is( "[title]" ) ) {
110 element
111 .data( "ui-tooltip-title", element.attr( "title" ) )
112 .attr( "title", "" );
113 }
114 });
115 },
116
117 _enable: function() {
118 // restore title attributes
119 this.element.find( this.options.items ).andSelf().each(function() {
120 var element = $( this );
121 if ( element.data( "ui-tooltip-title" ) ) {
122 element.attr( "title", element.data( "ui-tooltip-title" ) );
123 }
124 });
125 },
126
127 open: function( event ) {
128 var target = $( event ? event.target : this.element )
129 .closest( this.options.items );
130
131 // No element to show a tooltip for
132 if ( !target.length ) {
133 return;
134 }
135
136 // If the tooltip is open and we're tracking then reposition the tooltip.
137 // This makes sure that a tracking tooltip doesn't obscure a focused element
138 // if the user was hovering when the element gained focused.
139 if ( this.options.track && target.data( "ui-tooltip-id" ) ) {
140 this._find( target ).position( $.extend({
141 of: target
142 }, this.options.position ) );
143 // Stop tracking (#8622)
144 this._off( this.document, "mousemove" );
145 return;
146 }
147
148 if ( target.attr( "title" ) ) {
149 target.data( "ui-tooltip-title", target.attr( "title" ) );
150 }
151
152 target.data( "tooltip-open", true );
153
154 this._updateContent( target, event );
155 },
156
157 _updateContent: function( target, event ) {
158 var content,
159 contentOption = this.options.content,
160 that = this;
161
162 if ( typeof contentOption === "string" ) {
163 return this._open( event, target, contentOption );
164 }
165
166 content = contentOption.call( target[0], function( response ) {
167 // ignore async response if tooltip was closed already
168 if ( !target.data( "tooltip-open" ) ) {
169 return;
170 }
171 // IE may instantly serve a cached response for ajax requests
172 // delay this call to _open so the other call to _open runs first
173 that._delay(function() {
174 this._open( event, target, response );
175 });
176 });
177 if ( content ) {
178 this._open( event, target, content );
179 }
180 },
181
182 _open: function( event, target, content ) {
183 var tooltip, positionOption;
184 if ( !content ) {
185 return;
186 }
187
188 // Content can be updated multiple times. If the tooltip already
189 // exists, then just update the content and bail.
190 tooltip = this._find( target );
191 if ( tooltip.length ) {
192 tooltip.find( ".ui-tooltip-content" ).html( content );
193 return;
194 }
195
196 // if we have a title, clear it to prevent the native tooltip
197 // we have to check first to avoid defining a title if none exists
198 // (we don't want to cause an element to start matching [title])
199 //
200 // We use removeAttr only for key events, to allow IE to export the correct
201 // accessible attributes. For mouse events, set to empty string to avoid
202 // native tooltip showing up (happens only when removing inside mouseover).
203 if ( target.is( "[title]" ) ) {
204 if ( event && event.type === "mouseover" ) {
205 target.attr( "title", "" );
206 } else {
207 target.removeAttr( "title" );
208 }
209 }
210
211 tooltip = this._tooltip( target );
212 addDescribedBy( target, tooltip.attr( "id" ) );
213 tooltip.find( ".ui-tooltip-content" ).html( content );
214
215 function position( event ) {
216 positionOption.of = event;
217 tooltip.position( positionOption );
218 }
219 if ( this.options.track && event && /^mouse/.test( event.originalEvent.type ) ) {
220 positionOption = $.extend( {}, this.options.position );
221 this._on( this.document, {
222 mousemove: position
223 });
224 // trigger once to override element-relative positioning
225 position( event );
226 } else {
227 tooltip.position( $.extend({
228 of: target
229 }, this.options.position ) );
230 }
231
232 tooltip.hide();
233
234 this._show( tooltip, this.options.show );
235
236 this._trigger( "open", event, { tooltip: tooltip } );
237
238 this._on( target, {
239 mouseleave: "close",
240 focusout: "close",
241 keyup: function( event ) {
242 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
243 var fakeEvent = $.Event(event);
244 fakeEvent.currentTarget = target[0];
245 this.close( fakeEvent, true );
246 }
247 }
248 });
249 },
250
251 close: function( event, force ) {
252 var that = this,
253 target = $( event ? event.currentTarget : this.element ),
254 tooltip = this._find( target );
255
256 // disabling closes the tooltip, so we need to track when we're closing
257 // to avoid an infinite loop in case the tooltip becomes disabled on close
258 if ( this.closing ) {
259 return;
260 }
261
262 // don't close if the element has focus
263 // this prevents the tooltip from closing if you hover while focused
264 //
265 // we have to check the event type because tabbing out of the document
266 // may leave the element as the activeElement
267 if ( !force && event && event.type !== "focusout" &&
268 this.document[0].activeElement === target[0] ) {
269 return;
270 }
271
272 // only set title if we had one before (see comment in _open())
273 if ( target.data( "ui-tooltip-title" ) ) {
274 target.attr( "title", target.data( "ui-tooltip-title" ) );
275 }
276
277 removeDescribedBy( target );
278
279 tooltip.stop( true );
280 this._hide( tooltip, this.options.hide, function() {
281 $( this ).remove();
282 delete that.tooltips[ this.id ];
283 });
284
285 target.removeData( "tooltip-open" );
286 this._off( target, "mouseleave focusout keyup" );
287 this._off( this.document, "mousemove" );
288
289 this.closing = true;
290 this._trigger( "close", event, { tooltip: tooltip } );
291 this.closing = false;
292 },
293
294 _tooltip: function( element ) {
295 var id = "ui-tooltip-" + increments++,
296 tooltip = $( "<div>" )
297 .attr({
298 id: id,
299 role: "tooltip"
300 })
301 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
302 ( this.options.tooltipClass || "" ) );
303 $( "<div>" )
304 .addClass( "ui-tooltip-content" )
305 .appendTo( tooltip );
306 tooltip.appendTo( this.document[0].body );
307 if ( $.fn.bgiframe ) {
308 tooltip.bgiframe();
309 }
310 this.tooltips[ id ] = element;
311 return tooltip;
312 },
313
314 _find: function( target ) {
315 var id = target.data( "ui-tooltip-id" );
316 return id ? $( "#" + id ) : $();
317 },
318
319 _destroy: function() {
320 var that = this;
321
322 // close open tooltips
323 $.each( this.tooltips, function( id, element ) {
324 // Delegate to close method to handle common cleanup
325 var event = $.Event( "blur" );
326 event.target = event.currentTarget = element[0];
327 that.close( event, true );
328
329 // Remove immediately; destroying an open tooltip doesn't use the
330 // hide animation
331 $( "#" + id ).remove();
332
333 // Restore the title
334 if ( element.data( "ui-tooltip-title" ) ) {
335 element.attr( "title", element.data( "ui-tooltip-title" ) );
336 element.removeData( "ui-tooltip-title" );
337 }
338 });
339 }
340});
341
342}( jQuery ) );