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


Generated : Fri Apr 19 08:20:01 2024 Cross-referenced by PHPXref