| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
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);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Thu Sep 3 08:20:25 2026 | Cross-referenced by PHPXref |