integration/back-office/lib/jquery-ui/ui/jquery.ui.tooltip.js
changeset 2 78f71aa0a477
parent 1 b95aebb070b5
child 3 54f80d24f469
child 6 547b3ddedf7f
equal deleted inserted replaced
1:b95aebb070b5 2:78f71aa0a477
     1 /*!
       
     2  * jQuery UI Tooltip 1.10.3
       
     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.3",
       
    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 ) );