[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

/wp-includes/js/ -> wp-pointer.js (source)

   1  /**
   2   * @output wp-includes/js/wp-pointer.js
   3   */
   4  
   5  /* global wpPointerL10n */
   6  
   7  /**
   8   * Initializes the wp-pointer widget using jQuery UI Widget Factory.
   9   */
  10  (function($){
  11      var identifier = 0,
  12          zindex = 9999;
  13  
  14      $.widget('wp.pointer',/** @lends $.widget.wp.pointer.prototype */{
  15          options: {
  16              pointerClass: 'wp-pointer',
  17              pointerWidth: 320,
  18              content: function() {
  19                  return $(this).text();
  20              },
  21              buttons: function( event, t ) {
  22                  var close  = ( wpPointerL10n ) ? wpPointerL10n.dismiss : 'Dismiss',
  23                      button = $('<a class="close" href="#">' + close + '</a>');
  24  
  25                  return button.bind( 'click.pointer', function(e) {
  26                      e.preventDefault();
  27                      t.element.pointer('close');
  28                  });
  29              },
  30              position: 'top',
  31              show: function( event, t ) {
  32                  t.pointer.show();
  33                  t.opened();
  34              },
  35              hide: function( event, t ) {
  36                  t.pointer.hide();
  37                  t.closed();
  38              },
  39              document: document
  40          },
  41  
  42          /**
  43           * A class that represents a WordPress pointer.
  44           *
  45           * @since 3.3.0
  46           * @private
  47           *
  48           * @constructs $.widget.wp.pointer
  49           */
  50          _create: function() {
  51              var positioning,
  52                  family;
  53  
  54              this.content = $('<div class="wp-pointer-content"></div>');
  55              this.arrow   = $('<div class="wp-pointer-arrow"><div class="wp-pointer-arrow-inner"></div></div>');
  56  
  57              family = this.element.parents().add( this.element );
  58              positioning = 'absolute';
  59  
  60              if ( family.filter(function(){ return 'fixed' === $(this).css('position'); }).length )
  61                  positioning = 'fixed';
  62  
  63              this.pointer = $('<div />')
  64                  .append( this.content )
  65                  .append( this.arrow )
  66                  .attr('id', 'wp-pointer-' + identifier++)
  67                  .addClass( this.options.pointerClass )
  68                  .css({'position': positioning, 'width': this.options.pointerWidth+'px', 'display': 'none'})
  69                  .appendTo( this.options.document.body );
  70          },
  71  
  72          /**
  73           * Sets an option on the pointer instance.
  74           *
  75           * There are 4 special values that do something extra:
  76           *
  77           * - `document`     will transfer the pointer to the body of the new document
  78           *                  specified by the value.
  79           * - `pointerClass` will change the class of the pointer element.
  80           * - `position`     will reposition the pointer.
  81           * - `content`      will update the content of the pointer.
  82           *
  83           * @since 3.3.0
  84           * @private
  85           *
  86           * @param {string} key   The key of the option to set.
  87           * @param {*}      value The value to set the option to.
  88           */
  89          _setOption: function( key, value ) {
  90              var o   = this.options,
  91                  tip = this.pointer;
  92  
  93              // Handle document transfer
  94              if ( key === 'document' && value !== o.document ) {
  95                  tip.detach().appendTo( value.body );
  96  
  97              // Handle class change
  98              } else if ( key === 'pointerClass' ) {
  99                  tip.removeClass( o.pointerClass ).addClass( value );
 100              }
 101  
 102              // Call super method.
 103              $.Widget.prototype._setOption.apply( this, arguments );
 104  
 105              // Reposition automatically
 106              if ( key === 'position' ) {
 107                  this.reposition();
 108  
 109              // Update content automatically if pointer is open
 110              } else if ( key === 'content' && this.active ) {
 111                  this.update();
 112              }
 113          },
 114  
 115          /**
 116           * Removes the pointer element from of the DOM.
 117           *
 118           * Makes sure that the widget and all associated bindings are destroyed.
 119           *
 120           * @since 3.3.0
 121           */
 122          destroy: function() {
 123              this.pointer.remove();
 124              $.Widget.prototype.destroy.call( this );
 125          },
 126  
 127          /**
 128           * Returns the pointer element.
 129           *
 130           * @since 3.3.0
 131           *
 132           * @return {Object} Pointer The pointer object.
 133           */
 134          widget: function() {
 135              return this.pointer;
 136          },
 137  
 138          /**
 139           * Updates the content of the pointer.
 140           *
 141           * This function doesn't update the content of the pointer itself. That is done
 142           * by the `_update` method. This method will make sure that the `_update` method
 143           * is called with the right content.
 144           *
 145           * The content in the options can either be a string or a callback. If it is a
 146           * callback the result of this callback is used as the content.
 147           *
 148           * @since 3.3.0
 149           *
 150           * @param {Object} event The event that caused the update.
 151           *
 152           * @return {Promise} Resolves when the update has been executed.
 153           */
 154          update: function( event ) {
 155              var self = this,
 156                  o    = this.options,
 157                  dfd  = $.Deferred(),
 158                  content;
 159  
 160              if ( o.disabled )
 161                  return;
 162  
 163              dfd.done( function( content ) {
 164                  self._update( event, content );
 165              });
 166  
 167              // Either o.content is a string...
 168              if ( typeof o.content === 'string' ) {
 169                  content = o.content;
 170  
 171              // ...or o.content is a callback.
 172              } else {
 173                  content = o.content.call( this.element[0], dfd.resolve, event, this._handoff() );
 174              }
 175  
 176              // If content is set, then complete the update.
 177              if ( content )
 178                  dfd.resolve( content );
 179  
 180              return dfd.promise();
 181          },
 182  
 183          /**
 184           * Updates the content of the pointer.
 185           *
 186           * Will make sure that the pointer is correctly positioned.
 187           *
 188           * @since 3.3.0
 189           * @private
 190           *
 191           * @param {Object} event   The event that caused the update.
 192           * @param {*}      content The content object. Either a string or a jQuery tree.
 193           */
 194          _update: function( event, content ) {
 195              var buttons,
 196                  o = this.options;
 197  
 198              if ( ! content )
 199                  return;
 200  
 201              // Kill any animations on the pointer.
 202              this.pointer.stop();
 203              this.content.html( content );
 204  
 205              buttons = o.buttons.call( this.element[0], event, this._handoff() );
 206              if ( buttons ) {
 207                  buttons.wrap('<div class="wp-pointer-buttons" />').parent().appendTo( this.content );
 208              }
 209  
 210              this.reposition();
 211          },
 212  
 213          /**
 214           * Repositions the pointer.
 215           *
 216           * Makes sure the pointer is the correct size for its content and makes sure it
 217           * is positioned to point to the right element.
 218           *
 219           * @since 3.3.0
 220           */
 221          reposition: function() {
 222              var position;
 223  
 224              if ( this.options.disabled )
 225                  return;
 226  
 227              position = this._processPosition( this.options.position );
 228  
 229              // Reposition pointer.
 230              this.pointer.css({
 231                  top: 0,
 232                  left: 0,
 233                  zIndex: zindex++ // Increment the z-index so that it shows above other opened pointers.
 234              }).show().position($.extend({
 235                  of: this.element,
 236                  collision: 'fit none'
 237              }, position )); // the object comes before this.options.position so the user can override position.of.
 238  
 239              this.repoint();
 240          },
 241  
 242          /**
 243           * Sets the arrow of the pointer to the correct side of the pointer element.
 244           *
 245           * @since 3.3.0
 246           */
 247          repoint: function() {
 248              var o = this.options,
 249                  edge;
 250  
 251              if ( o.disabled )
 252                  return;
 253  
 254              edge = ( typeof o.position == 'string' ) ? o.position : o.position.edge;
 255  
 256              // Remove arrow classes.
 257              this.pointer[0].className = this.pointer[0].className.replace( /wp-pointer-[^\s'"]*/, '' );
 258  
 259              // Add arrow class.
 260              this.pointer.addClass( 'wp-pointer-' + edge );
 261          },
 262  
 263          /**
 264           * Calculates the correct position based on a position in the settings.
 265           *
 266           * @since 3.3.0
 267           * @private
 268           *
 269           * @param {string|Object} position Either a side of a pointer or an object
 270           *                                 containing a pointer.
 271           *
 272           * @return {Object} result  An object containing position related data.
 273           */
 274          _processPosition: function( position ) {
 275              var opposite = {
 276                      top: 'bottom',
 277                      bottom: 'top',
 278                      left: 'right',
 279                      right: 'left'
 280                  },
 281                  result;
 282  
 283              // If the position object is a string, it is shorthand for position.edge.
 284              if ( typeof position == 'string' ) {
 285                  result = {
 286                      edge: position + ''
 287                  };
 288              } else {
 289                  result = $.extend( {}, position );
 290              }
 291  
 292              if ( ! result.edge )
 293                  return result;
 294  
 295              if ( result.edge == 'top' || result.edge == 'bottom' ) {
 296                  result.align = result.align || 'left';
 297  
 298                  result.at = result.at || result.align + ' ' + opposite[ result.edge ];
 299                  result.my = result.my || result.align + ' ' + result.edge;
 300              } else {
 301                  result.align = result.align || 'top';
 302  
 303                  result.at = result.at || opposite[ result.edge ] + ' ' + result.align;
 304                  result.my = result.my || result.edge + ' ' + result.align;
 305              }
 306  
 307              return result;
 308          },
 309  
 310          /**
 311           * Opens the pointer.
 312           *
 313           * Only opens the pointer widget in case it is closed and not disabled, and
 314           * calls 'update' before doing so. Calling update makes sure that the pointer
 315           * is correctly sized and positioned.
 316           *
 317           * @since 3.3.0
 318           *
 319           * @param {Object} event The event that triggered the opening of this pointer.
 320           */
 321          open: function( event ) {
 322              var self = this,
 323                  o    = this.options;
 324  
 325              if ( this.active || o.disabled || this.element.is(':hidden') )
 326                  return;
 327  
 328              this.update().done( function() {
 329                  self._open( event );
 330              });
 331          },
 332  
 333          /**
 334           * Opens and shows the pointer element.
 335           *
 336           * @since 3.3.0
 337           * @private
 338           *
 339           * @param {Object} event An event object.
 340           */
 341          _open: function( event ) {
 342              var self = this,
 343                  o    = this.options;
 344  
 345              if ( this.active || o.disabled || this.element.is(':hidden') )
 346                  return;
 347  
 348              this.active = true;
 349  
 350              this._trigger( 'open', event, this._handoff() );
 351  
 352              this._trigger( 'show', event, this._handoff({
 353                  opened: function() {
 354                      self._trigger( 'opened', event, self._handoff() );
 355                  }
 356              }));
 357          },
 358  
 359          /**
 360           * Closes and hides the pointer element.
 361           *
 362           * @since 3.3.0
 363           *
 364           * @param {Object} event An event object.
 365           */
 366          close: function( event ) {
 367              if ( !this.active || this.options.disabled )
 368                  return;
 369  
 370              var self = this;
 371              this.active = false;
 372  
 373              this._trigger( 'close', event, this._handoff() );
 374              this._trigger( 'hide', event, this._handoff({
 375                  closed: function() {
 376                      self._trigger( 'closed', event, self._handoff() );
 377                  }
 378              }));
 379          },
 380  
 381          /**
 382           * Puts the pointer on top by increasing the z-index.
 383           *
 384           * @since 3.3.0
 385           */
 386          sendToTop: function() {
 387              if ( this.active )
 388                  this.pointer.css( 'z-index', zindex++ );
 389          },
 390  
 391          /**
 392           * Toggles the element between shown and hidden.
 393           *
 394           * @since 3.3.0
 395           *
 396           * @param {Object} event An event object.
 397           */
 398          toggle: function( event ) {
 399              if ( this.pointer.is(':hidden') )
 400                  this.open( event );
 401              else
 402                  this.close( event );
 403          },
 404  
 405          /**
 406           * Extends the pointer and the widget element with the supplied parameter, which
 407           * is either an element or a function.
 408           *
 409           * @since 3.3.0
 410           * @private
 411           *
 412           * @param {Object} extend The object to be merged into the original object.
 413           *
 414           * @return {Object} The extended object.
 415           */
 416          _handoff: function( extend ) {
 417              return $.extend({
 418                  pointer: this.pointer,
 419                  element: this.element
 420              }, extend);
 421          }
 422      });
 423  })(jQuery);


Generated: Sat Nov 23 20:47:33 2019 Cross-referenced by PHPXref 0.7