25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1220 lines
30 KiB

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