wp/wp-includes/js/wp-pointer.js
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
       
     1 /**
       
     2  * @output wp-includes/js/wp-pointer.js
       
     3  */
       
     4 
     1 /* global wpPointerL10n */
     5 /* global wpPointerL10n */
       
     6 
     2 /**
     7 /**
     3  * Pointer jQuery widget.
     8  * Initializes the wp-pointer widget using jQuery UI Widget Factory.
     4  */
     9  */
     5 (function($){
    10 (function($){
     6 	var identifier = 0,
    11 	var identifier = 0,
     7 		zindex = 9999;
    12 		zindex = 9999;
     8 
    13 
     9 	/**
       
    10 	 * @class $.widget.wp.pointer
       
    11 	 */
       
    12 	$.widget('wp.pointer',/** @lends $.widget.wp.pointer.prototype */{
    14 	$.widget('wp.pointer',/** @lends $.widget.wp.pointer.prototype */{
    13 		options: {
    15 		options: {
    14 			pointerClass: 'wp-pointer',
    16 			pointerClass: 'wp-pointer',
    15 			pointerWidth: 320,
    17 			pointerWidth: 320,
    16 			content: function() {
    18 			content: function() {
    35 				t.closed();
    37 				t.closed();
    36 			},
    38 			},
    37 			document: document
    39 			document: document
    38 		},
    40 		},
    39 
    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 		 */
    40 		_create: function() {
    50 		_create: function() {
    41 			var positioning,
    51 			var positioning,
    42 				family;
    52 				family;
    43 
    53 
    44 			this.content = $('<div class="wp-pointer-content"></div>');
    54 			this.content = $('<div class="wp-pointer-content"></div>');
    57 				.addClass( this.options.pointerClass )
    67 				.addClass( this.options.pointerClass )
    58 				.css({'position': positioning, 'width': this.options.pointerWidth+'px', 'display': 'none'})
    68 				.css({'position': positioning, 'width': this.options.pointerWidth+'px', 'display': 'none'})
    59 				.appendTo( this.options.document.body );
    69 				.appendTo( this.options.document.body );
    60 		},
    70 		},
    61 
    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 		 */
    62 		_setOption: function( key, value ) {
    89 		_setOption: function( key, value ) {
    63 			var o   = this.options,
    90 			var o   = this.options,
    64 				tip = this.pointer;
    91 				tip = this.pointer;
    65 
    92 
    66 			// Handle document transfer
    93 			// Handle document transfer
    83 			} else if ( key === 'content' && this.active ) {
   110 			} else if ( key === 'content' && this.active ) {
    84 				this.update();
   111 				this.update();
    85 			}
   112 			}
    86 		},
   113 		},
    87 
   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 		 */
    88 		destroy: function() {
   122 		destroy: function() {
    89 			this.pointer.remove();
   123 			this.pointer.remove();
    90 			$.Widget.prototype.destroy.call( this );
   124 			$.Widget.prototype.destroy.call( this );
    91 		},
   125 		},
    92 
   126 
       
   127 		/**
       
   128 		 * Returns the pointer element.
       
   129 		 *
       
   130 		 * @since 3.3.0
       
   131 		 *
       
   132 		 * @return {Object} Pointer The pointer object.
       
   133 		 */
    93 		widget: function() {
   134 		widget: function() {
    94 			return this.pointer;
   135 			return this.pointer;
    95 		},
   136 		},
    96 
   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 		 */
    97 		update: function( event ) {
   154 		update: function( event ) {
    98 			var self = this,
   155 			var self = this,
    99 				o    = this.options,
   156 				o    = this.options,
   100 				dfd  = $.Deferred(),
   157 				dfd  = $.Deferred(),
   101 				content;
   158 				content;
   122 
   179 
   123 			return dfd.promise();
   180 			return dfd.promise();
   124 		},
   181 		},
   125 
   182 
   126 		/**
   183 		/**
   127 		 * Update is separated into two functions to allow events to defer
   184 		 * Updates the content of the pointer.
   128 		 * updating the pointer (e.g. fetch content with ajax, etc).
   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.
   129 		 */
   193 		 */
   130 		_update: function( event, content ) {
   194 		_update: function( event, content ) {
   131 			var buttons,
   195 			var buttons,
   132 				o = this.options;
   196 				o = this.options;
   133 
   197 
   134 			if ( ! content )
   198 			if ( ! content )
   135 				return;
   199 				return;
   136 
   200 
   137 			this.pointer.stop(); // Kill any animations on the pointer.
   201 			// Kill any animations on the pointer.
       
   202 			this.pointer.stop();
   138 			this.content.html( content );
   203 			this.content.html( content );
   139 
   204 
   140 			buttons = o.buttons.call( this.element[0], event, this._handoff() );
   205 			buttons = o.buttons.call( this.element[0], event, this._handoff() );
   141 			if ( buttons ) {
   206 			if ( buttons ) {
   142 				buttons.wrap('<div class="wp-pointer-buttons" />').parent().appendTo( this.content );
   207 				buttons.wrap('<div class="wp-pointer-buttons" />').parent().appendTo( this.content );
   143 			}
   208 			}
   144 
   209 
   145 			this.reposition();
   210 			this.reposition();
   146 		},
   211 		},
   147 
   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 		 */
   148 		reposition: function() {
   221 		reposition: function() {
   149 			var position;
   222 			var position;
   150 
   223 
   151 			if ( this.options.disabled )
   224 			if ( this.options.disabled )
   152 				return;
   225 				return;
   164 			}, position )); // the object comes before this.options.position so the user can override position.of.
   237 			}, position )); // the object comes before this.options.position so the user can override position.of.
   165 
   238 
   166 			this.repoint();
   239 			this.repoint();
   167 		},
   240 		},
   168 
   241 
       
   242 		/**
       
   243 		 * Sets the arrow of the pointer to the correct side of the pointer element.
       
   244 		 *
       
   245 		 * @since 3.3.0
       
   246 		 */
   169 		repoint: function() {
   247 		repoint: function() {
   170 			var o = this.options,
   248 			var o = this.options,
   171 				edge;
   249 				edge;
   172 
   250 
   173 			if ( o.disabled )
   251 			if ( o.disabled )
   180 
   258 
   181 			// Add arrow class.
   259 			// Add arrow class.
   182 			this.pointer.addClass( 'wp-pointer-' + edge );
   260 			this.pointer.addClass( 'wp-pointer-' + edge );
   183 		},
   261 		},
   184 
   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 		 */
   185 		_processPosition: function( position ) {
   274 		_processPosition: function( position ) {
   186 			var opposite = {
   275 			var opposite = {
   187 					top: 'bottom',
   276 					top: 'bottom',
   188 					bottom: 'top',
   277 					bottom: 'top',
   189 					left: 'right',
   278 					left: 'right',
   216 			}
   305 			}
   217 
   306 
   218 			return result;
   307 			return result;
   219 		},
   308 		},
   220 
   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 		 */
   221 		open: function( event ) {
   321 		open: function( event ) {
   222 			var self = this,
   322 			var self = this,
   223 				o    = this.options;
   323 				o    = this.options;
   224 
   324 
   225 			if ( this.active || o.disabled || this.element.is(':hidden') )
   325 			if ( this.active || o.disabled || this.element.is(':hidden') )
   228 			this.update().done( function() {
   328 			this.update().done( function() {
   229 				self._open( event );
   329 				self._open( event );
   230 			});
   330 			});
   231 		},
   331 		},
   232 
   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 		 */
   233 		_open: function( event ) {
   341 		_open: function( event ) {
   234 			var self = this,
   342 			var self = this,
   235 				o    = this.options;
   343 				o    = this.options;
   236 
   344 
   237 			if ( this.active || o.disabled || this.element.is(':hidden') )
   345 			if ( this.active || o.disabled || this.element.is(':hidden') )
   246 					self._trigger( 'opened', event, self._handoff() );
   354 					self._trigger( 'opened', event, self._handoff() );
   247 				}
   355 				}
   248 			}));
   356 			}));
   249 		},
   357 		},
   250 
   358 
       
   359 		/**
       
   360 		 * Closes and hides the pointer element.
       
   361 		 *
       
   362 		 * @since 3.3.0
       
   363 		 *
       
   364 		 * @param {Object} event An event object.
       
   365 		 */
   251 		close: function( event ) {
   366 		close: function( event ) {
   252 			if ( !this.active || this.options.disabled )
   367 			if ( !this.active || this.options.disabled )
   253 				return;
   368 				return;
   254 
   369 
   255 			var self = this;
   370 			var self = this;
   261 					self._trigger( 'closed', event, self._handoff() );
   376 					self._trigger( 'closed', event, self._handoff() );
   262 				}
   377 				}
   263 			}));
   378 			}));
   264 		},
   379 		},
   265 
   380 
       
   381 		/**
       
   382 		 * Puts the pointer on top by increasing the z-index.
       
   383 		 *
       
   384 		 * @since 3.3.0
       
   385 		 */
   266 		sendToTop: function() {
   386 		sendToTop: function() {
   267 			if ( this.active )
   387 			if ( this.active )
   268 				this.pointer.css( 'z-index', zindex++ );
   388 				this.pointer.css( 'z-index', zindex++ );
   269 		},
   389 		},
   270 
   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 		 */
   271 		toggle: function( event ) {
   398 		toggle: function( event ) {
   272 			if ( this.pointer.is(':hidden') )
   399 			if ( this.pointer.is(':hidden') )
   273 				this.open( event );
   400 				this.open( event );
   274 			else
   401 			else
   275 				this.close( event );
   402 				this.close( event );
   276 		},
   403 		},
   277 
   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 		 */
   278 		_handoff: function( extend ) {
   416 		_handoff: function( extend ) {
   279 			return $.extend({
   417 			return $.extend({
   280 				pointer: this.pointer,
   418 				pointer: this.pointer,
   281 				element: this.element
   419 				element: this.element
   282 			}, extend);
   420 			}, extend);