[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

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


Generated : Thu Sep 3 08:20:25 2026 Cross-referenced by PHPXref