You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1216 lines
30 KiB

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