| /*! |
| * jQuery UI Tooltip 1.9.2 |
| * http://jqueryui.com |
| * |
| * Copyright 2012 jQuery Foundation and other contributors |
| * Released under the MIT license. |
| * http://jquery.org/license |
| * |
| * http://api.jqueryui.com/tooltip/ |
| * |
| * Depends: |
| * jquery.ui.core.js |
| * jquery.ui.widget.js |
| * jquery.ui.position.js |
| */ |
| (function( $ ) { |
| |
| var increments = 0; |
| |
| function addDescribedBy( elem, id ) { |
| var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); |
| describedby.push( id ); |
| elem |
| .data( "ui-tooltip-id", id ) |
| .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); |
| } |
| |
| function removeDescribedBy( elem ) { |
| var id = elem.data( "ui-tooltip-id" ), |
| describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), |
| index = $.inArray( id, describedby ); |
| if ( index !== -1 ) { |
| describedby.splice( index, 1 ); |
| } |
| |
| elem.removeData( "ui-tooltip-id" ); |
| describedby = $.trim( describedby.join( " " ) ); |
| if ( describedby ) { |
| elem.attr( "aria-describedby", describedby ); |
| } else { |
| elem.removeAttr( "aria-describedby" ); |
| } |
| } |
| |
| $.widget( "ui.tooltip", { |
| version: "1.9.2", |
| options: { |
| content: function() { |
| return $( this ).attr( "title" ); |
| }, |
| hide: true, |
| // Disabled elements have inconsistent behavior across browsers (#8661) |
| items: "[title]:not([disabled])", |
| position: { |
| my: "left top+15", |
| at: "left bottom", |
| collision: "flipfit flip" |
| }, |
| show: true, |
| tooltipClass: null, |
| track: false, |
| |
| // callbacks |
| close: null, |
| open: null |
| }, |
| |
| _create: function() { |
| this._on({ |
| mouseover: "open", |
| focusin: "open" |
| }); |
| |
| // IDs of generated tooltips, needed for destroy |
| this.tooltips = {}; |
| // IDs of parent tooltips where we removed the title attribute |
| this.parents = {}; |
| |
| if ( this.options.disabled ) { |
| this._disable(); |
| } |
| }, |
| |
| _setOption: function( key, value ) { |
| var that = this; |
| |
| if ( key === "disabled" ) { |
| this[ value ? "_disable" : "_enable" ](); |
| this.options[ key ] = value; |
| // disable element style changes |
| return; |
| } |
| |
| this._super( key, value ); |
| |
| if ( key === "content" ) { |
| $.each( this.tooltips, function( id, element ) { |
| that._updateContent( element ); |
| }); |
| } |
| }, |
| |
| _disable: function() { |
| var that = this; |
| |
| // close open tooltips |
| $.each( this.tooltips, function( id, element ) { |
| var event = $.Event( "blur" ); |
| event.target = event.currentTarget = element[0]; |
| that.close( event, true ); |
| }); |
| |
| // remove title attributes to prevent native tooltips |
| this.element.find( this.options.items ).andSelf().each(function() { |
| var element = $( this ); |
| if ( element.is( "[title]" ) ) { |
| element |
| .data( "ui-tooltip-title", element.attr( "title" ) ) |
| .attr( "title", "" ); |
| } |
| }); |
| }, |
| |
| _enable: function() { |
| // restore title attributes |
| this.element.find( this.options.items ).andSelf().each(function() { |
| var element = $( this ); |
| if ( element.data( "ui-tooltip-title" ) ) { |
| element.attr( "title", element.data( "ui-tooltip-title" ) ); |
| } |
| }); |
| }, |
| |
| open: function( event ) { |
| var that = this, |
| target = $( event ? event.target : this.element ) |
| // we need closest here due to mouseover bubbling, |
| // but always pointing at the same event target |
| .closest( this.options.items ); |
| |
| // No element to show a tooltip for or the tooltip is already open |
| if ( !target.length || target.data( "ui-tooltip-id" ) ) { |
| return; |
| } |
| |
| if ( target.attr( "title" ) ) { |
| target.data( "ui-tooltip-title", target.attr( "title" ) ); |
| } |
| |
| target.data( "ui-tooltip-open", true ); |
| |
| // kill parent tooltips, custom or native, for hover |
| if ( event && event.type === "mouseover" ) { |
| target.parents().each(function() { |
| var parent = $( this ), |
| blurEvent; |
| if ( parent.data( "ui-tooltip-open" ) ) { |
| blurEvent = $.Event( "blur" ); |
| blurEvent.target = blurEvent.currentTarget = this; |
| that.close( blurEvent, true ); |
| } |
| if ( parent.attr( "title" ) ) { |
| parent.uniqueId(); |
| that.parents[ this.id ] = { |
| element: this, |
| title: parent.attr( "title" ) |
| }; |
| parent.attr( "title", "" ); |
| } |
| }); |
| } |
| |
| this._updateContent( target, event ); |
| }, |
| |
| _updateContent: function( target, event ) { |
| var content, |
| contentOption = this.options.content, |
| that = this, |
| eventType = event ? event.type : null; |
| |
| if ( typeof contentOption === "string" ) { |
| return this._open( event, target, contentOption ); |
| } |
| |
| content = contentOption.call( target[0], function( response ) { |
| // ignore async response if tooltip was closed already |
| if ( !target.data( "ui-tooltip-open" ) ) { |
| return; |
| } |
| // IE may instantly serve a cached response for ajax requests |
| // delay this call to _open so the other call to _open runs first |
| that._delay(function() { |
| // jQuery creates a special event for focusin when it doesn't |
| // exist natively. To improve performance, the native event |
| // object is reused and the type is changed. Therefore, we can't |
| // rely on the type being correct after the event finished |
| // bubbling, so we set it back to the previous value. (#8740) |
| if ( event ) { |
| event.type = eventType; |
| } |
| this._open( event, target, response ); |
| }); |
| }); |
| if ( content ) { |
| this._open( event, target, content ); |
| } |
| }, |
| |
| _open: function( event, target, content ) { |
| var tooltip, events, delayedShow, |
| positionOption = $.extend( {}, this.options.position ); |
| |
| if ( !content ) { |
| return; |
| } |
| |
| // Content can be updated multiple times. If the tooltip already |
| // exists, then just update the content and bail. |
| tooltip = this._find( target ); |
| if ( tooltip.length ) { |
| tooltip.find( ".ui-tooltip-content" ).html( content ); |
| return; |
| } |
| |
| // if we have a title, clear it to prevent the native tooltip |
| // we have to check first to avoid defining a title if none exists |
| // (we don't want to cause an element to start matching [title]) |
| // |
| // We use removeAttr only for key events, to allow IE to export the correct |
| // accessible attributes. For mouse events, set to empty string to avoid |
| // native tooltip showing up (happens only when removing inside mouseover). |
| if ( target.is( "[title]" ) ) { |
| if ( event && event.type === "mouseover" ) { |
| target.attr( "title", "" ); |
| } else { |
| target.removeAttr( "title" ); |
| } |
| } |
| |
| tooltip = this._tooltip( target ); |
| addDescribedBy( target, tooltip.attr( "id" ) ); |
| tooltip.find( ".ui-tooltip-content" ).html( content ); |
| |
| function position( event ) { |
| positionOption.of = event; |
| if ( tooltip.is( ":hidden" ) ) { |
| return; |
| } |
| tooltip.position( positionOption ); |
| } |
| if ( this.options.track && event && /^mouse/.test( event.type ) ) { |
| this._on( this.document, { |
| mousemove: position |
| }); |
| // trigger once to override element-relative positioning |
| position( event ); |
| } else { |
| tooltip.position( $.extend({ |
| of: target |
| }, this.options.position ) ); |
| } |
| |
| tooltip.hide(); |
| |
| this._show( tooltip, this.options.show ); |
| // Handle tracking tooltips that are shown with a delay (#8644). As soon |
| // as the tooltip is visible, position the tooltip using the most recent |
| // event. |
| if ( this.options.show && this.options.show.delay ) { |
| delayedShow = setInterval(function() { |
| if ( tooltip.is( ":visible" ) ) { |
| position( positionOption.of ); |
| clearInterval( delayedShow ); |
| } |
| }, $.fx.interval ); |
| } |
| |
| this._trigger( "open", event, { tooltip: tooltip } ); |
| |
| events = { |
| keyup: function( event ) { |
| if ( event.keyCode === $.ui.keyCode.ESCAPE ) { |
| var fakeEvent = $.Event(event); |
| fakeEvent.currentTarget = target[0]; |
| this.close( fakeEvent, true ); |
| } |
| }, |
| remove: function() { |
| this._removeTooltip( tooltip ); |
| } |
| }; |
| if ( !event || event.type === "mouseover" ) { |
| events.mouseleave = "close"; |
| } |
| if ( !event || event.type === "focusin" ) { |
| events.focusout = "close"; |
| } |
| this._on( true, target, events ); |
| }, |
| |
| close: function( event ) { |
| var that = this, |
| target = $( event ? event.currentTarget : this.element ), |
| tooltip = this._find( target ); |
| |
| // disabling closes the tooltip, so we need to track when we're closing |
| // to avoid an infinite loop in case the tooltip becomes disabled on close |
| if ( this.closing ) { |
| return; |
| } |
| |
| // only set title if we had one before (see comment in _open()) |
| if ( target.data( "ui-tooltip-title" ) ) { |
| target.attr( "title", target.data( "ui-tooltip-title" ) ); |
| } |
| |
| removeDescribedBy( target ); |
| |
| tooltip.stop( true ); |
| this._hide( tooltip, this.options.hide, function() { |
| that._removeTooltip( $( this ) ); |
| }); |
| |
| target.removeData( "ui-tooltip-open" ); |
| this._off( target, "mouseleave focusout keyup" ); |
| // Remove 'remove' binding only on delegated targets |
| if ( target[0] !== this.element[0] ) { |
| this._off( target, "remove" ); |
| } |
| this._off( this.document, "mousemove" ); |
| |
| if ( event && event.type === "mouseleave" ) { |
| $.each( this.parents, function( id, parent ) { |
| $( parent.element ).attr( "title", parent.title ); |
| delete that.parents[ id ]; |
| }); |
| } |
| |
| this.closing = true; |
| this._trigger( "close", event, { tooltip: tooltip } ); |
| this.closing = false; |
| }, |
| |
| _tooltip: function( element ) { |
| var id = "ui-tooltip-" + increments++, |
| tooltip = $( "<div>" ) |
| .attr({ |
| id: id, |
| role: "tooltip" |
| }) |
| .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + |
| ( this.options.tooltipClass || "" ) ); |
| $( "<div>" ) |
| .addClass( "ui-tooltip-content" ) |
| .appendTo( tooltip ); |
| tooltip.appendTo( this.document[0].body ); |
| if ( $.fn.bgiframe ) { |
| tooltip.bgiframe(); |
| } |
| this.tooltips[ id ] = element; |
| return tooltip; |
| }, |
| |
| _find: function( target ) { |
| var id = target.data( "ui-tooltip-id" ); |
| return id ? $( "#" + id ) : $(); |
| }, |
| |
| _removeTooltip: function( tooltip ) { |
| tooltip.remove(); |
| delete this.tooltips[ tooltip.attr( "id" ) ]; |
| }, |
| |
| _destroy: function() { |
| var that = this; |
| |
| // close open tooltips |
| $.each( this.tooltips, function( id, element ) { |
| // Delegate to close method to handle common cleanup |
| var event = $.Event( "blur" ); |
| event.target = event.currentTarget = element[0]; |
| that.close( event, true ); |
| |
| // Remove immediately; destroying an open tooltip doesn't use the |
| // hide animation |
| $( "#" + id ).remove(); |
| |
| // Restore the title |
| if ( element.data( "ui-tooltip-title" ) ) { |
| element.attr( "title", element.data( "ui-tooltip-title" ) ); |
| element.removeData( "ui-tooltip-title" ); |
| } |
| }); |
| } |
| }); |
| |
| }( jQuery ) ); |