wp/wp-includes/js/jquery/ui/resizable.js
changeset 18 be944660c56a
child 19 3d72ae0968f4
equal deleted inserted replaced
17:34716fd837a4 18:be944660c56a
       
     1 /*!
       
     2  * jQuery UI Resizable 1.12.1
       
     3  * http://jqueryui.com
       
     4  *
       
     5  * Copyright jQuery Foundation and other contributors
       
     6  * Released under the MIT license.
       
     7  * http://jquery.org/license
       
     8  */
       
     9 
       
    10 //>>label: Resizable
       
    11 //>>group: Interactions
       
    12 //>>description: Enables resize functionality for any element.
       
    13 //>>docs: http://api.jqueryui.com/resizable/
       
    14 //>>demos: http://jqueryui.com/resizable/
       
    15 //>>css.structure: ../../themes/base/core.css
       
    16 //>>css.structure: ../../themes/base/resizable.css
       
    17 //>>css.theme: ../../themes/base/theme.css
       
    18 
       
    19 ( function( factory ) {
       
    20 	if ( typeof define === "function" && define.amd ) {
       
    21 
       
    22 		// AMD. Register as an anonymous module.
       
    23 		define( [
       
    24 			"jquery",
       
    25 			"./mouse",
       
    26 			"./core"
       
    27 		], factory );
       
    28 	} else {
       
    29 
       
    30 		// Browser globals
       
    31 		factory( jQuery );
       
    32 	}
       
    33 }( function( $ ) {
       
    34 
       
    35 $.widget( "ui.resizable", $.ui.mouse, {
       
    36 	version: "1.12.1",
       
    37 	widgetEventPrefix: "resize",
       
    38 	options: {
       
    39 		alsoResize: false,
       
    40 		animate: false,
       
    41 		animateDuration: "slow",
       
    42 		animateEasing: "swing",
       
    43 		aspectRatio: false,
       
    44 		autoHide: false,
       
    45 		classes: {
       
    46 			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
       
    47 		},
       
    48 		containment: false,
       
    49 		ghost: false,
       
    50 		grid: false,
       
    51 		handles: "e,s,se",
       
    52 		helper: false,
       
    53 		maxHeight: null,
       
    54 		maxWidth: null,
       
    55 		minHeight: 10,
       
    56 		minWidth: 10,
       
    57 
       
    58 		// See #7960
       
    59 		zIndex: 90,
       
    60 
       
    61 		// Callbacks
       
    62 		resize: null,
       
    63 		start: null,
       
    64 		stop: null
       
    65 	},
       
    66 
       
    67 	_num: function( value ) {
       
    68 		return parseFloat( value ) || 0;
       
    69 	},
       
    70 
       
    71 	_isNumber: function( value ) {
       
    72 		return !isNaN( parseFloat( value ) );
       
    73 	},
       
    74 
       
    75 	_hasScroll: function( el, a ) {
       
    76 
       
    77 		if ( $( el ).css( "overflow" ) === "hidden" ) {
       
    78 			return false;
       
    79 		}
       
    80 
       
    81 		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
       
    82 			has = false;
       
    83 
       
    84 		if ( el[ scroll ] > 0 ) {
       
    85 			return true;
       
    86 		}
       
    87 
       
    88 		// TODO: determine which cases actually cause this to happen
       
    89 		// if the element doesn't have the scroll set, see if it's possible to
       
    90 		// set the scroll
       
    91 		el[ scroll ] = 1;
       
    92 		has = ( el[ scroll ] > 0 );
       
    93 		el[ scroll ] = 0;
       
    94 		return has;
       
    95 	},
       
    96 
       
    97 	_create: function() {
       
    98 
       
    99 		var margins,
       
   100 			o = this.options,
       
   101 			that = this;
       
   102 		this._addClass( "ui-resizable" );
       
   103 
       
   104 		$.extend( this, {
       
   105 			_aspectRatio: !!( o.aspectRatio ),
       
   106 			aspectRatio: o.aspectRatio,
       
   107 			originalElement: this.element,
       
   108 			_proportionallyResizeElements: [],
       
   109 			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
       
   110 		} );
       
   111 
       
   112 		// Wrap the element if it cannot hold child nodes
       
   113 		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
       
   114 
       
   115 			this.element.wrap(
       
   116 				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
       
   117 					position: this.element.css( "position" ),
       
   118 					width: this.element.outerWidth(),
       
   119 					height: this.element.outerHeight(),
       
   120 					top: this.element.css( "top" ),
       
   121 					left: this.element.css( "left" )
       
   122 				} )
       
   123 			);
       
   124 
       
   125 			this.element = this.element.parent().data(
       
   126 				"ui-resizable", this.element.resizable( "instance" )
       
   127 			);
       
   128 
       
   129 			this.elementIsWrapper = true;
       
   130 
       
   131 			margins = {
       
   132 				marginTop: this.originalElement.css( "marginTop" ),
       
   133 				marginRight: this.originalElement.css( "marginRight" ),
       
   134 				marginBottom: this.originalElement.css( "marginBottom" ),
       
   135 				marginLeft: this.originalElement.css( "marginLeft" )
       
   136 			};
       
   137 
       
   138 			this.element.css( margins );
       
   139 			this.originalElement.css( "margin", 0 );
       
   140 
       
   141 			// support: Safari
       
   142 			// Prevent Safari textarea resize
       
   143 			this.originalResizeStyle = this.originalElement.css( "resize" );
       
   144 			this.originalElement.css( "resize", "none" );
       
   145 
       
   146 			this._proportionallyResizeElements.push( this.originalElement.css( {
       
   147 				position: "static",
       
   148 				zoom: 1,
       
   149 				display: "block"
       
   150 			} ) );
       
   151 
       
   152 			// Support: IE9
       
   153 			// avoid IE jump (hard set the margin)
       
   154 			this.originalElement.css( margins );
       
   155 
       
   156 			this._proportionallyResize();
       
   157 		}
       
   158 
       
   159 		this._setupHandles();
       
   160 
       
   161 		if ( o.autoHide ) {
       
   162 			$( this.element )
       
   163 				.on( "mouseenter", function() {
       
   164 					if ( o.disabled ) {
       
   165 						return;
       
   166 					}
       
   167 					that._removeClass( "ui-resizable-autohide" );
       
   168 					that._handles.show();
       
   169 				} )
       
   170 				.on( "mouseleave", function() {
       
   171 					if ( o.disabled ) {
       
   172 						return;
       
   173 					}
       
   174 					if ( !that.resizing ) {
       
   175 						that._addClass( "ui-resizable-autohide" );
       
   176 						that._handles.hide();
       
   177 					}
       
   178 				} );
       
   179 		}
       
   180 
       
   181 		this._mouseInit();
       
   182 	},
       
   183 
       
   184 	_destroy: function() {
       
   185 
       
   186 		this._mouseDestroy();
       
   187 
       
   188 		var wrapper,
       
   189 			_destroy = function( exp ) {
       
   190 				$( exp )
       
   191 					.removeData( "resizable" )
       
   192 					.removeData( "ui-resizable" )
       
   193 					.off( ".resizable" )
       
   194 					.find( ".ui-resizable-handle" )
       
   195 						.remove();
       
   196 			};
       
   197 
       
   198 		// TODO: Unwrap at same DOM position
       
   199 		if ( this.elementIsWrapper ) {
       
   200 			_destroy( this.element );
       
   201 			wrapper = this.element;
       
   202 			this.originalElement.css( {
       
   203 				position: wrapper.css( "position" ),
       
   204 				width: wrapper.outerWidth(),
       
   205 				height: wrapper.outerHeight(),
       
   206 				top: wrapper.css( "top" ),
       
   207 				left: wrapper.css( "left" )
       
   208 			} ).insertAfter( wrapper );
       
   209 			wrapper.remove();
       
   210 		}
       
   211 
       
   212 		this.originalElement.css( "resize", this.originalResizeStyle );
       
   213 		_destroy( this.originalElement );
       
   214 
       
   215 		return this;
       
   216 	},
       
   217 
       
   218 	_setOption: function( key, value ) {
       
   219 		this._super( key, value );
       
   220 
       
   221 		switch ( key ) {
       
   222 		case "handles":
       
   223 			this._removeHandles();
       
   224 			this._setupHandles();
       
   225 			break;
       
   226 		default:
       
   227 			break;
       
   228 		}
       
   229 	},
       
   230 
       
   231 	_setupHandles: function() {
       
   232 		var o = this.options, handle, i, n, hname, axis, that = this;
       
   233 		this.handles = o.handles ||
       
   234 			( !$( ".ui-resizable-handle", this.element ).length ?
       
   235 				"e,s,se" : {
       
   236 					n: ".ui-resizable-n",
       
   237 					e: ".ui-resizable-e",
       
   238 					s: ".ui-resizable-s",
       
   239 					w: ".ui-resizable-w",
       
   240 					se: ".ui-resizable-se",
       
   241 					sw: ".ui-resizable-sw",
       
   242 					ne: ".ui-resizable-ne",
       
   243 					nw: ".ui-resizable-nw"
       
   244 				} );
       
   245 
       
   246 		this._handles = $();
       
   247 		if ( this.handles.constructor === String ) {
       
   248 
       
   249 			if ( this.handles === "all" ) {
       
   250 				this.handles = "n,e,s,w,se,sw,ne,nw";
       
   251 			}
       
   252 
       
   253 			n = this.handles.split( "," );
       
   254 			this.handles = {};
       
   255 
       
   256 			for ( i = 0; i < n.length; i++ ) {
       
   257 
       
   258 				handle = $.trim( n[ i ] );
       
   259 				hname = "ui-resizable-" + handle;
       
   260 				axis = $( "<div>" );
       
   261 				this._addClass( axis, "ui-resizable-handle " + hname );
       
   262 
       
   263 				axis.css( { zIndex: o.zIndex } );
       
   264 
       
   265 				this.handles[ handle ] = ".ui-resizable-" + handle;
       
   266 				this.element.append( axis );
       
   267 			}
       
   268 
       
   269 		}
       
   270 
       
   271 		this._renderAxis = function( target ) {
       
   272 
       
   273 			var i, axis, padPos, padWrapper;
       
   274 
       
   275 			target = target || this.element;
       
   276 
       
   277 			for ( i in this.handles ) {
       
   278 
       
   279 				if ( this.handles[ i ].constructor === String ) {
       
   280 					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
       
   281 				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
       
   282 					this.handles[ i ] = $( this.handles[ i ] );
       
   283 					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
       
   284 				}
       
   285 
       
   286 				if ( this.elementIsWrapper &&
       
   287 						this.originalElement[ 0 ]
       
   288 							.nodeName
       
   289 							.match( /^(textarea|input|select|button)$/i ) ) {
       
   290 					axis = $( this.handles[ i ], this.element );
       
   291 
       
   292 					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
       
   293 						axis.outerHeight() :
       
   294 						axis.outerWidth();
       
   295 
       
   296 					padPos = [ "padding",
       
   297 						/ne|nw|n/.test( i ) ? "Top" :
       
   298 						/se|sw|s/.test( i ) ? "Bottom" :
       
   299 						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
       
   300 
       
   301 					target.css( padPos, padWrapper );
       
   302 
       
   303 					this._proportionallyResize();
       
   304 				}
       
   305 
       
   306 				this._handles = this._handles.add( this.handles[ i ] );
       
   307 			}
       
   308 		};
       
   309 
       
   310 		// TODO: make renderAxis a prototype function
       
   311 		this._renderAxis( this.element );
       
   312 
       
   313 		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
       
   314 		this._handles.disableSelection();
       
   315 
       
   316 		this._handles.on( "mouseover", function() {
       
   317 			if ( !that.resizing ) {
       
   318 				if ( this.className ) {
       
   319 					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
       
   320 				}
       
   321 				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
       
   322 			}
       
   323 		} );
       
   324 
       
   325 		if ( o.autoHide ) {
       
   326 			this._handles.hide();
       
   327 			this._addClass( "ui-resizable-autohide" );
       
   328 		}
       
   329 	},
       
   330 
       
   331 	_removeHandles: function() {
       
   332 		this._handles.remove();
       
   333 	},
       
   334 
       
   335 	_mouseCapture: function( event ) {
       
   336 		var i, handle,
       
   337 			capture = false;
       
   338 
       
   339 		for ( i in this.handles ) {
       
   340 			handle = $( this.handles[ i ] )[ 0 ];
       
   341 			if ( handle === event.target || $.contains( handle, event.target ) ) {
       
   342 				capture = true;
       
   343 			}
       
   344 		}
       
   345 
       
   346 		return !this.options.disabled && capture;
       
   347 	},
       
   348 
       
   349 	_mouseStart: function( event ) {
       
   350 
       
   351 		var curleft, curtop, cursor,
       
   352 			o = this.options,
       
   353 			el = this.element;
       
   354 
       
   355 		this.resizing = true;
       
   356 
       
   357 		this._renderProxy();
       
   358 
       
   359 		curleft = this._num( this.helper.css( "left" ) );
       
   360 		curtop = this._num( this.helper.css( "top" ) );
       
   361 
       
   362 		if ( o.containment ) {
       
   363 			curleft += $( o.containment ).scrollLeft() || 0;
       
   364 			curtop += $( o.containment ).scrollTop() || 0;
       
   365 		}
       
   366 
       
   367 		this.offset = this.helper.offset();
       
   368 		this.position = { left: curleft, top: curtop };
       
   369 
       
   370 		this.size = this._helper ? {
       
   371 				width: this.helper.width(),
       
   372 				height: this.helper.height()
       
   373 			} : {
       
   374 				width: el.width(),
       
   375 				height: el.height()
       
   376 			};
       
   377 
       
   378 		this.originalSize = this._helper ? {
       
   379 				width: el.outerWidth(),
       
   380 				height: el.outerHeight()
       
   381 			} : {
       
   382 				width: el.width(),
       
   383 				height: el.height()
       
   384 			};
       
   385 
       
   386 		this.sizeDiff = {
       
   387 			width: el.outerWidth() - el.width(),
       
   388 			height: el.outerHeight() - el.height()
       
   389 		};
       
   390 
       
   391 		this.originalPosition = { left: curleft, top: curtop };
       
   392 		this.originalMousePosition = { left: event.pageX, top: event.pageY };
       
   393 
       
   394 		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
       
   395 			o.aspectRatio :
       
   396 			( ( this.originalSize.width / this.originalSize.height ) || 1 );
       
   397 
       
   398 		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
       
   399 		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
       
   400 
       
   401 		this._addClass( "ui-resizable-resizing" );
       
   402 		this._propagate( "start", event );
       
   403 		return true;
       
   404 	},
       
   405 
       
   406 	_mouseDrag: function( event ) {
       
   407 
       
   408 		var data, props,
       
   409 			smp = this.originalMousePosition,
       
   410 			a = this.axis,
       
   411 			dx = ( event.pageX - smp.left ) || 0,
       
   412 			dy = ( event.pageY - smp.top ) || 0,
       
   413 			trigger = this._change[ a ];
       
   414 
       
   415 		this._updatePrevProperties();
       
   416 
       
   417 		if ( !trigger ) {
       
   418 			return false;
       
   419 		}
       
   420 
       
   421 		data = trigger.apply( this, [ event, dx, dy ] );
       
   422 
       
   423 		this._updateVirtualBoundaries( event.shiftKey );
       
   424 		if ( this._aspectRatio || event.shiftKey ) {
       
   425 			data = this._updateRatio( data, event );
       
   426 		}
       
   427 
       
   428 		data = this._respectSize( data, event );
       
   429 
       
   430 		this._updateCache( data );
       
   431 
       
   432 		this._propagate( "resize", event );
       
   433 
       
   434 		props = this._applyChanges();
       
   435 
       
   436 		if ( !this._helper && this._proportionallyResizeElements.length ) {
       
   437 			this._proportionallyResize();
       
   438 		}
       
   439 
       
   440 		if ( !$.isEmptyObject( props ) ) {
       
   441 			this._updatePrevProperties();
       
   442 			this._trigger( "resize", event, this.ui() );
       
   443 			this._applyChanges();
       
   444 		}
       
   445 
       
   446 		return false;
       
   447 	},
       
   448 
       
   449 	_mouseStop: function( event ) {
       
   450 
       
   451 		this.resizing = false;
       
   452 		var pr, ista, soffseth, soffsetw, s, left, top,
       
   453 			o = this.options, that = this;
       
   454 
       
   455 		if ( this._helper ) {
       
   456 
       
   457 			pr = this._proportionallyResizeElements;
       
   458 			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
       
   459 			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
       
   460 			soffsetw = ista ? 0 : that.sizeDiff.width;
       
   461 
       
   462 			s = {
       
   463 				width: ( that.helper.width()  - soffsetw ),
       
   464 				height: ( that.helper.height() - soffseth )
       
   465 			};
       
   466 			left = ( parseFloat( that.element.css( "left" ) ) +
       
   467 				( that.position.left - that.originalPosition.left ) ) || null;
       
   468 			top = ( parseFloat( that.element.css( "top" ) ) +
       
   469 				( that.position.top - that.originalPosition.top ) ) || null;
       
   470 
       
   471 			if ( !o.animate ) {
       
   472 				this.element.css( $.extend( s, { top: top, left: left } ) );
       
   473 			}
       
   474 
       
   475 			that.helper.height( that.size.height );
       
   476 			that.helper.width( that.size.width );
       
   477 
       
   478 			if ( this._helper && !o.animate ) {
       
   479 				this._proportionallyResize();
       
   480 			}
       
   481 		}
       
   482 
       
   483 		$( "body" ).css( "cursor", "auto" );
       
   484 
       
   485 		this._removeClass( "ui-resizable-resizing" );
       
   486 
       
   487 		this._propagate( "stop", event );
       
   488 
       
   489 		if ( this._helper ) {
       
   490 			this.helper.remove();
       
   491 		}
       
   492 
       
   493 		return false;
       
   494 
       
   495 	},
       
   496 
       
   497 	_updatePrevProperties: function() {
       
   498 		this.prevPosition = {
       
   499 			top: this.position.top,
       
   500 			left: this.position.left
       
   501 		};
       
   502 		this.prevSize = {
       
   503 			width: this.size.width,
       
   504 			height: this.size.height
       
   505 		};
       
   506 	},
       
   507 
       
   508 	_applyChanges: function() {
       
   509 		var props = {};
       
   510 
       
   511 		if ( this.position.top !== this.prevPosition.top ) {
       
   512 			props.top = this.position.top + "px";
       
   513 		}
       
   514 		if ( this.position.left !== this.prevPosition.left ) {
       
   515 			props.left = this.position.left + "px";
       
   516 		}
       
   517 		if ( this.size.width !== this.prevSize.width ) {
       
   518 			props.width = this.size.width + "px";
       
   519 		}
       
   520 		if ( this.size.height !== this.prevSize.height ) {
       
   521 			props.height = this.size.height + "px";
       
   522 		}
       
   523 
       
   524 		this.helper.css( props );
       
   525 
       
   526 		return props;
       
   527 	},
       
   528 
       
   529 	_updateVirtualBoundaries: function( forceAspectRatio ) {
       
   530 		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
       
   531 			o = this.options;
       
   532 
       
   533 		b = {
       
   534 			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
       
   535 			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
       
   536 			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
       
   537 			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
       
   538 		};
       
   539 
       
   540 		if ( this._aspectRatio || forceAspectRatio ) {
       
   541 			pMinWidth = b.minHeight * this.aspectRatio;
       
   542 			pMinHeight = b.minWidth / this.aspectRatio;
       
   543 			pMaxWidth = b.maxHeight * this.aspectRatio;
       
   544 			pMaxHeight = b.maxWidth / this.aspectRatio;
       
   545 
       
   546 			if ( pMinWidth > b.minWidth ) {
       
   547 				b.minWidth = pMinWidth;
       
   548 			}
       
   549 			if ( pMinHeight > b.minHeight ) {
       
   550 				b.minHeight = pMinHeight;
       
   551 			}
       
   552 			if ( pMaxWidth < b.maxWidth ) {
       
   553 				b.maxWidth = pMaxWidth;
       
   554 			}
       
   555 			if ( pMaxHeight < b.maxHeight ) {
       
   556 				b.maxHeight = pMaxHeight;
       
   557 			}
       
   558 		}
       
   559 		this._vBoundaries = b;
       
   560 	},
       
   561 
       
   562 	_updateCache: function( data ) {
       
   563 		this.offset = this.helper.offset();
       
   564 		if ( this._isNumber( data.left ) ) {
       
   565 			this.position.left = data.left;
       
   566 		}
       
   567 		if ( this._isNumber( data.top ) ) {
       
   568 			this.position.top = data.top;
       
   569 		}
       
   570 		if ( this._isNumber( data.height ) ) {
       
   571 			this.size.height = data.height;
       
   572 		}
       
   573 		if ( this._isNumber( data.width ) ) {
       
   574 			this.size.width = data.width;
       
   575 		}
       
   576 	},
       
   577 
       
   578 	_updateRatio: function( data ) {
       
   579 
       
   580 		var cpos = this.position,
       
   581 			csize = this.size,
       
   582 			a = this.axis;
       
   583 
       
   584 		if ( this._isNumber( data.height ) ) {
       
   585 			data.width = ( data.height * this.aspectRatio );
       
   586 		} else if ( this._isNumber( data.width ) ) {
       
   587 			data.height = ( data.width / this.aspectRatio );
       
   588 		}
       
   589 
       
   590 		if ( a === "sw" ) {
       
   591 			data.left = cpos.left + ( csize.width - data.width );
       
   592 			data.top = null;
       
   593 		}
       
   594 		if ( a === "nw" ) {
       
   595 			data.top = cpos.top + ( csize.height - data.height );
       
   596 			data.left = cpos.left + ( csize.width - data.width );
       
   597 		}
       
   598 
       
   599 		return data;
       
   600 	},
       
   601 
       
   602 	_respectSize: function( data ) {
       
   603 
       
   604 		var o = this._vBoundaries,
       
   605 			a = this.axis,
       
   606 			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
       
   607 			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
       
   608 			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
       
   609 			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
       
   610 			dw = this.originalPosition.left + this.originalSize.width,
       
   611 			dh = this.originalPosition.top + this.originalSize.height,
       
   612 			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
       
   613 		if ( isminw ) {
       
   614 			data.width = o.minWidth;
       
   615 		}
       
   616 		if ( isminh ) {
       
   617 			data.height = o.minHeight;
       
   618 		}
       
   619 		if ( ismaxw ) {
       
   620 			data.width = o.maxWidth;
       
   621 		}
       
   622 		if ( ismaxh ) {
       
   623 			data.height = o.maxHeight;
       
   624 		}
       
   625 
       
   626 		if ( isminw && cw ) {
       
   627 			data.left = dw - o.minWidth;
       
   628 		}
       
   629 		if ( ismaxw && cw ) {
       
   630 			data.left = dw - o.maxWidth;
       
   631 		}
       
   632 		if ( isminh && ch ) {
       
   633 			data.top = dh - o.minHeight;
       
   634 		}
       
   635 		if ( ismaxh && ch ) {
       
   636 			data.top = dh - o.maxHeight;
       
   637 		}
       
   638 
       
   639 		// Fixing jump error on top/left - bug #2330
       
   640 		if ( !data.width && !data.height && !data.left && data.top ) {
       
   641 			data.top = null;
       
   642 		} else if ( !data.width && !data.height && !data.top && data.left ) {
       
   643 			data.left = null;
       
   644 		}
       
   645 
       
   646 		return data;
       
   647 	},
       
   648 
       
   649 	_getPaddingPlusBorderDimensions: function( element ) {
       
   650 		var i = 0,
       
   651 			widths = [],
       
   652 			borders = [
       
   653 				element.css( "borderTopWidth" ),
       
   654 				element.css( "borderRightWidth" ),
       
   655 				element.css( "borderBottomWidth" ),
       
   656 				element.css( "borderLeftWidth" )
       
   657 			],
       
   658 			paddings = [
       
   659 				element.css( "paddingTop" ),
       
   660 				element.css( "paddingRight" ),
       
   661 				element.css( "paddingBottom" ),
       
   662 				element.css( "paddingLeft" )
       
   663 			];
       
   664 
       
   665 		for ( ; i < 4; i++ ) {
       
   666 			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
       
   667 			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
       
   668 		}
       
   669 
       
   670 		return {
       
   671 			height: widths[ 0 ] + widths[ 2 ],
       
   672 			width: widths[ 1 ] + widths[ 3 ]
       
   673 		};
       
   674 	},
       
   675 
       
   676 	_proportionallyResize: function() {
       
   677 
       
   678 		if ( !this._proportionallyResizeElements.length ) {
       
   679 			return;
       
   680 		}
       
   681 
       
   682 		var prel,
       
   683 			i = 0,
       
   684 			element = this.helper || this.element;
       
   685 
       
   686 		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
       
   687 
       
   688 			prel = this._proportionallyResizeElements[ i ];
       
   689 
       
   690 			// TODO: Seems like a bug to cache this.outerDimensions
       
   691 			// considering that we are in a loop.
       
   692 			if ( !this.outerDimensions ) {
       
   693 				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
       
   694 			}
       
   695 
       
   696 			prel.css( {
       
   697 				height: ( element.height() - this.outerDimensions.height ) || 0,
       
   698 				width: ( element.width() - this.outerDimensions.width ) || 0
       
   699 			} );
       
   700 
       
   701 		}
       
   702 
       
   703 	},
       
   704 
       
   705 	_renderProxy: function() {
       
   706 
       
   707 		var el = this.element, o = this.options;
       
   708 		this.elementOffset = el.offset();
       
   709 
       
   710 		if ( this._helper ) {
       
   711 
       
   712 			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
       
   713 
       
   714 			this._addClass( this.helper, this._helper );
       
   715 			this.helper.css( {
       
   716 				width: this.element.outerWidth(),
       
   717 				height: this.element.outerHeight(),
       
   718 				position: "absolute",
       
   719 				left: this.elementOffset.left + "px",
       
   720 				top: this.elementOffset.top + "px",
       
   721 				zIndex: ++o.zIndex //TODO: Don't modify option
       
   722 			} );
       
   723 
       
   724 			this.helper
       
   725 				.appendTo( "body" )
       
   726 				.disableSelection();
       
   727 
       
   728 		} else {
       
   729 			this.helper = this.element;
       
   730 		}
       
   731 
       
   732 	},
       
   733 
       
   734 	_change: {
       
   735 		e: function( event, dx ) {
       
   736 			return { width: this.originalSize.width + dx };
       
   737 		},
       
   738 		w: function( event, dx ) {
       
   739 			var cs = this.originalSize, sp = this.originalPosition;
       
   740 			return { left: sp.left + dx, width: cs.width - dx };
       
   741 		},
       
   742 		n: function( event, dx, dy ) {
       
   743 			var cs = this.originalSize, sp = this.originalPosition;
       
   744 			return { top: sp.top + dy, height: cs.height - dy };
       
   745 		},
       
   746 		s: function( event, dx, dy ) {
       
   747 			return { height: this.originalSize.height + dy };
       
   748 		},
       
   749 		se: function( event, dx, dy ) {
       
   750 			return $.extend( this._change.s.apply( this, arguments ),
       
   751 				this._change.e.apply( this, [ event, dx, dy ] ) );
       
   752 		},
       
   753 		sw: function( event, dx, dy ) {
       
   754 			return $.extend( this._change.s.apply( this, arguments ),
       
   755 				this._change.w.apply( this, [ event, dx, dy ] ) );
       
   756 		},
       
   757 		ne: function( event, dx, dy ) {
       
   758 			return $.extend( this._change.n.apply( this, arguments ),
       
   759 				this._change.e.apply( this, [ event, dx, dy ] ) );
       
   760 		},
       
   761 		nw: function( event, dx, dy ) {
       
   762 			return $.extend( this._change.n.apply( this, arguments ),
       
   763 				this._change.w.apply( this, [ event, dx, dy ] ) );
       
   764 		}
       
   765 	},
       
   766 
       
   767 	_propagate: function( n, event ) {
       
   768 		$.ui.plugin.call( this, n, [ event, this.ui() ] );
       
   769 		( n !== "resize" && this._trigger( n, event, this.ui() ) );
       
   770 	},
       
   771 
       
   772 	plugins: {},
       
   773 
       
   774 	ui: function() {
       
   775 		return {
       
   776 			originalElement: this.originalElement,
       
   777 			element: this.element,
       
   778 			helper: this.helper,
       
   779 			position: this.position,
       
   780 			size: this.size,
       
   781 			originalSize: this.originalSize,
       
   782 			originalPosition: this.originalPosition
       
   783 		};
       
   784 	}
       
   785 
       
   786 } );
       
   787 
       
   788 /*
       
   789  * Resizable Extensions
       
   790  */
       
   791 
       
   792 $.ui.plugin.add( "resizable", "animate", {
       
   793 
       
   794 	stop: function( event ) {
       
   795 		var that = $( this ).resizable( "instance" ),
       
   796 			o = that.options,
       
   797 			pr = that._proportionallyResizeElements,
       
   798 			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
       
   799 			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
       
   800 			soffsetw = ista ? 0 : that.sizeDiff.width,
       
   801 			style = {
       
   802 				width: ( that.size.width - soffsetw ),
       
   803 				height: ( that.size.height - soffseth )
       
   804 			},
       
   805 			left = ( parseFloat( that.element.css( "left" ) ) +
       
   806 				( that.position.left - that.originalPosition.left ) ) || null,
       
   807 			top = ( parseFloat( that.element.css( "top" ) ) +
       
   808 				( that.position.top - that.originalPosition.top ) ) || null;
       
   809 
       
   810 		that.element.animate(
       
   811 			$.extend( style, top && left ? { top: top, left: left } : {} ), {
       
   812 				duration: o.animateDuration,
       
   813 				easing: o.animateEasing,
       
   814 				step: function() {
       
   815 
       
   816 					var data = {
       
   817 						width: parseFloat( that.element.css( "width" ) ),
       
   818 						height: parseFloat( that.element.css( "height" ) ),
       
   819 						top: parseFloat( that.element.css( "top" ) ),
       
   820 						left: parseFloat( that.element.css( "left" ) )
       
   821 					};
       
   822 
       
   823 					if ( pr && pr.length ) {
       
   824 						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
       
   825 					}
       
   826 
       
   827 					// Propagating resize, and updating values for each animation step
       
   828 					that._updateCache( data );
       
   829 					that._propagate( "resize", event );
       
   830 
       
   831 				}
       
   832 			}
       
   833 		);
       
   834 	}
       
   835 
       
   836 } );
       
   837 
       
   838 $.ui.plugin.add( "resizable", "containment", {
       
   839 
       
   840 	start: function() {
       
   841 		var element, p, co, ch, cw, width, height,
       
   842 			that = $( this ).resizable( "instance" ),
       
   843 			o = that.options,
       
   844 			el = that.element,
       
   845 			oc = o.containment,
       
   846 			ce = ( oc instanceof $ ) ?
       
   847 				oc.get( 0 ) :
       
   848 				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
       
   849 
       
   850 		if ( !ce ) {
       
   851 			return;
       
   852 		}
       
   853 
       
   854 		that.containerElement = $( ce );
       
   855 
       
   856 		if ( /document/.test( oc ) || oc === document ) {
       
   857 			that.containerOffset = {
       
   858 				left: 0,
       
   859 				top: 0
       
   860 			};
       
   861 			that.containerPosition = {
       
   862 				left: 0,
       
   863 				top: 0
       
   864 			};
       
   865 
       
   866 			that.parentData = {
       
   867 				element: $( document ),
       
   868 				left: 0,
       
   869 				top: 0,
       
   870 				width: $( document ).width(),
       
   871 				height: $( document ).height() || document.body.parentNode.scrollHeight
       
   872 			};
       
   873 		} else {
       
   874 			element = $( ce );
       
   875 			p = [];
       
   876 			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
       
   877 				p[ i ] = that._num( element.css( "padding" + name ) );
       
   878 			} );
       
   879 
       
   880 			that.containerOffset = element.offset();
       
   881 			that.containerPosition = element.position();
       
   882 			that.containerSize = {
       
   883 				height: ( element.innerHeight() - p[ 3 ] ),
       
   884 				width: ( element.innerWidth() - p[ 1 ] )
       
   885 			};
       
   886 
       
   887 			co = that.containerOffset;
       
   888 			ch = that.containerSize.height;
       
   889 			cw = that.containerSize.width;
       
   890 			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
       
   891 			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
       
   892 
       
   893 			that.parentData = {
       
   894 				element: ce,
       
   895 				left: co.left,
       
   896 				top: co.top,
       
   897 				width: width,
       
   898 				height: height
       
   899 			};
       
   900 		}
       
   901 	},
       
   902 
       
   903 	resize: function( event ) {
       
   904 		var woset, hoset, isParent, isOffsetRelative,
       
   905 			that = $( this ).resizable( "instance" ),
       
   906 			o = that.options,
       
   907 			co = that.containerOffset,
       
   908 			cp = that.position,
       
   909 			pRatio = that._aspectRatio || event.shiftKey,
       
   910 			cop = {
       
   911 				top: 0,
       
   912 				left: 0
       
   913 			},
       
   914 			ce = that.containerElement,
       
   915 			continueResize = true;
       
   916 
       
   917 		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
       
   918 			cop = co;
       
   919 		}
       
   920 
       
   921 		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
       
   922 			that.size.width = that.size.width +
       
   923 				( that._helper ?
       
   924 					( that.position.left - co.left ) :
       
   925 					( that.position.left - cop.left ) );
       
   926 
       
   927 			if ( pRatio ) {
       
   928 				that.size.height = that.size.width / that.aspectRatio;
       
   929 				continueResize = false;
       
   930 			}
       
   931 			that.position.left = o.helper ? co.left : 0;
       
   932 		}
       
   933 
       
   934 		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
       
   935 			that.size.height = that.size.height +
       
   936 				( that._helper ?
       
   937 					( that.position.top - co.top ) :
       
   938 					that.position.top );
       
   939 
       
   940 			if ( pRatio ) {
       
   941 				that.size.width = that.size.height * that.aspectRatio;
       
   942 				continueResize = false;
       
   943 			}
       
   944 			that.position.top = that._helper ? co.top : 0;
       
   945 		}
       
   946 
       
   947 		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
       
   948 		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
       
   949 
       
   950 		if ( isParent && isOffsetRelative ) {
       
   951 			that.offset.left = that.parentData.left + that.position.left;
       
   952 			that.offset.top = that.parentData.top + that.position.top;
       
   953 		} else {
       
   954 			that.offset.left = that.element.offset().left;
       
   955 			that.offset.top = that.element.offset().top;
       
   956 		}
       
   957 
       
   958 		woset = Math.abs( that.sizeDiff.width +
       
   959 			( that._helper ?
       
   960 				that.offset.left - cop.left :
       
   961 				( that.offset.left - co.left ) ) );
       
   962 
       
   963 		hoset = Math.abs( that.sizeDiff.height +
       
   964 			( that._helper ?
       
   965 				that.offset.top - cop.top :
       
   966 				( that.offset.top - co.top ) ) );
       
   967 
       
   968 		if ( woset + that.size.width >= that.parentData.width ) {
       
   969 			that.size.width = that.parentData.width - woset;
       
   970 			if ( pRatio ) {
       
   971 				that.size.height = that.size.width / that.aspectRatio;
       
   972 				continueResize = false;
       
   973 			}
       
   974 		}
       
   975 
       
   976 		if ( hoset + that.size.height >= that.parentData.height ) {
       
   977 			that.size.height = that.parentData.height - hoset;
       
   978 			if ( pRatio ) {
       
   979 				that.size.width = that.size.height * that.aspectRatio;
       
   980 				continueResize = false;
       
   981 			}
       
   982 		}
       
   983 
       
   984 		if ( !continueResize ) {
       
   985 			that.position.left = that.prevPosition.left;
       
   986 			that.position.top = that.prevPosition.top;
       
   987 			that.size.width = that.prevSize.width;
       
   988 			that.size.height = that.prevSize.height;
       
   989 		}
       
   990 	},
       
   991 
       
   992 	stop: function() {
       
   993 		var that = $( this ).resizable( "instance" ),
       
   994 			o = that.options,
       
   995 			co = that.containerOffset,
       
   996 			cop = that.containerPosition,
       
   997 			ce = that.containerElement,
       
   998 			helper = $( that.helper ),
       
   999 			ho = helper.offset(),
       
  1000 			w = helper.outerWidth() - that.sizeDiff.width,
       
  1001 			h = helper.outerHeight() - that.sizeDiff.height;
       
  1002 
       
  1003 		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
       
  1004 			$( this ).css( {
       
  1005 				left: ho.left - cop.left - co.left,
       
  1006 				width: w,
       
  1007 				height: h
       
  1008 			} );
       
  1009 		}
       
  1010 
       
  1011 		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
       
  1012 			$( this ).css( {
       
  1013 				left: ho.left - cop.left - co.left,
       
  1014 				width: w,
       
  1015 				height: h
       
  1016 			} );
       
  1017 		}
       
  1018 	}
       
  1019 } );
       
  1020 
       
  1021 $.ui.plugin.add( "resizable", "alsoResize", {
       
  1022 
       
  1023 	start: function() {
       
  1024 		var that = $( this ).resizable( "instance" ),
       
  1025 			o = that.options;
       
  1026 
       
  1027 		$( o.alsoResize ).each( function() {
       
  1028 			var el = $( this );
       
  1029 			el.data( "ui-resizable-alsoresize", {
       
  1030 				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
       
  1031 				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
       
  1032 			} );
       
  1033 		} );
       
  1034 	},
       
  1035 
       
  1036 	resize: function( event, ui ) {
       
  1037 		var that = $( this ).resizable( "instance" ),
       
  1038 			o = that.options,
       
  1039 			os = that.originalSize,
       
  1040 			op = that.originalPosition,
       
  1041 			delta = {
       
  1042 				height: ( that.size.height - os.height ) || 0,
       
  1043 				width: ( that.size.width - os.width ) || 0,
       
  1044 				top: ( that.position.top - op.top ) || 0,
       
  1045 				left: ( that.position.left - op.left ) || 0
       
  1046 			};
       
  1047 
       
  1048 			$( o.alsoResize ).each( function() {
       
  1049 				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
       
  1050 					css = el.parents( ui.originalElement[ 0 ] ).length ?
       
  1051 							[ "width", "height" ] :
       
  1052 							[ "width", "height", "top", "left" ];
       
  1053 
       
  1054 				$.each( css, function( i, prop ) {
       
  1055 					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
       
  1056 					if ( sum && sum >= 0 ) {
       
  1057 						style[ prop ] = sum || null;
       
  1058 					}
       
  1059 				} );
       
  1060 
       
  1061 				el.css( style );
       
  1062 			} );
       
  1063 	},
       
  1064 
       
  1065 	stop: function() {
       
  1066 		$( this ).removeData( "ui-resizable-alsoresize" );
       
  1067 	}
       
  1068 } );
       
  1069 
       
  1070 $.ui.plugin.add( "resizable", "ghost", {
       
  1071 
       
  1072 	start: function() {
       
  1073 
       
  1074 		var that = $( this ).resizable( "instance" ), cs = that.size;
       
  1075 
       
  1076 		that.ghost = that.originalElement.clone();
       
  1077 		that.ghost.css( {
       
  1078 			opacity: 0.25,
       
  1079 			display: "block",
       
  1080 			position: "relative",
       
  1081 			height: cs.height,
       
  1082 			width: cs.width,
       
  1083 			margin: 0,
       
  1084 			left: 0,
       
  1085 			top: 0
       
  1086 		} );
       
  1087 
       
  1088 		that._addClass( that.ghost, "ui-resizable-ghost" );
       
  1089 
       
  1090 		// DEPRECATED
       
  1091 		// TODO: remove after 1.12
       
  1092 		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
       
  1093 
       
  1094 			// Ghost option
       
  1095 			that.ghost.addClass( this.options.ghost );
       
  1096 		}
       
  1097 
       
  1098 		that.ghost.appendTo( that.helper );
       
  1099 
       
  1100 	},
       
  1101 
       
  1102 	resize: function() {
       
  1103 		var that = $( this ).resizable( "instance" );
       
  1104 		if ( that.ghost ) {
       
  1105 			that.ghost.css( {
       
  1106 				position: "relative",
       
  1107 				height: that.size.height,
       
  1108 				width: that.size.width
       
  1109 			} );
       
  1110 		}
       
  1111 	},
       
  1112 
       
  1113 	stop: function() {
       
  1114 		var that = $( this ).resizable( "instance" );
       
  1115 		if ( that.ghost && that.helper ) {
       
  1116 			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
       
  1117 		}
       
  1118 	}
       
  1119 
       
  1120 } );
       
  1121 
       
  1122 $.ui.plugin.add( "resizable", "grid", {
       
  1123 
       
  1124 	resize: function() {
       
  1125 		var outerDimensions,
       
  1126 			that = $( this ).resizable( "instance" ),
       
  1127 			o = that.options,
       
  1128 			cs = that.size,
       
  1129 			os = that.originalSize,
       
  1130 			op = that.originalPosition,
       
  1131 			a = that.axis,
       
  1132 			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
       
  1133 			gridX = ( grid[ 0 ] || 1 ),
       
  1134 			gridY = ( grid[ 1 ] || 1 ),
       
  1135 			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
       
  1136 			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
       
  1137 			newWidth = os.width + ox,
       
  1138 			newHeight = os.height + oy,
       
  1139 			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
       
  1140 			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
       
  1141 			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
       
  1142 			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
       
  1143 
       
  1144 		o.grid = grid;
       
  1145 
       
  1146 		if ( isMinWidth ) {
       
  1147 			newWidth += gridX;
       
  1148 		}
       
  1149 		if ( isMinHeight ) {
       
  1150 			newHeight += gridY;
       
  1151 		}
       
  1152 		if ( isMaxWidth ) {
       
  1153 			newWidth -= gridX;
       
  1154 		}
       
  1155 		if ( isMaxHeight ) {
       
  1156 			newHeight -= gridY;
       
  1157 		}
       
  1158 
       
  1159 		if ( /^(se|s|e)$/.test( a ) ) {
       
  1160 			that.size.width = newWidth;
       
  1161 			that.size.height = newHeight;
       
  1162 		} else if ( /^(ne)$/.test( a ) ) {
       
  1163 			that.size.width = newWidth;
       
  1164 			that.size.height = newHeight;
       
  1165 			that.position.top = op.top - oy;
       
  1166 		} else if ( /^(sw)$/.test( a ) ) {
       
  1167 			that.size.width = newWidth;
       
  1168 			that.size.height = newHeight;
       
  1169 			that.position.left = op.left - ox;
       
  1170 		} else {
       
  1171 			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
       
  1172 				outerDimensions = that._getPaddingPlusBorderDimensions( this );
       
  1173 			}
       
  1174 
       
  1175 			if ( newHeight - gridY > 0 ) {
       
  1176 				that.size.height = newHeight;
       
  1177 				that.position.top = op.top - oy;
       
  1178 			} else {
       
  1179 				newHeight = gridY - outerDimensions.height;
       
  1180 				that.size.height = newHeight;
       
  1181 				that.position.top = op.top + os.height - newHeight;
       
  1182 			}
       
  1183 			if ( newWidth - gridX > 0 ) {
       
  1184 				that.size.width = newWidth;
       
  1185 				that.position.left = op.left - ox;
       
  1186 			} else {
       
  1187 				newWidth = gridX - outerDimensions.width;
       
  1188 				that.size.width = newWidth;
       
  1189 				that.position.left = op.left + os.width - newWidth;
       
  1190 			}
       
  1191 		}
       
  1192 	}
       
  1193 
       
  1194 } );
       
  1195 
       
  1196 return $.ui.resizable;
       
  1197 
       
  1198 } ) );