Bez popisu

resizable.js 29KB

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