[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/jquery/ui/ -> tooltip.js (source)

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


Generated : Wed Dec 2 08:20:02 2020 Cross-referenced by PHPXref