jquery-ui.custom.js 135 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204
  1. /*!
  2. * jQuery UI 1.8.7
  3. *
  4. * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  5. * Dual licensed under the MIT or GPL Version 2 licenses.
  6. * http://jquery.org/license
  7. *
  8. * http://docs.jquery.com/UI
  9. */
  10. (function( $, undefined ) {
  11. // prevent duplicate loading
  12. // this is only a problem because we proxy existing functions
  13. // and we don't want to double proxy them
  14. $.ui = $.ui || {};
  15. if ( $.ui.version ) {
  16. return;
  17. }
  18. $.extend( $.ui, {
  19. version: "1.8.7",
  20. keyCode: {
  21. ALT: 18,
  22. BACKSPACE: 8,
  23. CAPS_LOCK: 20,
  24. COMMA: 188,
  25. COMMAND: 91,
  26. COMMAND_LEFT: 91, // COMMAND
  27. COMMAND_RIGHT: 93,
  28. CONTROL: 17,
  29. DELETE: 46,
  30. DOWN: 40,
  31. END: 35,
  32. ENTER: 13,
  33. ESCAPE: 27,
  34. HOME: 36,
  35. INSERT: 45,
  36. LEFT: 37,
  37. MENU: 93, // COMMAND_RIGHT
  38. NUMPAD_ADD: 107,
  39. NUMPAD_DECIMAL: 110,
  40. NUMPAD_DIVIDE: 111,
  41. NUMPAD_ENTER: 108,
  42. NUMPAD_MULTIPLY: 106,
  43. NUMPAD_SUBTRACT: 109,
  44. PAGE_DOWN: 34,
  45. PAGE_UP: 33,
  46. PERIOD: 190,
  47. RIGHT: 39,
  48. SHIFT: 16,
  49. SPACE: 32,
  50. TAB: 9,
  51. UP: 38,
  52. WINDOWS: 91 // COMMAND
  53. }
  54. });
  55. // plugins
  56. $.fn.extend({
  57. _focus: $.fn.focus,
  58. focus: function( delay, fn ) {
  59. return typeof delay === "number" ?
  60. this.each(function() {
  61. var elem = this;
  62. setTimeout(function() {
  63. $( elem ).focus();
  64. if ( fn ) {
  65. fn.call( elem );
  66. }
  67. }, delay );
  68. }) :
  69. this._focus.apply( this, arguments );
  70. },
  71. scrollParent: function() {
  72. var scrollParent;
  73. if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
  74. scrollParent = this.parents().filter(function() {
  75. return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
  76. }).eq(0);
  77. } else {
  78. scrollParent = this.parents().filter(function() {
  79. return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
  80. }).eq(0);
  81. }
  82. return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
  83. },
  84. zIndex: function( zIndex ) {
  85. if ( zIndex !== undefined ) {
  86. return this.css( "zIndex", zIndex );
  87. }
  88. if ( this.length ) {
  89. var elem = $( this[ 0 ] ), position, value;
  90. while ( elem.length && elem[ 0 ] !== document ) {
  91. // Ignore z-index if position is set to a value where z-index is ignored by the browser
  92. // This makes behavior of this function consistent across browsers
  93. // WebKit always returns auto if the element is positioned
  94. position = elem.css( "position" );
  95. if ( position === "absolute" || position === "relative" || position === "fixed" ) {
  96. // IE returns 0 when zIndex is not specified
  97. // other browsers return a string
  98. // we ignore the case of nested elements with an explicit value of 0
  99. // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
  100. value = parseInt( elem.css( "zIndex" ), 10 );
  101. if ( !isNaN( value ) && value !== 0 ) {
  102. return value;
  103. }
  104. }
  105. elem = elem.parent();
  106. }
  107. }
  108. return 0;
  109. },
  110. disableSelection: function() {
  111. return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
  112. ".ui-disableSelection", function( event ) {
  113. event.preventDefault();
  114. });
  115. },
  116. enableSelection: function() {
  117. return this.unbind( ".ui-disableSelection" );
  118. }
  119. });
  120. $.each( [ "Width", "Height" ], function( i, name ) {
  121. var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
  122. type = name.toLowerCase(),
  123. orig = {
  124. innerWidth: $.fn.innerWidth,
  125. innerHeight: $.fn.innerHeight,
  126. outerWidth: $.fn.outerWidth,
  127. outerHeight: $.fn.outerHeight
  128. };
  129. function reduce( elem, size, border, margin ) {
  130. $.each( side, function() {
  131. size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
  132. if ( border ) {
  133. size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
  134. }
  135. if ( margin ) {
  136. size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
  137. }
  138. });
  139. return size;
  140. }
  141. $.fn[ "inner" + name ] = function( size ) {
  142. if ( size === undefined ) {
  143. return orig[ "inner" + name ].call( this );
  144. }
  145. return this.each(function() {
  146. $( this ).css( type, reduce( this, size ) + "px" );
  147. });
  148. };
  149. $.fn[ "outer" + name] = function( size, margin ) {
  150. if ( typeof size !== "number" ) {
  151. return orig[ "outer" + name ].call( this, size );
  152. }
  153. return this.each(function() {
  154. $( this).css( type, reduce( this, size, true, margin ) + "px" );
  155. });
  156. };
  157. });
  158. // selectors
  159. function visible( element ) {
  160. return !$( element ).parents().andSelf().filter(function() {
  161. return $.curCSS( this, "visibility" ) === "hidden" ||
  162. $.expr.filters.hidden( this );
  163. }).length;
  164. }
  165. $.extend( $.expr[ ":" ], {
  166. data: function( elem, i, match ) {
  167. return !!$.data( elem, match[ 3 ] );
  168. },
  169. focusable: function( element ) {
  170. var nodeName = element.nodeName.toLowerCase(),
  171. tabIndex = $.attr( element, "tabindex" );
  172. if ( "area" === nodeName ) {
  173. var map = element.parentNode,
  174. mapName = map.name,
  175. img;
  176. if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
  177. return false;
  178. }
  179. img = $( "img[usemap=#" + mapName + "]" )[0];
  180. return !!img && visible( img );
  181. }
  182. return ( /input|select|textarea|button|object/.test( nodeName )
  183. ? !element.disabled
  184. : "a" == nodeName
  185. ? element.href || !isNaN( tabIndex )
  186. : !isNaN( tabIndex ))
  187. // the element and all of its ancestors must be visible
  188. && visible( element );
  189. },
  190. tabbable: function( element ) {
  191. var tabIndex = $.attr( element, "tabindex" );
  192. return ( isNaN( tabIndex ) || tabIndex >= 0 ) && $( element ).is( ":focusable" );
  193. }
  194. });
  195. // support
  196. $(function() {
  197. var body = document.body,
  198. div = body.appendChild( div = document.createElement( "div" ) );
  199. $.extend( div.style, {
  200. minHeight: "100px",
  201. height: "auto",
  202. padding: 0,
  203. borderWidth: 0
  204. });
  205. $.support.minHeight = div.offsetHeight === 100;
  206. $.support.selectstart = "onselectstart" in div;
  207. // set display to none to avoid a layout bug in IE
  208. // http://dev.jquery.com/ticket/4014
  209. body.removeChild( div ).style.display = "none";
  210. });
  211. // deprecated
  212. $.extend( $.ui, {
  213. // $.ui.plugin is deprecated. Use the proxy pattern instead.
  214. plugin: {
  215. add: function( module, option, set ) {
  216. var proto = $.ui[ module ].prototype;
  217. for ( var i in set ) {
  218. proto.plugins[ i ] = proto.plugins[ i ] || [];
  219. proto.plugins[ i ].push( [ option, set[ i ] ] );
  220. }
  221. },
  222. call: function( instance, name, args ) {
  223. var set = instance.plugins[ name ];
  224. if ( !set || !instance.element[ 0 ].parentNode ) {
  225. return;
  226. }
  227. for ( var i = 0; i < set.length; i++ ) {
  228. if ( instance.options[ set[ i ][ 0 ] ] ) {
  229. set[ i ][ 1 ].apply( instance.element, args );
  230. }
  231. }
  232. }
  233. },
  234. // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
  235. contains: function( a, b ) {
  236. return document.compareDocumentPosition ?
  237. a.compareDocumentPosition( b ) & 16 :
  238. a !== b && a.contains( b );
  239. },
  240. // only used by resizable
  241. hasScroll: function( el, a ) {
  242. //If overflow is hidden, the element might have extra content, but the user wants to hide it
  243. if ( $( el ).css( "overflow" ) === "hidden") {
  244. return false;
  245. }
  246. var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
  247. has = false;
  248. if ( el[ scroll ] > 0 ) {
  249. return true;
  250. }
  251. // TODO: determine which cases actually cause this to happen
  252. // if the element doesn't have the scroll set, see if it's possible to
  253. // set the scroll
  254. el[ scroll ] = 1;
  255. has = ( el[ scroll ] > 0 );
  256. el[ scroll ] = 0;
  257. return has;
  258. },
  259. // these are odd functions, fix the API or move into individual plugins
  260. isOverAxis: function( x, reference, size ) {
  261. //Determines when x coordinate is over "b" element axis
  262. return ( x > reference ) && ( x < ( reference + size ) );
  263. },
  264. isOver: function( y, x, top, left, height, width ) {
  265. //Determines when x, y coordinates is over "b" element
  266. return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
  267. }
  268. });
  269. })( jQuery );
  270. /*!
  271. * jQuery UI Widget 1.8.7
  272. *
  273. * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  274. * Dual licensed under the MIT or GPL Version 2 licenses.
  275. * http://jquery.org/license
  276. *
  277. * http://docs.jquery.com/UI/Widget
  278. */
  279. (function( $, undefined ) {
  280. // jQuery 1.4+
  281. if ( $.cleanData ) {
  282. var _cleanData = $.cleanData;
  283. $.cleanData = function( elems ) {
  284. for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
  285. $( elem ).triggerHandler( "remove" );
  286. }
  287. _cleanData( elems );
  288. };
  289. } else {
  290. var _remove = $.fn.remove;
  291. $.fn.remove = function( selector, keepData ) {
  292. return this.each(function() {
  293. if ( !keepData ) {
  294. if ( !selector || $.filter( selector, [ this ] ).length ) {
  295. $( "*", this ).add( [ this ] ).each(function() {
  296. $( this ).triggerHandler( "remove" );
  297. });
  298. }
  299. }
  300. return _remove.call( $(this), selector, keepData );
  301. });
  302. };
  303. }
  304. $.widget = function( name, base, prototype ) {
  305. var namespace = name.split( "." )[ 0 ],
  306. fullName;
  307. name = name.split( "." )[ 1 ];
  308. fullName = namespace + "-" + name;
  309. if ( !prototype ) {
  310. prototype = base;
  311. base = $.Widget;
  312. }
  313. // create selector for plugin
  314. $.expr[ ":" ][ fullName ] = function( elem ) {
  315. return !!$.data( elem, name );
  316. };
  317. $[ namespace ] = $[ namespace ] || {};
  318. $[ namespace ][ name ] = function( options, element ) {
  319. // allow instantiation without initializing for simple inheritance
  320. if ( arguments.length ) {
  321. this._createWidget( options, element );
  322. }
  323. };
  324. var basePrototype = new base();
  325. // we need to make the options hash a property directly on the new instance
  326. // otherwise we'll modify the options hash on the prototype that we're
  327. // inheriting from
  328. // $.each( basePrototype, function( key, val ) {
  329. // if ( $.isPlainObject(val) ) {
  330. // basePrototype[ key ] = $.extend( {}, val );
  331. // }
  332. // });
  333. basePrototype.options = $.extend( true, {}, basePrototype.options );
  334. $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
  335. namespace: namespace,
  336. widgetName: name,
  337. widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
  338. widgetBaseClass: fullName
  339. }, prototype );
  340. $.widget.bridge( name, $[ namespace ][ name ] );
  341. };
  342. $.widget.bridge = function( name, object ) {
  343. $.fn[ name ] = function( options ) {
  344. var isMethodCall = typeof options === "string",
  345. args = Array.prototype.slice.call( arguments, 1 ),
  346. returnValue = this;
  347. // allow multiple hashes to be passed on init
  348. options = !isMethodCall && args.length ?
  349. $.extend.apply( null, [ true, options ].concat(args) ) :
  350. options;
  351. // prevent calls to internal methods
  352. if ( isMethodCall && options.charAt( 0 ) === "_" ) {
  353. return returnValue;
  354. }
  355. if ( isMethodCall ) {
  356. this.each(function() {
  357. var instance = $.data( this, name ),
  358. methodValue = instance && $.isFunction( instance[options] ) ?
  359. instance[ options ].apply( instance, args ) :
  360. instance;
  361. // TODO: add this back in 1.9 and use $.error() (see #5972)
  362. // if ( !instance ) {
  363. // throw "cannot call methods on " + name + " prior to initialization; " +
  364. // "attempted to call method '" + options + "'";
  365. // }
  366. // if ( !$.isFunction( instance[options] ) ) {
  367. // throw "no such method '" + options + "' for " + name + " widget instance";
  368. // }
  369. // var methodValue = instance[ options ].apply( instance, args );
  370. if ( methodValue !== instance && methodValue !== undefined ) {
  371. returnValue = methodValue;
  372. return false;
  373. }
  374. });
  375. } else {
  376. this.each(function() {
  377. var instance = $.data( this, name );
  378. if ( instance ) {
  379. instance.option( options || {} )._init();
  380. } else {
  381. $.data( this, name, new object( options, this ) );
  382. }
  383. });
  384. }
  385. return returnValue;
  386. };
  387. };
  388. $.Widget = function( options, element ) {
  389. // allow instantiation without initializing for simple inheritance
  390. if ( arguments.length ) {
  391. this._createWidget( options, element );
  392. }
  393. };
  394. $.Widget.prototype = {
  395. widgetName: "widget",
  396. widgetEventPrefix: "",
  397. options: {
  398. disabled: false
  399. },
  400. _createWidget: function( options, element ) {
  401. // $.widget.bridge stores the plugin instance, but we do it anyway
  402. // so that it's stored even before the _create function runs
  403. $.data( element, this.widgetName, this );
  404. this.element = $( element );
  405. this.options = $.extend( true, {},
  406. this.options,
  407. this._getCreateOptions(),
  408. options );
  409. var self = this;
  410. this.element.bind( "remove." + this.widgetName, function() {
  411. self.destroy();
  412. });
  413. this._create();
  414. this._trigger( "create" );
  415. this._init();
  416. },
  417. _getCreateOptions: function() {
  418. return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
  419. },
  420. _create: function() {},
  421. _init: function() {},
  422. destroy: function() {
  423. this.element
  424. .unbind( "." + this.widgetName )
  425. .removeData( this.widgetName );
  426. this.widget()
  427. .unbind( "." + this.widgetName )
  428. .removeAttr( "aria-disabled" )
  429. .removeClass(
  430. this.widgetBaseClass + "-disabled " +
  431. "ui-state-disabled" );
  432. },
  433. widget: function() {
  434. return this.element;
  435. },
  436. option: function( key, value ) {
  437. var options = key;
  438. if ( arguments.length === 0 ) {
  439. // don't return a reference to the internal hash
  440. return $.extend( {}, this.options );
  441. }
  442. if (typeof key === "string" ) {
  443. if ( value === undefined ) {
  444. return this.options[ key ];
  445. }
  446. options = {};
  447. options[ key ] = value;
  448. }
  449. this._setOptions( options );
  450. return this;
  451. },
  452. _setOptions: function( options ) {
  453. var self = this;
  454. $.each( options, function( key, value ) {
  455. self._setOption( key, value );
  456. });
  457. return this;
  458. },
  459. _setOption: function( key, value ) {
  460. this.options[ key ] = value;
  461. if ( key === "disabled" ) {
  462. this.widget()
  463. [ value ? "addClass" : "removeClass"](
  464. this.widgetBaseClass + "-disabled" + " " +
  465. "ui-state-disabled" )
  466. .attr( "aria-disabled", value );
  467. }
  468. return this;
  469. },
  470. enable: function() {
  471. return this._setOption( "disabled", false );
  472. },
  473. disable: function() {
  474. return this._setOption( "disabled", true );
  475. },
  476. _trigger: function( type, event, data ) {
  477. var callback = this.options[ type ];
  478. event = $.Event( event );
  479. event.type = ( type === this.widgetEventPrefix ?
  480. type :
  481. this.widgetEventPrefix + type ).toLowerCase();
  482. data = data || {};
  483. // copy original event properties over to the new event
  484. // this would happen if we could call $.event.fix instead of $.Event
  485. // but we don't have a way to force an event to be fixed multiple times
  486. if ( event.originalEvent ) {
  487. for ( var i = $.event.props.length, prop; i; ) {
  488. prop = $.event.props[ --i ];
  489. event[ prop ] = event.originalEvent[ prop ];
  490. }
  491. }
  492. this.element.trigger( event, data );
  493. return !( $.isFunction(callback) &&
  494. callback.call( this.element[0], event, data ) === false ||
  495. event.isDefaultPrevented() );
  496. }
  497. };
  498. })( jQuery );
  499. /*!
  500. * jQuery UI Mouse 1.8.7
  501. *
  502. * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  503. * Dual licensed under the MIT or GPL Version 2 licenses.
  504. * http://jquery.org/license
  505. *
  506. * http://docs.jquery.com/UI/Mouse
  507. *
  508. * Depends:
  509. * jquery.ui.widget.js
  510. */
  511. (function( $, undefined ) {
  512. $.widget("ui.mouse", {
  513. options: {
  514. cancel: ':input,option',
  515. distance: 1,
  516. delay: 0
  517. },
  518. _mouseInit: function() {
  519. var self = this;
  520. this.element
  521. .bind('mousedown.'+this.widgetName, function(event) {
  522. return self._mouseDown(event);
  523. })
  524. .bind('click.'+this.widgetName, function(event) {
  525. if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
  526. $.removeData(event.target, self.widgetName + '.preventClickEvent');
  527. event.stopImmediatePropagation();
  528. return false;
  529. }
  530. });
  531. this.started = false;
  532. },
  533. // TODO: make sure destroying one instance of mouse doesn't mess with
  534. // other instances of mouse
  535. _mouseDestroy: function() {
  536. this.element.unbind('.'+this.widgetName);
  537. },
  538. _mouseDown: function(event) {
  539. // don't let more than one widget handle mouseStart
  540. // TODO: figure out why we have to use originalEvent
  541. event.originalEvent = event.originalEvent || {};
  542. if (event.originalEvent.mouseHandled) { return; }
  543. // we may have missed mouseup (out of window)
  544. (this._mouseStarted && this._mouseUp(event));
  545. this._mouseDownEvent = event;
  546. var self = this,
  547. btnIsLeft = (event.which == 1),
  548. elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
  549. if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
  550. return true;
  551. }
  552. this.mouseDelayMet = !this.options.delay;
  553. if (!this.mouseDelayMet) {
  554. this._mouseDelayTimer = setTimeout(function() {
  555. self.mouseDelayMet = true;
  556. }, this.options.delay);
  557. }
  558. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  559. this._mouseStarted = (this._mouseStart(event) !== false);
  560. if (!this._mouseStarted) {
  561. event.preventDefault();
  562. return true;
  563. }
  564. }
  565. // these delegates are required to keep context
  566. this._mouseMoveDelegate = function(event) {
  567. return self._mouseMove(event);
  568. };
  569. this._mouseUpDelegate = function(event) {
  570. return self._mouseUp(event);
  571. };
  572. $(document)
  573. .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
  574. .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  575. event.preventDefault();
  576. event.originalEvent.mouseHandled = true;
  577. return true;
  578. },
  579. _mouseMove: function(event) {
  580. // IE mouseup check - mouseup happened when mouse was out of window
  581. if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
  582. return this._mouseUp(event);
  583. }
  584. if (this._mouseStarted) {
  585. this._mouseDrag(event);
  586. return event.preventDefault();
  587. }
  588. if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  589. this._mouseStarted =
  590. (this._mouseStart(this._mouseDownEvent, event) !== false);
  591. (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
  592. }
  593. return !this._mouseStarted;
  594. },
  595. _mouseUp: function(event) {
  596. $(document)
  597. .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
  598. .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  599. if (this._mouseStarted) {
  600. this._mouseStarted = false;
  601. if (event.target == this._mouseDownEvent.target) {
  602. $.data(event.target, this.widgetName + '.preventClickEvent', true);
  603. }
  604. this._mouseStop(event);
  605. }
  606. return false;
  607. },
  608. _mouseDistanceMet: function(event) {
  609. return (Math.max(
  610. Math.abs(this._mouseDownEvent.pageX - event.pageX),
  611. Math.abs(this._mouseDownEvent.pageY - event.pageY)
  612. ) >= this.options.distance
  613. );
  614. },
  615. _mouseDelayMet: function(event) {
  616. return this.mouseDelayMet;
  617. },
  618. // These are placeholder methods, to be overriden by extending plugin
  619. _mouseStart: function(event) {},
  620. _mouseDrag: function(event) {},
  621. _mouseStop: function(event) {},
  622. _mouseCapture: function(event) { return true; }
  623. });
  624. })(jQuery);
  625. /*
  626. * jQuery UI Position 1.8.7
  627. *
  628. * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  629. * Dual licensed under the MIT or GPL Version 2 licenses.
  630. * http://jquery.org/license
  631. *
  632. * http://docs.jquery.com/UI/Position
  633. */
  634. (function( $, undefined ) {
  635. $.ui = $.ui || {};
  636. var horizontalPositions = /left|center|right/,
  637. verticalPositions = /top|center|bottom/,
  638. center = "center",
  639. _position = $.fn.position,
  640. _offset = $.fn.offset;
  641. $.fn.position = function( options ) {
  642. if ( !options || !options.of ) {
  643. return _position.apply( this, arguments );
  644. }
  645. // make a copy, we don't want to modify arguments
  646. options = $.extend( {}, options );
  647. var target = $( options.of ),
  648. targetElem = target[0],
  649. collision = ( options.collision || "flip" ).split( " " ),
  650. offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
  651. targetWidth,
  652. targetHeight,
  653. basePosition;
  654. if ( targetElem.nodeType === 9 ) {
  655. targetWidth = target.width();
  656. targetHeight = target.height();
  657. basePosition = { top: 0, left: 0 };
  658. // TODO: use $.isWindow() in 1.9
  659. } else if ( targetElem.setTimeout ) {
  660. targetWidth = target.width();
  661. targetHeight = target.height();
  662. basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
  663. } else if ( targetElem.preventDefault ) {
  664. // force left top to allow flipping
  665. options.at = "left top";
  666. targetWidth = targetHeight = 0;
  667. basePosition = { top: options.of.pageY, left: options.of.pageX };
  668. } else {
  669. targetWidth = target.outerWidth();
  670. targetHeight = target.outerHeight();
  671. basePosition = target.offset();
  672. }
  673. // force my and at to have valid horizontal and veritcal positions
  674. // if a value is missing or invalid, it will be converted to center
  675. $.each( [ "my", "at" ], function() {
  676. var pos = ( options[this] || "" ).split( " " );
  677. if ( pos.length === 1) {
  678. pos = horizontalPositions.test( pos[0] ) ?
  679. pos.concat( [center] ) :
  680. verticalPositions.test( pos[0] ) ?
  681. [ center ].concat( pos ) :
  682. [ center, center ];
  683. }
  684. pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
  685. pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
  686. options[ this ] = pos;
  687. });
  688. // normalize collision option
  689. if ( collision.length === 1 ) {
  690. collision[ 1 ] = collision[ 0 ];
  691. }
  692. // normalize offset option
  693. offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
  694. if ( offset.length === 1 ) {
  695. offset[ 1 ] = offset[ 0 ];
  696. }
  697. offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
  698. if ( options.at[0] === "right" ) {
  699. basePosition.left += targetWidth;
  700. } else if (options.at[0] === center ) {
  701. basePosition.left += targetWidth / 2;
  702. }
  703. if ( options.at[1] === "bottom" ) {
  704. basePosition.top += targetHeight;
  705. } else if ( options.at[1] === center ) {
  706. basePosition.top += targetHeight / 2;
  707. }
  708. basePosition.left += offset[ 0 ];
  709. basePosition.top += offset[ 1 ];
  710. return this.each(function() {
  711. var elem = $( this ),
  712. elemWidth = elem.outerWidth(),
  713. elemHeight = elem.outerHeight(),
  714. marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
  715. marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
  716. collisionWidth = elemWidth + marginLeft +
  717. parseInt( $.curCSS( this, "marginRight", true ) ) || 0,
  718. collisionHeight = elemHeight + marginTop +
  719. parseInt( $.curCSS( this, "marginBottom", true ) ) || 0,
  720. position = $.extend( {}, basePosition ),
  721. collisionPosition;
  722. if ( options.my[0] === "right" ) {
  723. position.left -= elemWidth;
  724. } else if ( options.my[0] === center ) {
  725. position.left -= elemWidth / 2;
  726. }
  727. if ( options.my[1] === "bottom" ) {
  728. position.top -= elemHeight;
  729. } else if ( options.my[1] === center ) {
  730. position.top -= elemHeight / 2;
  731. }
  732. // prevent fractions (see #5280)
  733. position.left = Math.round( position.left );
  734. position.top = Math.round( position.top );
  735. collisionPosition = {
  736. left: position.left - marginLeft,
  737. top: position.top - marginTop
  738. };
  739. $.each( [ "left", "top" ], function( i, dir ) {
  740. if ( $.ui.position[ collision[i] ] ) {
  741. $.ui.position[ collision[i] ][ dir ]( position, {
  742. targetWidth: targetWidth,
  743. targetHeight: targetHeight,
  744. elemWidth: elemWidth,
  745. elemHeight: elemHeight,
  746. collisionPosition: collisionPosition,
  747. collisionWidth: collisionWidth,
  748. collisionHeight: collisionHeight,
  749. offset: offset,
  750. my: options.my,
  751. at: options.at
  752. });
  753. }
  754. });
  755. if ( $.fn.bgiframe ) {
  756. elem.bgiframe();
  757. }
  758. elem.offset( $.extend( position, { using: options.using } ) );
  759. });
  760. };
  761. $.ui.position = {
  762. fit: {
  763. left: function( position, data ) {
  764. var win = $( window ),
  765. over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
  766. position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
  767. },
  768. top: function( position, data ) {
  769. var win = $( window ),
  770. over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
  771. position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
  772. }
  773. },
  774. flip: {
  775. left: function( position, data ) {
  776. if ( data.at[0] === center ) {
  777. return;
  778. }
  779. var win = $( window ),
  780. over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
  781. myOffset = data.my[ 0 ] === "left" ?
  782. -data.elemWidth :
  783. data.my[ 0 ] === "right" ?
  784. data.elemWidth :
  785. 0,
  786. atOffset = data.at[ 0 ] === "left" ?
  787. data.targetWidth :
  788. -data.targetWidth,
  789. offset = -2 * data.offset[ 0 ];
  790. position.left += data.collisionPosition.left < 0 ?
  791. myOffset + atOffset + offset :
  792. over > 0 ?
  793. myOffset + atOffset + offset :
  794. 0;
  795. },
  796. top: function( position, data ) {
  797. if ( data.at[1] === center ) {
  798. return;
  799. }
  800. var win = $( window ),
  801. over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
  802. myOffset = data.my[ 1 ] === "top" ?
  803. -data.elemHeight :
  804. data.my[ 1 ] === "bottom" ?
  805. data.elemHeight :
  806. 0,
  807. atOffset = data.at[ 1 ] === "top" ?
  808. data.targetHeight :
  809. -data.targetHeight,
  810. offset = -2 * data.offset[ 1 ];
  811. position.top += data.collisionPosition.top < 0 ?
  812. myOffset + atOffset + offset :
  813. over > 0 ?
  814. myOffset + atOffset + offset :
  815. 0;
  816. }
  817. }
  818. };
  819. // offset setter from jQuery 1.4
  820. if ( !$.offset.setOffset ) {
  821. $.offset.setOffset = function( elem, options ) {
  822. // set position first, in-case top/left are set even on static elem
  823. if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
  824. elem.style.position = "relative";
  825. }
  826. var curElem = $( elem ),
  827. curOffset = curElem.offset(),
  828. curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
  829. curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
  830. props = {
  831. top: (options.top - curOffset.top) + curTop,
  832. left: (options.left - curOffset.left) + curLeft
  833. };
  834. if ( 'using' in options ) {
  835. options.using.call( elem, props );
  836. } else {
  837. curElem.css( props );
  838. }
  839. };
  840. $.fn.offset = function( options ) {
  841. var elem = this[ 0 ];
  842. if ( !elem || !elem.ownerDocument ) { return null; }
  843. if ( options ) {
  844. return this.each(function() {
  845. $.offset.setOffset( this, options );
  846. });
  847. }
  848. return _offset.call( this );
  849. };
  850. }
  851. }( jQuery ));
  852. /*
  853. * jQuery UI Draggable 1.8.7
  854. *
  855. * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  856. * Dual licensed under the MIT or GPL Version 2 licenses.
  857. * http://jquery.org/license
  858. *
  859. * http://docs.jquery.com/UI/Draggables
  860. *
  861. * Depends:
  862. * jquery.ui.core.js
  863. * jquery.ui.mouse.js
  864. * jquery.ui.widget.js
  865. */
  866. (function( $, undefined ) {
  867. $.widget("ui.draggable", $.ui.mouse, {
  868. widgetEventPrefix: "drag",
  869. options: {
  870. addClasses: true,
  871. appendTo: "parent",
  872. axis: false,
  873. connectToSortable: false,
  874. containment: false,
  875. cursor: "auto",
  876. cursorAt: false,
  877. grid: false,
  878. handle: false,
  879. helper: "original",
  880. iframeFix: false,
  881. opacity: false,
  882. refreshPositions: false,
  883. revert: false,
  884. revertDuration: 500,
  885. scope: "default",
  886. scroll: true,
  887. scrollSensitivity: 20,
  888. scrollSpeed: 20,
  889. snap: false,
  890. snapMode: "both",
  891. snapTolerance: 20,
  892. stack: false,
  893. zIndex: false
  894. },
  895. _create: function() {
  896. if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
  897. this.element[0].style.position = 'relative';
  898. (this.options.addClasses && this.element.addClass("ui-draggable"));
  899. (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
  900. this._mouseInit();
  901. },
  902. destroy: function() {
  903. if(!this.element.data('draggable')) return;
  904. this.element
  905. .removeData("draggable")
  906. .unbind(".draggable")
  907. .removeClass("ui-draggable"
  908. + " ui-draggable-dragging"
  909. + " ui-draggable-disabled");
  910. this._mouseDestroy();
  911. return this;
  912. },
  913. _mouseCapture: function(event) {
  914. var o = this.options;
  915. // among others, prevent a drag on a resizable-handle
  916. if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
  917. return false;
  918. //Quit if we're not on a valid handle
  919. this.handle = this._getHandle(event);
  920. if (!this.handle)
  921. return false;
  922. return true;
  923. },
  924. _mouseStart: function(event) {
  925. var o = this.options;
  926. //Create and append the visible helper
  927. this.helper = this._createHelper(event);
  928. //Cache the helper size
  929. this._cacheHelperProportions();
  930. //If ddmanager is used for droppables, set the global draggable
  931. if($.ui.ddmanager)
  932. $.ui.ddmanager.current = this;
  933. /*
  934. * - Position generation -
  935. * This block generates everything position related - it's the core of draggables.
  936. */
  937. //Cache the margins of the original element
  938. this._cacheMargins();
  939. //Store the helper's css position
  940. this.cssPosition = this.helper.css("position");
  941. this.scrollParent = this.helper.scrollParent();
  942. //The element's absolute position on the page minus margins
  943. this.offset = this.positionAbs = this.element.offset();
  944. this.offset = {
  945. top: this.offset.top - this.margins.top,
  946. left: this.offset.left - this.margins.left
  947. };
  948. $.extend(this.offset, {
  949. click: { //Where the click happened, relative to the element
  950. left: event.pageX - this.offset.left,
  951. top: event.pageY - this.offset.top
  952. },
  953. parent: this._getParentOffset(),
  954. relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
  955. });
  956. //Generate the original position
  957. this.originalPosition = this.position = this._generatePosition(event);
  958. this.originalPageX = event.pageX;
  959. this.originalPageY = event.pageY;
  960. //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
  961. (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
  962. //Set a containment if given in the options
  963. if(o.containment)
  964. this._setContainment();
  965. //Trigger event + callbacks
  966. if(this._trigger("start", event) === false) {
  967. this._clear();
  968. return false;
  969. }
  970. //Recache the helper size
  971. this._cacheHelperProportions();
  972. //Prepare the droppable offsets
  973. if ($.ui.ddmanager && !o.dropBehaviour)
  974. $.ui.ddmanager.prepareOffsets(this, event);
  975. this.helper.addClass("ui-draggable-dragging");
  976. this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
  977. return true;
  978. },
  979. _mouseDrag: function(event, noPropagation) {
  980. //Compute the helpers position
  981. this.position = this._generatePosition(event);
  982. this.positionAbs = this._convertPositionTo("absolute");
  983. //Call plugins and callbacks and use the resulting position if something is returned
  984. if (!noPropagation) {
  985. var ui = this._uiHash();
  986. if(this._trigger('drag', event, ui) === false) {
  987. this._mouseUp({});
  988. return false;
  989. }
  990. this.position = ui.position;
  991. }
  992. if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
  993. if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
  994. if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
  995. return false;
  996. },
  997. _mouseStop: function(event) {
  998. //If we are using droppables, inform the manager about the drop
  999. var dropped = false;
  1000. if ($.ui.ddmanager && !this.options.dropBehaviour)
  1001. dropped = $.ui.ddmanager.drop(this, event);
  1002. //if a drop comes from outside (a sortable)
  1003. if(this.dropped) {
  1004. dropped = this.dropped;
  1005. this.dropped = false;
  1006. }
  1007. //if the original element is removed, don't bother to continue
  1008. if(!this.element[0] || !this.element[0].parentNode)
  1009. return false;
  1010. if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
  1011. var self = this;
  1012. $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
  1013. if(self._trigger("stop", event) !== false) {
  1014. self._clear();
  1015. }
  1016. });
  1017. } else {
  1018. if(this._trigger("stop", event) !== false) {
  1019. this._clear();
  1020. }
  1021. }
  1022. return false;
  1023. },
  1024. cancel: function() {
  1025. if(this.helper.is(".ui-draggable-dragging")) {
  1026. this._mouseUp({});
  1027. } else {
  1028. this._clear();
  1029. }
  1030. return this;
  1031. },
  1032. _getHandle: function(event) {
  1033. var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
  1034. $(this.options.handle, this.element)
  1035. .find("*")
  1036. .andSelf()
  1037. .each(function() {
  1038. if(this == event.target) handle = true;
  1039. });
  1040. return handle;
  1041. },
  1042. _createHelper: function(event) {
  1043. var o = this.options;
  1044. var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
  1045. if(!helper.parents('body').length)
  1046. helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
  1047. if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
  1048. helper.css("position", "absolute");
  1049. return helper;
  1050. },
  1051. _adjustOffsetFromHelper: function(obj) {
  1052. if (typeof obj == 'string') {
  1053. obj = obj.split(' ');
  1054. }
  1055. if ($.isArray(obj)) {
  1056. obj = {left: +obj[0], top: +obj[1] || 0};
  1057. }
  1058. if ('left' in obj) {
  1059. this.offset.click.left = obj.left + this.margins.left;
  1060. }
  1061. if ('right' in obj) {
  1062. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  1063. }
  1064. if ('top' in obj) {
  1065. this.offset.click.top = obj.top + this.margins.top;
  1066. }
  1067. if ('bottom' in obj) {
  1068. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  1069. }
  1070. },
  1071. _getParentOffset: function() {
  1072. //Get the offsetParent and cache its position
  1073. this.offsetParent = this.helper.offsetParent();
  1074. var po = this.offsetParent.offset();
  1075. // This is a special case where we need to modify a offset calculated on start, since the following happened:
  1076. // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
  1077. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
  1078. // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
  1079. if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
  1080. po.left += this.scrollParent.scrollLeft();
  1081. po.top += this.scrollParent.scrollTop();
  1082. }
  1083. if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
  1084. || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
  1085. po = { top: 0, left: 0 };
  1086. return {
  1087. top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
  1088. left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
  1089. };
  1090. },
  1091. _getRelativeOffset: function() {
  1092. if(this.cssPosition == "relative") {
  1093. var p = this.element.position();
  1094. return {
  1095. top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
  1096. left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
  1097. };
  1098. } else {
  1099. return { top: 0, left: 0 };
  1100. }
  1101. },
  1102. _cacheMargins: function() {
  1103. this.margins = {
  1104. left: (parseInt(this.element.css("marginLeft"),10) || 0),
  1105. top: (parseInt(this.element.css("marginTop"),10) || 0)
  1106. };
  1107. },
  1108. _cacheHelperProportions: function() {
  1109. this.helperProportions = {
  1110. width: this.helper.outerWidth(),
  1111. height: this.helper.outerHeight()
  1112. };
  1113. },
  1114. _setContainment: function() {
  1115. var o = this.options;
  1116. if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
  1117. if(o.containment == 'document' || o.containment == 'window') this.containment = [
  1118. (o.containment == 'document' ? 0 : $(window).scrollLeft()) - this.offset.relative.left - this.offset.parent.left,
  1119. (o.containment == 'document' ? 0 : $(window).scrollTop()) - this.offset.relative.top - this.offset.parent.top,
  1120. (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
  1121. (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
  1122. ];
  1123. if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
  1124. var ce = $(o.containment)[0]; if(!ce) return;
  1125. var co = $(o.containment).offset();
  1126. var over = ($(ce).css("overflow") != 'hidden');
  1127. this.containment = [
  1128. co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
  1129. co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
  1130. co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
  1131. co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
  1132. ];
  1133. } else if(o.containment.constructor == Array) {
  1134. this.containment = o.containment;
  1135. }
  1136. },
  1137. _convertPositionTo: function(d, pos) {
  1138. if(!pos) pos = this.position;
  1139. var mod = d == "absolute" ? 1 : -1;
  1140. var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  1141. return {
  1142. top: (
  1143. pos.top // The absolute mouse position
  1144. + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  1145. + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
  1146. - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
  1147. ),
  1148. left: (
  1149. pos.left // The absolute mouse position
  1150. + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  1151. + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
  1152. - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
  1153. )
  1154. };
  1155. },
  1156. _generatePosition: function(event) {
  1157. var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  1158. var pageX = event.pageX;
  1159. var pageY = event.pageY;
  1160. /*
  1161. * - Position constraining -
  1162. * Constrain the position to a mix of grid, containment.
  1163. */
  1164. if(this.originalPosition) { //If we are not dragging yet, we won't check for options
  1165. if(this.containment) {
  1166. if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
  1167. if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
  1168. if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
  1169. if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
  1170. }
  1171. if(o.grid) {
  1172. var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
  1173. pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
  1174. var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
  1175. pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
  1176. }
  1177. }
  1178. return {
  1179. top: (
  1180. pageY // The absolute mouse position
  1181. - this.offset.click.top // Click offset (relative to the element)
  1182. - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
  1183. - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
  1184. + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
  1185. ),
  1186. left: (
  1187. pageX // The absolute mouse position
  1188. - this.offset.click.left // Click offset (relative to the element)
  1189. - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
  1190. - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
  1191. + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
  1192. )
  1193. };
  1194. },
  1195. _clear: function() {
  1196. this.helper.removeClass("ui-draggable-dragging");
  1197. if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
  1198. //if($.ui.ddmanager) $.ui.ddmanager.current = null;
  1199. this.helper = null;
  1200. this.cancelHelperRemoval = false;
  1201. },
  1202. // From now on bulk stuff - mainly helpers
  1203. _trigger: function(type, event, ui) {
  1204. ui = ui || this._uiHash();
  1205. $.ui.plugin.call(this, type, [event, ui]);
  1206. if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
  1207. return $.Widget.prototype._trigger.call(this, type, event, ui);
  1208. },
  1209. plugins: {},
  1210. _uiHash: function(event) {
  1211. return {
  1212. helper: this.helper,
  1213. position: this.position,
  1214. originalPosition: this.originalPosition,
  1215. offset: this.positionAbs
  1216. };
  1217. }
  1218. });
  1219. $.extend($.ui.draggable, {
  1220. version: "1.8.7"
  1221. });
  1222. $.ui.plugin.add("draggable", "connectToSortable", {
  1223. start: function(event, ui) {
  1224. var inst = $(this).data("draggable"), o = inst.options,
  1225. uiSortable = $.extend({}, ui, { item: inst.element });
  1226. inst.sortables = [];
  1227. $(o.connectToSortable).each(function() {
  1228. var sortable = $.data(this, 'sortable');
  1229. if (sortable && !sortable.options.disabled) {
  1230. inst.sortables.push({
  1231. instance: sortable,
  1232. shouldRevert: sortable.options.revert
  1233. });
  1234. sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache
  1235. sortable._trigger("activate", event, uiSortable);
  1236. }
  1237. });
  1238. },
  1239. stop: function(event, ui) {
  1240. //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
  1241. var inst = $(this).data("draggable"),
  1242. uiSortable = $.extend({}, ui, { item: inst.element });
  1243. $.each(inst.sortables, function() {
  1244. if(this.instance.isOver) {
  1245. this.instance.isOver = 0;
  1246. inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
  1247. this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
  1248. //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
  1249. if(this.shouldRevert) this.instance.options.revert = true;
  1250. //Trigger the stop of the sortable
  1251. this.instance._mouseStop(event);
  1252. this.instance.options.helper = this.instance.options._helper;
  1253. //If the helper has been the original item, restore properties in the sortable
  1254. if(inst.options.helper == 'original')
  1255. this.instance.currentItem.css({ top: 'auto', left: 'auto' });
  1256. } else {
  1257. this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
  1258. this.instance._trigger("deactivate", event, uiSortable);
  1259. }
  1260. });
  1261. },
  1262. drag: function(event, ui) {
  1263. var inst = $(this).data("draggable"), self = this;
  1264. var checkPos = function(o) {
  1265. var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
  1266. var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
  1267. var itemHeight = o.height, itemWidth = o.width;
  1268. var itemTop = o.top, itemLeft = o.left;
  1269. return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
  1270. };
  1271. $.each(inst.sortables, function(i) {
  1272. //Copy over some variables to allow calling the sortable's native _intersectsWith
  1273. this.instance.positionAbs = inst.positionAbs;
  1274. this.instance.helperProportions = inst.helperProportions;
  1275. this.instance.offset.click = inst.offset.click;
  1276. if(this.instance._intersectsWith(this.instance.containerCache)) {
  1277. //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
  1278. if(!this.instance.isOver) {
  1279. this.instance.isOver = 1;
  1280. //Now we fake the start of dragging for the sortable instance,
  1281. //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
  1282. //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
  1283. this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
  1284. this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
  1285. this.instance.options.helper = function() { return ui.helper[0]; };
  1286. event.target = this.instance.currentItem[0];
  1287. this.instance._mouseCapture(event, true);
  1288. this.instance._mouseStart(event, true, true);
  1289. //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
  1290. this.instance.offset.click.top = inst.offset.click.top;
  1291. this.instance.offset.click.left = inst.offset.click.left;
  1292. this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
  1293. this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
  1294. inst._trigger("toSortable", event);
  1295. inst.dropped = this.instance.element; //draggable revert needs that
  1296. //hack so receive/update callbacks work (mostly)
  1297. inst.currentItem = inst.element;
  1298. this.instance.fromOutside = inst;
  1299. }
  1300. //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
  1301. if(this.instance.currentItem) this.instance._mouseDrag(event);
  1302. } else {
  1303. //If it doesn't intersect with the sortable, and it intersected before,
  1304. //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
  1305. if(this.instance.isOver) {
  1306. this.instance.isOver = 0;
  1307. this.instance.cancelHelperRemoval = true;
  1308. //Prevent reverting on this forced stop
  1309. this.instance.options.revert = false;
  1310. // The out event needs to be triggered independently
  1311. this.instance._trigger('out', event, this.instance._uiHash(this.instance));
  1312. this.instance._mouseStop(event, true);
  1313. this.instance.options.helper = this.instance.options._helper;
  1314. //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
  1315. this.instance.currentItem.remove();
  1316. if(this.instance.placeholder) this.instance.placeholder.remove();
  1317. inst._trigger("fromSortable", event);
  1318. inst.dropped = false; //draggable revert needs that
  1319. }
  1320. };
  1321. });
  1322. }
  1323. });
  1324. $.ui.plugin.add("draggable", "cursor", {
  1325. start: function(event, ui) {
  1326. var t = $('body'), o = $(this).data('draggable').options;
  1327. if (t.css("cursor")) o._cursor = t.css("cursor");
  1328. t.css("cursor", o.cursor);
  1329. },
  1330. stop: function(event, ui) {
  1331. var o = $(this).data('draggable').options;
  1332. if (o._cursor) $('body').css("cursor", o._cursor);
  1333. }
  1334. });
  1335. $.ui.plugin.add("draggable", "iframeFix", {
  1336. start: function(event, ui) {
  1337. var o = $(this).data('draggable').options;
  1338. $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
  1339. $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
  1340. .css({
  1341. width: this.offsetWidth+"px", height: this.offsetHeight+"px",
  1342. position: "absolute", opacity: "0.001", zIndex: 1000
  1343. })
  1344. .css($(this).offset())
  1345. .appendTo("body");
  1346. });
  1347. },
  1348. stop: function(event, ui) {
  1349. $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
  1350. }
  1351. });
  1352. $.ui.plugin.add("draggable", "opacity", {
  1353. start: function(event, ui) {
  1354. var t = $(ui.helper), o = $(this).data('draggable').options;
  1355. if(t.css("opacity")) o._opacity = t.css("opacity");
  1356. t.css('opacity', o.opacity);
  1357. },
  1358. stop: function(event, ui) {
  1359. var o = $(this).data('draggable').options;
  1360. if(o._opacity) $(ui.helper).css('opacity', o._opacity);
  1361. }
  1362. });
  1363. $.ui.plugin.add("draggable", "scroll", {
  1364. start: function(event, ui) {
  1365. var i = $(this).data("draggable");
  1366. if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
  1367. },
  1368. drag: function(event, ui) {
  1369. var i = $(this).data("draggable"), o = i.options, scrolled = false;
  1370. if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
  1371. if(!o.axis || o.axis != 'x') {
  1372. if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
  1373. i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
  1374. else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
  1375. i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
  1376. }
  1377. if(!o.axis || o.axis != 'y') {
  1378. if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
  1379. i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
  1380. else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
  1381. i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
  1382. }
  1383. } else {
  1384. if(!o.axis || o.axis != 'x') {
  1385. if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
  1386. scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  1387. else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
  1388. scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  1389. }
  1390. if(!o.axis || o.axis != 'y') {
  1391. if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
  1392. scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  1393. else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
  1394. scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  1395. }
  1396. }
  1397. if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
  1398. $.ui.ddmanager.prepareOffsets(i, event);
  1399. }
  1400. });
  1401. $.ui.plugin.add("draggable", "snap", {
  1402. start: function(event, ui) {
  1403. var i = $(this).data("draggable"), o = i.options;
  1404. i.snapElements = [];
  1405. $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
  1406. var $t = $(this); var $o = $t.offset();
  1407. if(this != i.element[0]) i.snapElements.push({
  1408. item: this,
  1409. width: $t.outerWidth(), height: $t.outerHeight(),
  1410. top: $o.top, left: $o.left
  1411. });
  1412. });
  1413. },
  1414. drag: function(event, ui) {
  1415. var inst = $(this).data("draggable"), o = inst.options;
  1416. var d = o.snapTolerance;
  1417. var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
  1418. y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
  1419. for (var i = inst.snapElements.length - 1; i >= 0; i--){
  1420. var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
  1421. t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
  1422. //Yes, I know, this is insane ;)
  1423. if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
  1424. if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
  1425. inst.snapElements[i].snapping = false;
  1426. continue;
  1427. }
  1428. if(o.snapMode != 'inner') {
  1429. var ts = Math.abs(t - y2) <= d;
  1430. var bs = Math.abs(b - y1) <= d;
  1431. var ls = Math.abs(l - x2) <= d;
  1432. var rs = Math.abs(r - x1) <= d;
  1433. if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  1434. if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
  1435. if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
  1436. if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
  1437. }
  1438. var first = (ts || bs || ls || rs);
  1439. if(o.snapMode != 'outer') {
  1440. var ts = Math.abs(t - y1) <= d;
  1441. var bs = Math.abs(b - y2) <= d;
  1442. var ls = Math.abs(l - x1) <= d;
  1443. var rs = Math.abs(r - x2) <= d;
  1444. if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
  1445. if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  1446. if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
  1447. if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
  1448. }
  1449. if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
  1450. (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
  1451. inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
  1452. };
  1453. }
  1454. });
  1455. $.ui.plugin.add("draggable", "stack", {
  1456. start: function(event, ui) {
  1457. var o = $(this).data("draggable").options;
  1458. var group = $.makeArray($(o.stack)).sort(function(a,b) {
  1459. return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
  1460. });
  1461. if (!group.length) { return; }
  1462. var min = parseInt(group[0].style.zIndex) || 0;
  1463. $(group).each(function(i) {
  1464. this.style.zIndex = min + i;
  1465. });
  1466. this[0].style.zIndex = min + group.length;
  1467. }
  1468. });
  1469. $.ui.plugin.add("draggable", "zIndex", {
  1470. start: function(event, ui) {
  1471. var t = $(ui.helper), o = $(this).data("draggable").options;
  1472. if(t.css("zIndex")) o._zIndex = t.css("zIndex");
  1473. t.css('zIndex', o.zIndex);
  1474. },
  1475. stop: function(event, ui) {
  1476. var o = $(this).data("draggable").options;
  1477. if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
  1478. }
  1479. });
  1480. })(jQuery);
  1481. /*
  1482. * jQuery UI Droppable 1.8.7
  1483. *
  1484. * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  1485. * Dual licensed under the MIT or GPL Version 2 licenses.
  1486. * http://jquery.org/license
  1487. *
  1488. * http://docs.jquery.com/UI/Droppables
  1489. *
  1490. * Depends:
  1491. * jquery.ui.core.js
  1492. * jquery.ui.widget.js
  1493. * jquery.ui.mouse.js
  1494. * jquery.ui.draggable.js
  1495. */
  1496. (function( $, undefined ) {
  1497. $.widget("ui.droppable", {
  1498. widgetEventPrefix: "drop",
  1499. options: {
  1500. accept: '*',
  1501. activeClass: false,
  1502. addClasses: true,
  1503. greedy: false,
  1504. hoverClass: false,
  1505. scope: 'default',
  1506. tolerance: 'intersect'
  1507. },
  1508. _create: function() {
  1509. var o = this.options, accept = o.accept;
  1510. this.isover = 0; this.isout = 1;
  1511. this.accept = $.isFunction(accept) ? accept : function(d) {
  1512. return d.is(accept);
  1513. };
  1514. //Store the droppable's proportions
  1515. this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
  1516. // Add the reference and positions to the manager
  1517. $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
  1518. $.ui.ddmanager.droppables[o.scope].push(this);
  1519. (o.addClasses && this.element.addClass("ui-droppable"));
  1520. },
  1521. destroy: function() {
  1522. var drop = $.ui.ddmanager.droppables[this.options.scope];
  1523. for ( var i = 0; i < drop.length; i++ )
  1524. if ( drop[i] == this )
  1525. drop.splice(i, 1);
  1526. this.element
  1527. .removeClass("ui-droppable ui-droppable-disabled")
  1528. .removeData("droppable")
  1529. .unbind(".droppable");
  1530. return this;
  1531. },
  1532. _setOption: function(key, value) {
  1533. if(key == 'accept') {
  1534. this.accept = $.isFunction(value) ? value : function(d) {
  1535. return d.is(value);
  1536. };
  1537. }
  1538. $.Widget.prototype._setOption.apply(this, arguments);
  1539. },
  1540. _activate: function(event) {
  1541. var draggable = $.ui.ddmanager.current;
  1542. if(this.options.activeClass) this.element.addClass(this.options.activeClass);
  1543. (draggable && this._trigger('activate', event, this.ui(draggable)));
  1544. },
  1545. _deactivate: function(event) {
  1546. var draggable = $.ui.ddmanager.current;
  1547. if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
  1548. (draggable && this._trigger('deactivate', event, this.ui(draggable)));
  1549. },
  1550. _over: function(event) {
  1551. var draggable = $.ui.ddmanager.current;
  1552. if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  1553. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  1554. if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
  1555. this._trigger('over', event, this.ui(draggable));
  1556. }
  1557. },
  1558. _out: function(event) {
  1559. var draggable = $.ui.ddmanager.current;
  1560. if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  1561. if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  1562. if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
  1563. this._trigger('out', event, this.ui(draggable));
  1564. }
  1565. },
  1566. _drop: function(event,custom) {
  1567. var draggable = custom || $.ui.ddmanager.current;
  1568. if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
  1569. var childrenIntersection = false;
  1570. this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
  1571. var inst = $.data(this, 'droppable');
  1572. if(
  1573. inst.options.greedy
  1574. && !inst.options.disabled
  1575. && inst.options.scope == draggable.options.scope
  1576. && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
  1577. && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
  1578. ) { childrenIntersection = true; return false; }
  1579. });
  1580. if(childrenIntersection) return false;
  1581. if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  1582. if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
  1583. if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
  1584. this._trigger('drop', event, this.ui(draggable));
  1585. return this.element;
  1586. }
  1587. return false;
  1588. },
  1589. ui: function(c) {
  1590. return {
  1591. draggable: (c.currentItem || c.element),
  1592. helper: c.helper,
  1593. position: c.position,
  1594. offset: c.positionAbs
  1595. };
  1596. }
  1597. });
  1598. $.extend($.ui.droppable, {
  1599. version: "1.8.7"
  1600. });
  1601. $.ui.intersect = function(draggable, droppable, toleranceMode) {
  1602. if (!droppable.offset) return false;
  1603. var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
  1604. y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
  1605. var l = droppable.offset.left, r = l + droppable.proportions.width,
  1606. t = droppable.offset.top, b = t + droppable.proportions.height;
  1607. switch (toleranceMode) {
  1608. case 'fit':
  1609. return (l <= x1 && x2 <= r
  1610. && t <= y1 && y2 <= b);
  1611. break;
  1612. case 'intersect':
  1613. return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
  1614. && x2 - (draggable.helperProportions.width / 2) < r // Left Half
  1615. && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
  1616. && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
  1617. break;
  1618. case 'pointer':
  1619. var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
  1620. draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
  1621. isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
  1622. return isOver;
  1623. break;
  1624. case 'touch':
  1625. return (
  1626. (y1 >= t && y1 <= b) || // Top edge touching
  1627. (y2 >= t && y2 <= b) || // Bottom edge touching
  1628. (y1 < t && y2 > b) // Surrounded vertically
  1629. ) && (
  1630. (x1 >= l && x1 <= r) || // Left edge touching
  1631. (x2 >= l && x2 <= r) || // Right edge touching
  1632. (x1 < l && x2 > r) // Surrounded horizontally
  1633. );
  1634. break;
  1635. default:
  1636. return false;
  1637. break;
  1638. }
  1639. };
  1640. /*
  1641. This manager tracks offsets of draggables and droppables
  1642. */
  1643. $.ui.ddmanager = {
  1644. current: null,
  1645. droppables: { 'default': [] },
  1646. prepareOffsets: function(t, event) {
  1647. var m = $.ui.ddmanager.droppables[t.options.scope] || [];
  1648. var type = event ? event.type : null; // workaround for #2317
  1649. var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
  1650. droppablesLoop: for (var i = 0; i < m.length; i++) {
  1651. if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
  1652. for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
  1653. m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
  1654. m[i].offset = m[i].element.offset();
  1655. m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
  1656. if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
  1657. }
  1658. },
  1659. drop: function(draggable, event) {
  1660. var dropped = false;
  1661. $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
  1662. if(!this.options) return;
  1663. if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
  1664. dropped = dropped || this._drop.call(this, event);
  1665. if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
  1666. this.isout = 1; this.isover = 0;
  1667. this._deactivate.call(this, event);
  1668. }
  1669. });
  1670. return dropped;
  1671. },
  1672. drag: function(draggable, event) {
  1673. //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
  1674. if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
  1675. //Run through all droppables and check their positions based on specific tolerance options
  1676. $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
  1677. if(this.options.disabled || this.greedyChild || !this.visible) return;
  1678. var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
  1679. var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
  1680. if(!c) return;
  1681. var parentInstance;
  1682. if (this.options.greedy) {
  1683. var parent = this.element.parents(':data(droppable):eq(0)');
  1684. if (parent.length) {
  1685. parentInstance = $.data(parent[0], 'droppable');
  1686. parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
  1687. }
  1688. }
  1689. // we just moved into a greedy child
  1690. if (parentInstance && c == 'isover') {
  1691. parentInstance['isover'] = 0;
  1692. parentInstance['isout'] = 1;
  1693. parentInstance._out.call(parentInstance, event);
  1694. }
  1695. this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
  1696. this[c == "isover" ? "_over" : "_out"].call(this, event);
  1697. // we just moved out of a greedy child
  1698. if (parentInstance && c == 'isout') {
  1699. parentInstance['isout'] = 0;
  1700. parentInstance['isover'] = 1;
  1701. parentInstance._over.call(parentInstance, event);
  1702. }
  1703. });
  1704. }
  1705. };
  1706. })(jQuery);
  1707. /*
  1708. * jQuery UI Resizable 1.8.7
  1709. *
  1710. * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  1711. * Dual licensed under the MIT or GPL Version 2 licenses.
  1712. * http://jquery.org/license
  1713. *
  1714. * http://docs.jquery.com/UI/Resizables
  1715. *
  1716. * Depends:
  1717. * jquery.ui.core.js
  1718. * jquery.ui.mouse.js
  1719. * jquery.ui.widget.js
  1720. */
  1721. (function( $, undefined ) {
  1722. $.widget("ui.resizable", $.ui.mouse, {
  1723. widgetEventPrefix: "resize",
  1724. options: {
  1725. alsoResize: false,
  1726. animate: false,
  1727. animateDuration: "slow",
  1728. animateEasing: "swing",
  1729. aspectRatio: false,
  1730. autoHide: false,
  1731. containment: false,
  1732. ghost: false,
  1733. grid: false,
  1734. handles: "e,s,se",
  1735. helper: false,
  1736. maxHeight: null,
  1737. maxWidth: null,
  1738. minHeight: 10,
  1739. minWidth: 10,
  1740. zIndex: 1000
  1741. },
  1742. _create: function() {
  1743. var self = this, o = this.options;
  1744. this.element.addClass("ui-resizable");
  1745. $.extend(this, {
  1746. _aspectRatio: !!(o.aspectRatio),
  1747. aspectRatio: o.aspectRatio,
  1748. originalElement: this.element,
  1749. _proportionallyResizeElements: [],
  1750. _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
  1751. });
  1752. //Wrap the element if it cannot hold child nodes
  1753. if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
  1754. //Opera fix for relative positioning
  1755. if (/relative/.test(this.element.css('position')) && $.browser.opera)
  1756. this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
  1757. //Create a wrapper element and set the wrapper to the new current internal element
  1758. this.element.wrap(
  1759. $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
  1760. position: this.element.css('position'),
  1761. width: this.element.outerWidth(),
  1762. height: this.element.outerHeight(),
  1763. top: this.element.css('top'),
  1764. left: this.element.css('left')
  1765. })
  1766. );
  1767. //Overwrite the original this.element
  1768. this.element = this.element.parent().data(
  1769. "resizable", this.element.data('resizable')
  1770. );
  1771. this.elementIsWrapper = true;
  1772. //Move margins to the wrapper
  1773. this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
  1774. this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
  1775. //Prevent Safari textarea resize
  1776. this.originalResizeStyle = this.originalElement.css('resize');
  1777. this.originalElement.css('resize', 'none');
  1778. //Push the actual element to our proportionallyResize internal array
  1779. this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
  1780. // avoid IE jump (hard set the margin)
  1781. this.originalElement.css({ margin: this.originalElement.css('margin') });
  1782. // fix handlers offset
  1783. this._proportionallyResize();
  1784. }
  1785. this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
  1786. if(this.handles.constructor == String) {
  1787. if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
  1788. var n = this.handles.split(","); this.handles = {};
  1789. for(var i = 0; i < n.length; i++) {
  1790. var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
  1791. var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
  1792. // increase zIndex of sw, se, ne, nw axis
  1793. //TODO : this modifies original option
  1794. if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
  1795. //TODO : What's going on here?
  1796. if ('se' == handle) {
  1797. axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
  1798. };
  1799. //Insert into internal handles object and append to element
  1800. this.handles[handle] = '.ui-resizable-'+handle;
  1801. this.element.append(axis);
  1802. }
  1803. }
  1804. this._renderAxis = function(target) {
  1805. target = target || this.element;
  1806. for(var i in this.handles) {
  1807. if(this.handles[i].constructor == String)
  1808. this.handles[i] = $(this.handles[i], this.element).show();
  1809. //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
  1810. if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
  1811. var axis = $(this.handles[i], this.element), padWrapper = 0;
  1812. //Checking the correct pad and border
  1813. padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
  1814. //The padding type i have to apply...
  1815. var padPos = [ 'padding',
  1816. /ne|nw|n/.test(i) ? 'Top' :
  1817. /se|sw|s/.test(i) ? 'Bottom' :
  1818. /^e$/.test(i) ? 'Right' : 'Left' ].join("");
  1819. target.css(padPos, padWrapper);
  1820. this._proportionallyResize();
  1821. }
  1822. //TODO: What's that good for? There's not anything to be executed left
  1823. if(!$(this.handles[i]).length)
  1824. continue;
  1825. }
  1826. };
  1827. //TODO: make renderAxis a prototype function
  1828. this._renderAxis(this.element);
  1829. this._handles = $('.ui-resizable-handle', this.element)
  1830. .disableSelection();
  1831. //Matching axis name
  1832. this._handles.mouseover(function() {
  1833. if (!self.resizing) {
  1834. if (this.className)
  1835. var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
  1836. //Axis, default = se
  1837. self.axis = axis && axis[1] ? axis[1] : 'se';
  1838. }
  1839. });
  1840. //If we want to auto hide the elements
  1841. if (o.autoHide) {
  1842. this._handles.hide();
  1843. $(this.element)
  1844. .addClass("ui-resizable-autohide")
  1845. .hover(function() {
  1846. $(this).removeClass("ui-resizable-autohide");
  1847. self._handles.show();
  1848. },
  1849. function(){
  1850. if (!self.resizing) {
  1851. $(this).addClass("ui-resizable-autohide");
  1852. self._handles.hide();
  1853. }
  1854. });
  1855. }
  1856. //Initialize the mouse interaction
  1857. this._mouseInit();
  1858. },
  1859. destroy: function() {
  1860. this._mouseDestroy();
  1861. var _destroy = function(exp) {
  1862. $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
  1863. .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
  1864. };
  1865. //TODO: Unwrap at same DOM position
  1866. if (this.elementIsWrapper) {
  1867. _destroy(this.element);
  1868. var wrapper = this.element;
  1869. wrapper.after(
  1870. this.originalElement.css({
  1871. position: wrapper.css('position'),
  1872. width: wrapper.outerWidth(),
  1873. height: wrapper.outerHeight(),
  1874. top: wrapper.css('top'),
  1875. left: wrapper.css('left')
  1876. })
  1877. ).remove();
  1878. }
  1879. this.originalElement.css('resize', this.originalResizeStyle);
  1880. _destroy(this.originalElement);
  1881. return this;
  1882. },
  1883. _mouseCapture: function(event) {
  1884. var handle = false;
  1885. for (var i in this.handles) {
  1886. if ($(this.handles[i])[0] == event.target) {
  1887. handle = true;
  1888. }
  1889. }
  1890. return !this.options.disabled && handle;
  1891. },
  1892. _mouseStart: function(event) {
  1893. var o = this.options, iniPos = this.element.position(), el = this.element;
  1894. this.resizing = true;
  1895. this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
  1896. // bugfix for http://dev.jquery.com/ticket/1749
  1897. if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
  1898. el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
  1899. }
  1900. //Opera fixing relative position
  1901. if ($.browser.opera && (/relative/).test(el.css('position')))
  1902. el.css({ position: 'relative', top: 'auto', left: 'auto' });
  1903. this._renderProxy();
  1904. var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
  1905. if (o.containment) {
  1906. curleft += $(o.containment).scrollLeft() || 0;
  1907. curtop += $(o.containment).scrollTop() || 0;
  1908. }
  1909. //Store needed variables
  1910. this.offset = this.helper.offset();
  1911. this.position = { left: curleft, top: curtop };
  1912. this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
  1913. this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
  1914. this.originalPosition = { left: curleft, top: curtop };
  1915. this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
  1916. this.originalMousePosition = { left: event.pageX, top: event.pageY };
  1917. //Aspect Ratio
  1918. this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
  1919. var cursor = $('.ui-resizable-' + this.axis).css('cursor');
  1920. $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
  1921. el.addClass("ui-resizable-resizing");
  1922. this._propagate("start", event);
  1923. return true;
  1924. },
  1925. _mouseDrag: function(event) {
  1926. //Increase performance, avoid regex
  1927. var el = this.helper, o = this.options, props = {},
  1928. self = this, smp = this.originalMousePosition, a = this.axis;
  1929. var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
  1930. var trigger = this._change[a];
  1931. if (!trigger) return false;
  1932. // Calculate the attrs that will be change
  1933. var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
  1934. if (this._aspectRatio || event.shiftKey)
  1935. data = this._updateRatio(data, event);
  1936. data = this._respectSize(data, event);
  1937. // plugins callbacks need to be called first
  1938. this._propagate("resize", event);
  1939. el.css({
  1940. top: this.position.top + "px", left: this.position.left + "px",
  1941. width: this.size.width + "px", height: this.size.height + "px"
  1942. });
  1943. if (!this._helper && this._proportionallyResizeElements.length)
  1944. this._proportionallyResize();
  1945. this._updateCache(data);
  1946. // calling the user callback at the end
  1947. this._trigger('resize', event, this.ui());
  1948. return false;
  1949. },
  1950. _mouseStop: function(event) {
  1951. this.resizing = false;
  1952. var o = this.options, self = this;
  1953. if(this._helper) {
  1954. var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
  1955. soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
  1956. soffsetw = ista ? 0 : self.sizeDiff.width;
  1957. var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
  1958. left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
  1959. top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
  1960. if (!o.animate)
  1961. this.element.css($.extend(s, { top: top, left: left }));
  1962. self.helper.height(self.size.height);
  1963. self.helper.width(self.size.width);
  1964. if (this._helper && !o.animate) this._proportionallyResize();
  1965. }
  1966. $('body').css('cursor', 'auto');
  1967. this.element.removeClass("ui-resizable-resizing");
  1968. this._propagate("stop", event);
  1969. if (this._helper) this.helper.remove();
  1970. return false;
  1971. },
  1972. _updateCache: function(data) {
  1973. var o = this.options;
  1974. this.offset = this.helper.offset();
  1975. if (isNumber(data.left)) this.position.left = data.left;
  1976. if (isNumber(data.top)) this.position.top = data.top;
  1977. if (isNumber(data.height)) this.size.height = data.height;
  1978. if (isNumber(data.width)) this.size.width = data.width;
  1979. },
  1980. _updateRatio: function(data, event) {
  1981. var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
  1982. if (data.height) data.width = (csize.height * this.aspectRatio);
  1983. else if (data.width) data.height = (csize.width / this.aspectRatio);
  1984. if (a == 'sw') {
  1985. data.left = cpos.left + (csize.width - data.width);
  1986. data.top = null;
  1987. }
  1988. if (a == 'nw') {
  1989. data.top = cpos.top + (csize.height - data.height);
  1990. data.left = cpos.left + (csize.width - data.width);
  1991. }
  1992. return data;
  1993. },
  1994. _respectSize: function(data, event) {
  1995. var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
  1996. ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
  1997. isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
  1998. if (isminw) data.width = o.minWidth;
  1999. if (isminh) data.height = o.minHeight;
  2000. if (ismaxw) data.width = o.maxWidth;
  2001. if (ismaxh) data.height = o.maxHeight;
  2002. var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
  2003. var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
  2004. if (isminw && cw) data.left = dw - o.minWidth;
  2005. if (ismaxw && cw) data.left = dw - o.maxWidth;
  2006. if (isminh && ch) data.top = dh - o.minHeight;
  2007. if (ismaxh && ch) data.top = dh - o.maxHeight;
  2008. // fixing jump error on top/left - bug #2330
  2009. var isNotwh = !data.width && !data.height;
  2010. if (isNotwh && !data.left && data.top) data.top = null;
  2011. else if (isNotwh && !data.top && data.left) data.left = null;
  2012. return data;
  2013. },
  2014. _proportionallyResize: function() {
  2015. var o = this.options;
  2016. if (!this._proportionallyResizeElements.length) return;
  2017. var element = this.helper || this.element;
  2018. for (var i=0; i < this._proportionallyResizeElements.length; i++) {
  2019. var prel = this._proportionallyResizeElements[i];
  2020. if (!this.borderDif) {
  2021. var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
  2022. p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
  2023. this.borderDif = $.map(b, function(v, i) {
  2024. var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
  2025. return border + padding;
  2026. });
  2027. }
  2028. if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
  2029. continue;
  2030. prel.css({
  2031. height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
  2032. width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
  2033. });
  2034. };
  2035. },
  2036. _renderProxy: function() {
  2037. var el = this.element, o = this.options;
  2038. this.elementOffset = el.offset();
  2039. if(this._helper) {
  2040. this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
  2041. // fix ie6 offset TODO: This seems broken
  2042. var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
  2043. pxyoffset = ( ie6 ? 2 : -1 );
  2044. this.helper.addClass(this._helper).css({
  2045. width: this.element.outerWidth() + pxyoffset,
  2046. height: this.element.outerHeight() + pxyoffset,
  2047. position: 'absolute',
  2048. left: this.elementOffset.left - ie6offset +'px',
  2049. top: this.elementOffset.top - ie6offset +'px',
  2050. zIndex: ++o.zIndex //TODO: Don't modify option
  2051. });
  2052. this.helper
  2053. .appendTo("body")
  2054. .disableSelection();
  2055. } else {
  2056. this.helper = this.element;
  2057. }
  2058. },
  2059. _change: {
  2060. e: function(event, dx, dy) {
  2061. return { width: this.originalSize.width + dx };
  2062. },
  2063. w: function(event, dx, dy) {
  2064. var o = this.options, cs = this.originalSize, sp = this.originalPosition;
  2065. return { left: sp.left + dx, width: cs.width - dx };
  2066. },
  2067. n: function(event, dx, dy) {
  2068. var o = this.options, cs = this.originalSize, sp = this.originalPosition;
  2069. return { top: sp.top + dy, height: cs.height - dy };
  2070. },
  2071. s: function(event, dx, dy) {
  2072. return { height: this.originalSize.height + dy };
  2073. },
  2074. se: function(event, dx, dy) {
  2075. return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  2076. },
  2077. sw: function(event, dx, dy) {
  2078. return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  2079. },
  2080. ne: function(event, dx, dy) {
  2081. return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  2082. },
  2083. nw: function(event, dx, dy) {
  2084. return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  2085. }
  2086. },
  2087. _propagate: function(n, event) {
  2088. $.ui.plugin.call(this, n, [event, this.ui()]);
  2089. (n != "resize" && this._trigger(n, event, this.ui()));
  2090. },
  2091. plugins: {},
  2092. ui: function() {
  2093. return {
  2094. originalElement: this.originalElement,
  2095. element: this.element,
  2096. helper: this.helper,
  2097. position: this.position,
  2098. size: this.size,
  2099. originalSize: this.originalSize,
  2100. originalPosition: this.originalPosition
  2101. };
  2102. }
  2103. });
  2104. $.extend($.ui.resizable, {
  2105. version: "1.8.7"
  2106. });
  2107. /*
  2108. * Resizable Extensions
  2109. */
  2110. $.ui.plugin.add("resizable", "alsoResize", {
  2111. start: function (event, ui) {
  2112. var self = $(this).data("resizable"), o = self.options;
  2113. var _store = function (exp) {
  2114. $(exp).each(function() {
  2115. var el = $(this);
  2116. el.data("resizable-alsoresize", {
  2117. width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
  2118. left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
  2119. position: el.css('position') // to reset Opera on stop()
  2120. });
  2121. });
  2122. };
  2123. if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
  2124. if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
  2125. else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
  2126. }else{
  2127. _store(o.alsoResize);
  2128. }
  2129. },
  2130. resize: function (event, ui) {
  2131. var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
  2132. var delta = {
  2133. height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
  2134. top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
  2135. },
  2136. _alsoResize = function (exp, c) {
  2137. $(exp).each(function() {
  2138. var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
  2139. css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
  2140. $.each(css, function (i, prop) {
  2141. var sum = (start[prop]||0) + (delta[prop]||0);
  2142. if (sum && sum >= 0)
  2143. style[prop] = sum || null;
  2144. });
  2145. // Opera fixing relative position
  2146. if ($.browser.opera && /relative/.test(el.css('position'))) {
  2147. self._revertToRelativePosition = true;
  2148. el.css({ position: 'absolute', top: 'auto', left: 'auto' });
  2149. }
  2150. el.css(style);
  2151. });
  2152. };
  2153. if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
  2154. $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
  2155. }else{
  2156. _alsoResize(o.alsoResize);
  2157. }
  2158. },
  2159. stop: function (event, ui) {
  2160. var self = $(this).data("resizable"), o = self.options;
  2161. var _reset = function (exp) {
  2162. $(exp).each(function() {
  2163. var el = $(this);
  2164. // reset position for Opera - no need to verify it was changed
  2165. el.css({ position: el.data("resizable-alsoresize").position });
  2166. });
  2167. };
  2168. if (self._revertToRelativePosition) {
  2169. self._revertToRelativePosition = false;
  2170. if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
  2171. $.each(o.alsoResize, function (exp) { _reset(exp); });
  2172. }else{
  2173. _reset(o.alsoResize);
  2174. }
  2175. }
  2176. $(this).removeData("resizable-alsoresize");
  2177. }
  2178. });
  2179. $.ui.plugin.add("resizable", "animate", {
  2180. stop: function(event, ui) {
  2181. var self = $(this).data("resizable"), o = self.options;
  2182. var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
  2183. soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
  2184. soffsetw = ista ? 0 : self.sizeDiff.width;
  2185. var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
  2186. left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
  2187. top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
  2188. self.element.animate(
  2189. $.extend(style, top && left ? { top: top, left: left } : {}), {
  2190. duration: o.animateDuration,
  2191. easing: o.animateEasing,
  2192. step: function() {
  2193. var data = {
  2194. width: parseInt(self.element.css('width'), 10),
  2195. height: parseInt(self.element.css('height'), 10),
  2196. top: parseInt(self.element.css('top'), 10),
  2197. left: parseInt(self.element.css('left'), 10)
  2198. };
  2199. if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
  2200. // propagating resize, and updating values for each animation step
  2201. self._updateCache(data);
  2202. self._propagate("resize", event);
  2203. }
  2204. }
  2205. );
  2206. }
  2207. });
  2208. $.ui.plugin.add("resizable", "containment", {
  2209. start: function(event, ui) {
  2210. var self = $(this).data("resizable"), o = self.options, el = self.element;
  2211. var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
  2212. if (!ce) return;
  2213. self.containerElement = $(ce);
  2214. if (/document/.test(oc) || oc == document) {
  2215. self.containerOffset = { left: 0, top: 0 };
  2216. self.containerPosition = { left: 0, top: 0 };
  2217. self.parentData = {
  2218. element: $(document), left: 0, top: 0,
  2219. width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
  2220. };
  2221. }
  2222. // i'm a node, so compute top, left, right, bottom
  2223. else {
  2224. var element = $(ce), p = [];
  2225. $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
  2226. self.containerOffset = element.offset();
  2227. self.containerPosition = element.position();
  2228. self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
  2229. var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
  2230. width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
  2231. self.parentData = {
  2232. element: ce, left: co.left, top: co.top, width: width, height: height
  2233. };
  2234. }
  2235. },
  2236. resize: function(event, ui) {
  2237. var self = $(this).data("resizable"), o = self.options,
  2238. ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
  2239. pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
  2240. if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
  2241. if (cp.left < (self._helper ? co.left : 0)) {
  2242. self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
  2243. if (pRatio) self.size.height = self.size.width / o.aspectRatio;
  2244. self.position.left = o.helper ? co.left : 0;
  2245. }
  2246. if (cp.top < (self._helper ? co.top : 0)) {
  2247. self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
  2248. if (pRatio) self.size.width = self.size.height * o.aspectRatio;
  2249. self.position.top = self._helper ? co.top : 0;
  2250. }
  2251. self.offset.left = self.parentData.left+self.position.left;
  2252. self.offset.top = self.parentData.top+self.position.top;
  2253. var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
  2254. hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
  2255. var isParent = self.containerElement.get(0) == self.element.parent().get(0),
  2256. isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
  2257. if(isParent && isOffsetRelative) woset -= self.parentData.left;
  2258. if (woset + self.size.width >= self.parentData.width) {
  2259. self.size.width = self.parentData.width - woset;
  2260. if (pRatio) self.size.height = self.size.width / self.aspectRatio;
  2261. }
  2262. if (hoset + self.size.height >= self.parentData.height) {
  2263. self.size.height = self.parentData.height - hoset;
  2264. if (pRatio) self.size.width = self.size.height * self.aspectRatio;
  2265. }
  2266. },
  2267. stop: function(event, ui){
  2268. var self = $(this).data("resizable"), o = self.options, cp = self.position,
  2269. co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
  2270. var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
  2271. if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
  2272. $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  2273. if (self._helper && !o.animate && (/static/).test(ce.css('position')))
  2274. $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  2275. }
  2276. });
  2277. $.ui.plugin.add("resizable", "ghost", {
  2278. start: function(event, ui) {
  2279. var self = $(this).data("resizable"), o = self.options, cs = self.size;
  2280. self.ghost = self.originalElement.clone();
  2281. self.ghost
  2282. .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
  2283. .addClass('ui-resizable-ghost')
  2284. .addClass(typeof o.ghost == 'string' ? o.ghost : '');
  2285. self.ghost.appendTo(self.helper);
  2286. },
  2287. resize: function(event, ui){
  2288. var self = $(this).data("resizable"), o = self.options;
  2289. if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
  2290. },
  2291. stop: function(event, ui){
  2292. var self = $(this).data("resizable"), o = self.options;
  2293. if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
  2294. }
  2295. });
  2296. $.ui.plugin.add("resizable", "grid", {
  2297. resize: function(event, ui) {
  2298. var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
  2299. o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
  2300. var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
  2301. if (/^(se|s|e)$/.test(a)) {
  2302. self.size.width = os.width + ox;
  2303. self.size.height = os.height + oy;
  2304. }
  2305. else if (/^(ne)$/.test(a)) {
  2306. self.size.width = os.width + ox;
  2307. self.size.height = os.height + oy;
  2308. self.position.top = op.top - oy;
  2309. }
  2310. else if (/^(sw)$/.test(a)) {
  2311. self.size.width = os.width + ox;
  2312. self.size.height = os.height + oy;
  2313. self.position.left = op.left - ox;
  2314. }
  2315. else {
  2316. self.size.width = os.width + ox;
  2317. self.size.height = os.height + oy;
  2318. self.position.top = op.top - oy;
  2319. self.position.left = op.left - ox;
  2320. }
  2321. }
  2322. });
  2323. var num = function(v) {
  2324. return parseInt(v, 10) || 0;
  2325. };
  2326. var isNumber = function(value) {
  2327. return !isNaN(parseInt(value, 10));
  2328. };
  2329. })(jQuery);
  2330. /*
  2331. * jQuery UI Selectable 1.8.7
  2332. *
  2333. * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  2334. * Dual licensed under the MIT or GPL Version 2 licenses.
  2335. * http://jquery.org/license
  2336. *
  2337. * http://docs.jquery.com/UI/Selectables
  2338. *
  2339. * Depends:
  2340. * jquery.ui.core.js
  2341. * jquery.ui.mouse.js
  2342. * jquery.ui.widget.js
  2343. */
  2344. (function( $, undefined ) {
  2345. $.widget("ui.selectable", $.ui.mouse, {
  2346. options: {
  2347. appendTo: 'body',
  2348. autoRefresh: true,
  2349. distance: 0,
  2350. filter: '*',
  2351. tolerance: 'touch'
  2352. },
  2353. _create: function() {
  2354. var self = this;
  2355. this.element.addClass("ui-selectable");
  2356. this.dragged = false;
  2357. // cache selectee children based on filter
  2358. var selectees;
  2359. this.refresh = function() {
  2360. selectees = $(self.options.filter, self.element[0]);
  2361. selectees.each(function() {
  2362. var $this = $(this);
  2363. var pos = $this.offset();
  2364. $.data(this, "selectable-item", {
  2365. element: this,
  2366. $element: $this,
  2367. left: pos.left,
  2368. top: pos.top,
  2369. right: pos.left + $this.outerWidth(),
  2370. bottom: pos.top + $this.outerHeight(),
  2371. startselected: false,
  2372. selected: $this.hasClass('ui-selected'),
  2373. selecting: $this.hasClass('ui-selecting'),
  2374. unselecting: $this.hasClass('ui-unselecting')
  2375. });
  2376. });
  2377. };
  2378. this.refresh();
  2379. this.selectees = selectees.addClass("ui-selectee");
  2380. this._mouseInit();
  2381. this.helper = $("<div class='ui-selectable-helper'></div>");
  2382. },
  2383. destroy: function() {
  2384. this.selectees
  2385. .removeClass("ui-selectee")
  2386. .removeData("selectable-item");
  2387. this.element
  2388. .removeClass("ui-selectable ui-selectable-disabled")
  2389. .removeData("selectable")
  2390. .unbind(".selectable");
  2391. this._mouseDestroy();
  2392. return this;
  2393. },
  2394. _mouseStart: function(event) {
  2395. var self = this;
  2396. this.opos = [event.pageX, event.pageY];
  2397. if (this.options.disabled)
  2398. return;
  2399. var options = this.options;
  2400. this.selectees = $(options.filter, this.element[0]);
  2401. this._trigger("start", event);
  2402. $(options.appendTo).append(this.helper);
  2403. // position helper (lasso)
  2404. this.helper.css({
  2405. "left": event.clientX,
  2406. "top": event.clientY,
  2407. "width": 0,
  2408. "height": 0
  2409. });
  2410. if (options.autoRefresh) {
  2411. this.refresh();
  2412. }
  2413. this.selectees.filter('.ui-selected').each(function() {
  2414. var selectee = $.data(this, "selectable-item");
  2415. selectee.startselected = true;
  2416. if (!event.metaKey) {
  2417. selectee.$element.removeClass('ui-selected');
  2418. selectee.selected = false;
  2419. selectee.$element.addClass('ui-unselecting');
  2420. selectee.unselecting = true;
  2421. // selectable UNSELECTING callback
  2422. self._trigger("unselecting", event, {
  2423. unselecting: selectee.element
  2424. });
  2425. }
  2426. });
  2427. $(event.target).parents().andSelf().each(function() {
  2428. var selectee = $.data(this, "selectable-item");
  2429. if (selectee) {
  2430. var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
  2431. selectee.$element
  2432. .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
  2433. .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
  2434. selectee.unselecting = !doSelect;
  2435. selectee.selecting = doSelect;
  2436. selectee.selected = doSelect;
  2437. // selectable (UN)SELECTING callback
  2438. if (doSelect) {
  2439. self._trigger("selecting", event, {
  2440. selecting: selectee.element
  2441. });
  2442. } else {
  2443. self._trigger("unselecting", event, {
  2444. unselecting: selectee.element
  2445. });
  2446. }
  2447. return false;
  2448. }
  2449. });
  2450. },
  2451. _mouseDrag: function(event) {
  2452. var self = this;
  2453. this.dragged = true;
  2454. if (this.options.disabled)
  2455. return;
  2456. var options = this.options;
  2457. var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
  2458. if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
  2459. if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
  2460. this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
  2461. this.selectees.each(function() {
  2462. var selectee = $.data(this, "selectable-item");
  2463. //prevent helper from being selected if appendTo: selectable
  2464. if (!selectee || selectee.element == self.element[0])
  2465. return;
  2466. var hit = false;
  2467. if (options.tolerance == 'touch') {
  2468. hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
  2469. } else if (options.tolerance == 'fit') {
  2470. hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
  2471. }
  2472. if (hit) {
  2473. // SELECT
  2474. if (selectee.selected) {
  2475. selectee.$element.removeClass('ui-selected');
  2476. selectee.selected = false;
  2477. }
  2478. if (selectee.unselecting) {
  2479. selectee.$element.removeClass('ui-unselecting');
  2480. selectee.unselecting = false;
  2481. }
  2482. if (!selectee.selecting) {
  2483. selectee.$element.addClass('ui-selecting');
  2484. selectee.selecting = true;
  2485. // selectable SELECTING callback
  2486. self._trigger("selecting", event, {
  2487. selecting: selectee.element
  2488. });
  2489. }
  2490. } else {
  2491. // UNSELECT
  2492. if (selectee.selecting) {
  2493. if (event.metaKey && selectee.startselected) {
  2494. selectee.$element.removeClass('ui-selecting');
  2495. selectee.selecting = false;
  2496. selectee.$element.addClass('ui-selected');
  2497. selectee.selected = true;
  2498. } else {
  2499. selectee.$element.removeClass('ui-selecting');
  2500. selectee.selecting = false;
  2501. if (selectee.startselected) {
  2502. selectee.$element.addClass('ui-unselecting');
  2503. selectee.unselecting = true;
  2504. }
  2505. // selectable UNSELECTING callback
  2506. self._trigger("unselecting", event, {
  2507. unselecting: selectee.element
  2508. });
  2509. }
  2510. }
  2511. if (selectee.selected) {
  2512. if (!event.metaKey && !selectee.startselected) {
  2513. selectee.$element.removeClass('ui-selected');
  2514. selectee.selected = false;
  2515. selectee.$element.addClass('ui-unselecting');
  2516. selectee.unselecting = true;
  2517. // selectable UNSELECTING callback
  2518. self._trigger("unselecting", event, {
  2519. unselecting: selectee.element
  2520. });
  2521. }
  2522. }
  2523. }
  2524. });
  2525. return false;
  2526. },
  2527. _mouseStop: function(event) {
  2528. var self = this;
  2529. this.dragged = false;
  2530. var options = this.options;
  2531. $('.ui-unselecting', this.element[0]).each(function() {
  2532. var selectee = $.data(this, "selectable-item");
  2533. selectee.$element.removeClass('ui-unselecting');
  2534. selectee.unselecting = false;
  2535. selectee.startselected = false;
  2536. self._trigger("unselected", event, {
  2537. unselected: selectee.element
  2538. });
  2539. });
  2540. $('.ui-selecting', this.element[0]).each(function() {
  2541. var selectee = $.data(this, "selectable-item");
  2542. selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
  2543. selectee.selecting = false;
  2544. selectee.selected = true;
  2545. selectee.startselected = true;
  2546. self._trigger("selected", event, {
  2547. selected: selectee.element
  2548. });
  2549. });
  2550. this._trigger("stop", event);
  2551. this.helper.remove();
  2552. return false;
  2553. }
  2554. });
  2555. $.extend($.ui.selectable, {
  2556. version: "1.8.7"
  2557. });
  2558. })(jQuery);
  2559. /*
  2560. * jQuery UI Sortable 1.8.7
  2561. *
  2562. * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  2563. * Dual licensed under the MIT or GPL Version 2 licenses.
  2564. * http://jquery.org/license
  2565. *
  2566. * http://docs.jquery.com/UI/Sortables
  2567. *
  2568. * Depends:
  2569. * jquery.ui.core.js
  2570. * jquery.ui.mouse.js
  2571. * jquery.ui.widget.js
  2572. */
  2573. (function( $, undefined ) {
  2574. $.widget("ui.sortable", $.ui.mouse, {
  2575. widgetEventPrefix: "sort",
  2576. options: {
  2577. appendTo: "parent",
  2578. axis: false,
  2579. connectWith: false,
  2580. containment: false,
  2581. cursor: 'auto',
  2582. cursorAt: false,
  2583. dropOnEmpty: true,
  2584. forcePlaceholderSize: false,
  2585. forceHelperSize: false,
  2586. grid: false,
  2587. handle: false,
  2588. helper: "original",
  2589. items: '> *',
  2590. opacity: false,
  2591. placeholder: false,
  2592. revert: false,
  2593. scroll: true,
  2594. scrollSensitivity: 20,
  2595. scrollSpeed: 20,
  2596. scope: "default",
  2597. tolerance: "intersect",
  2598. zIndex: 1000
  2599. },
  2600. _create: function() {
  2601. var o = this.options;
  2602. this.containerCache = {};
  2603. this.element.addClass("ui-sortable");
  2604. //Get the items
  2605. this.refresh();
  2606. //Let's determine if the items are floating
  2607. this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false;
  2608. //Let's determine the parent's offset
  2609. this.offset = this.element.offset();
  2610. //Initialize mouse events for interaction
  2611. this._mouseInit();
  2612. },
  2613. destroy: function() {
  2614. this.element
  2615. .removeClass("ui-sortable ui-sortable-disabled")
  2616. .removeData("sortable")
  2617. .unbind(".sortable");
  2618. this._mouseDestroy();
  2619. for ( var i = this.items.length - 1; i >= 0; i-- )
  2620. this.items[i].item.removeData("sortable-item");
  2621. return this;
  2622. },
  2623. _setOption: function(key, value){
  2624. if ( key === "disabled" ) {
  2625. this.options[ key ] = value;
  2626. this.widget()
  2627. [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
  2628. } else {
  2629. // Don't call widget base _setOption for disable as it adds ui-state-disabled class
  2630. $.Widget.prototype._setOption.apply(this, arguments);
  2631. }
  2632. },
  2633. _mouseCapture: function(event, overrideHandle) {
  2634. if (this.reverting) {
  2635. return false;
  2636. }
  2637. if(this.options.disabled || this.options.type == 'static') return false;
  2638. //We have to refresh the items data once first
  2639. this._refreshItems(event);
  2640. //Find out if the clicked node (or one of its parents) is a actual item in this.items
  2641. var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
  2642. if($.data(this, 'sortable-item') == self) {
  2643. currentItem = $(this);
  2644. return false;
  2645. }
  2646. });
  2647. if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
  2648. if(!currentItem) return false;
  2649. if(this.options.handle && !overrideHandle) {
  2650. var validHandle = false;
  2651. $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
  2652. if(!validHandle) return false;
  2653. }
  2654. this.currentItem = currentItem;
  2655. this._removeCurrentsFromItems();
  2656. return true;
  2657. },
  2658. _mouseStart: function(event, overrideHandle, noActivation) {
  2659. var o = this.options, self = this;
  2660. this.currentContainer = this;
  2661. //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
  2662. this.refreshPositions();
  2663. //Create and append the visible helper
  2664. this.helper = this._createHelper(event);
  2665. //Cache the helper size
  2666. this._cacheHelperProportions();
  2667. /*
  2668. * - Position generation -
  2669. * This block generates everything position related - it's the core of draggables.
  2670. */
  2671. //Cache the margins of the original element
  2672. this._cacheMargins();
  2673. //Get the next scrolling parent
  2674. this.scrollParent = this.helper.scrollParent();
  2675. //The element's absolute position on the page minus margins
  2676. this.offset = this.currentItem.offset();
  2677. this.offset = {
  2678. top: this.offset.top - this.margins.top,
  2679. left: this.offset.left - this.margins.left
  2680. };
  2681. // Only after we got the offset, we can change the helper's position to absolute
  2682. // TODO: Still need to figure out a way to make relative sorting possible
  2683. this.helper.css("position", "absolute");
  2684. this.cssPosition = this.helper.css("position");
  2685. $.extend(this.offset, {
  2686. click: { //Where the click happened, relative to the element
  2687. left: event.pageX - this.offset.left,
  2688. top: event.pageY - this.offset.top
  2689. },
  2690. parent: this._getParentOffset(),
  2691. relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
  2692. });
  2693. //Generate the original position
  2694. this.originalPosition = this._generatePosition(event);
  2695. this.originalPageX = event.pageX;
  2696. this.originalPageY = event.pageY;
  2697. //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
  2698. (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
  2699. //Cache the former DOM position
  2700. this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
  2701. //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
  2702. if(this.helper[0] != this.currentItem[0]) {
  2703. this.currentItem.hide();
  2704. }
  2705. //Create the placeholder
  2706. this._createPlaceholder();
  2707. //Set a containment if given in the options
  2708. if(o.containment)
  2709. this._setContainment();
  2710. if(o.cursor) { // cursor option
  2711. if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
  2712. $('body').css("cursor", o.cursor);
  2713. }
  2714. if(o.opacity) { // opacity option
  2715. if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
  2716. this.helper.css("opacity", o.opacity);
  2717. }
  2718. if(o.zIndex) { // zIndex option
  2719. if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
  2720. this.helper.css("zIndex", o.zIndex);
  2721. }
  2722. //Prepare scrolling
  2723. if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
  2724. this.overflowOffset = this.scrollParent.offset();
  2725. //Call callbacks
  2726. this._trigger("start", event, this._uiHash());
  2727. //Recache the helper size
  2728. if(!this._preserveHelperProportions)
  2729. this._cacheHelperProportions();
  2730. //Post 'activate' events to possible containers
  2731. if(!noActivation) {
  2732. for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
  2733. }
  2734. //Prepare possible droppables
  2735. if($.ui.ddmanager)
  2736. $.ui.ddmanager.current = this;
  2737. if ($.ui.ddmanager && !o.dropBehaviour)
  2738. $.ui.ddmanager.prepareOffsets(this, event);
  2739. this.dragging = true;
  2740. this.helper.addClass("ui-sortable-helper");
  2741. this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
  2742. return true;
  2743. },
  2744. _mouseDrag: function(event) {
  2745. //Compute the helpers position
  2746. this.position = this._generatePosition(event);
  2747. this.positionAbs = this._convertPositionTo("absolute");
  2748. if (!this.lastPositionAbs) {
  2749. this.lastPositionAbs = this.positionAbs;
  2750. }
  2751. //Do scrolling
  2752. if(this.options.scroll) {
  2753. var o = this.options, scrolled = false;
  2754. if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
  2755. if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
  2756. this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
  2757. else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
  2758. this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
  2759. if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
  2760. this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
  2761. else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
  2762. this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
  2763. } else {
  2764. if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
  2765. scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  2766. else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
  2767. scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  2768. if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
  2769. scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  2770. else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
  2771. scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  2772. }
  2773. if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
  2774. $.ui.ddmanager.prepareOffsets(this, event);
  2775. }
  2776. //Regenerate the absolute position used for position checks
  2777. this.positionAbs = this._convertPositionTo("absolute");
  2778. //Set the helper position
  2779. if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
  2780. if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
  2781. //Rearrange
  2782. for (var i = this.items.length - 1; i >= 0; i--) {
  2783. //Cache variables and intersection, continue if no intersection
  2784. var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
  2785. if (!intersection) continue;
  2786. if(itemElement != this.currentItem[0] //cannot intersect with itself
  2787. && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
  2788. && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
  2789. && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
  2790. //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
  2791. ) {
  2792. this.direction = intersection == 1 ? "down" : "up";
  2793. if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
  2794. this._rearrange(event, item);
  2795. } else {
  2796. break;
  2797. }
  2798. this._trigger("change", event, this._uiHash());
  2799. break;
  2800. }
  2801. }
  2802. //Post events to containers
  2803. this._contactContainers(event);
  2804. //Interconnect with droppables
  2805. if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
  2806. //Call callbacks
  2807. this._trigger('sort', event, this._uiHash());
  2808. this.lastPositionAbs = this.positionAbs;
  2809. return false;
  2810. },
  2811. _mouseStop: function(event, noPropagation) {
  2812. if(!event) return;
  2813. //If we are using droppables, inform the manager about the drop
  2814. if ($.ui.ddmanager && !this.options.dropBehaviour)
  2815. $.ui.ddmanager.drop(this, event);
  2816. if(this.options.revert) {
  2817. var self = this;
  2818. var cur = self.placeholder.offset();
  2819. self.reverting = true;
  2820. $(this.helper).animate({
  2821. left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
  2822. top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
  2823. }, parseInt(this.options.revert, 10) || 500, function() {
  2824. self._clear(event);
  2825. });
  2826. } else {
  2827. this._clear(event, noPropagation);
  2828. }
  2829. return false;
  2830. },
  2831. cancel: function() {
  2832. var self = this;
  2833. if(this.dragging) {
  2834. this._mouseUp();
  2835. if(this.options.helper == "original")
  2836. this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
  2837. else
  2838. this.currentItem.show();
  2839. //Post deactivating events to containers
  2840. for (var i = this.containers.length - 1; i >= 0; i--){
  2841. this.containers[i]._trigger("deactivate", null, self._uiHash(this));
  2842. if(this.containers[i].containerCache.over) {
  2843. this.containers[i]._trigger("out", null, self._uiHash(this));
  2844. this.containers[i].containerCache.over = 0;
  2845. }
  2846. }
  2847. }
  2848. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
  2849. if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
  2850. if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
  2851. $.extend(this, {
  2852. helper: null,
  2853. dragging: false,
  2854. reverting: false,
  2855. _noFinalSort: null
  2856. });
  2857. if(this.domPosition.prev) {
  2858. $(this.domPosition.prev).after(this.currentItem);
  2859. } else {
  2860. $(this.domPosition.parent).prepend(this.currentItem);
  2861. }
  2862. return this;
  2863. },
  2864. serialize: function(o) {
  2865. var items = this._getItemsAsjQuery(o && o.connected);
  2866. var str = []; o = o || {};
  2867. $(items).each(function() {
  2868. var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
  2869. if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
  2870. });
  2871. if(!str.length && o.key) {
  2872. str.push(o.key + '=');
  2873. }
  2874. return str.join('&');
  2875. },
  2876. toArray: function(o) {
  2877. var items = this._getItemsAsjQuery(o && o.connected);
  2878. var ret = []; o = o || {};
  2879. items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
  2880. return ret;
  2881. },
  2882. /* Be careful with the following core functions */
  2883. _intersectsWith: function(item) {
  2884. var x1 = this.positionAbs.left,
  2885. x2 = x1 + this.helperProportions.width,
  2886. y1 = this.positionAbs.top,
  2887. y2 = y1 + this.helperProportions.height;
  2888. var l = item.left,
  2889. r = l + item.width,
  2890. t = item.top,
  2891. b = t + item.height;
  2892. var dyClick = this.offset.click.top,
  2893. dxClick = this.offset.click.left;
  2894. var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
  2895. if( this.options.tolerance == "pointer"
  2896. || this.options.forcePointerForContainers
  2897. || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
  2898. ) {
  2899. return isOverElement;
  2900. } else {
  2901. return (l < x1 + (this.helperProportions.width / 2) // Right Half
  2902. && x2 - (this.helperProportions.width / 2) < r // Left Half
  2903. && t < y1 + (this.helperProportions.height / 2) // Bottom Half
  2904. && y2 - (this.helperProportions.height / 2) < b ); // Top Half
  2905. }
  2906. },
  2907. _intersectsWithPointer: function(item) {
  2908. var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
  2909. isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
  2910. isOverElement = isOverElementHeight && isOverElementWidth,
  2911. verticalDirection = this._getDragVerticalDirection(),
  2912. horizontalDirection = this._getDragHorizontalDirection();
  2913. if (!isOverElement)
  2914. return false;
  2915. return this.floating ?
  2916. ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
  2917. : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
  2918. },
  2919. _intersectsWithSides: function(item) {
  2920. var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
  2921. isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
  2922. verticalDirection = this._getDragVerticalDirection(),
  2923. horizontalDirection = this._getDragHorizontalDirection();
  2924. if (this.floating && horizontalDirection) {
  2925. return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
  2926. } else {
  2927. return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
  2928. }
  2929. },
  2930. _getDragVerticalDirection: function() {
  2931. var delta = this.positionAbs.top - this.lastPositionAbs.top;
  2932. return delta != 0 && (delta > 0 ? "down" : "up");
  2933. },
  2934. _getDragHorizontalDirection: function() {
  2935. var delta = this.positionAbs.left - this.lastPositionAbs.left;
  2936. return delta != 0 && (delta > 0 ? "right" : "left");
  2937. },
  2938. refresh: function(event) {
  2939. this._refreshItems(event);
  2940. this.refreshPositions();
  2941. return this;
  2942. },
  2943. _connectWith: function() {
  2944. var options = this.options;
  2945. return options.connectWith.constructor == String
  2946. ? [options.connectWith]
  2947. : options.connectWith;
  2948. },
  2949. _getItemsAsjQuery: function(connected) {
  2950. var self = this;
  2951. var items = [];
  2952. var queries = [];
  2953. var connectWith = this._connectWith();
  2954. if(connectWith && connected) {
  2955. for (var i = connectWith.length - 1; i >= 0; i--){
  2956. var cur = $(connectWith[i]);
  2957. for (var j = cur.length - 1; j >= 0; j--){
  2958. var inst = $.data(cur[j], 'sortable');
  2959. if(inst && inst != this && !inst.options.disabled) {
  2960. queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
  2961. }
  2962. };
  2963. };
  2964. }
  2965. queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
  2966. for (var i = queries.length - 1; i >= 0; i--){
  2967. queries[i][0].each(function() {
  2968. items.push(this);
  2969. });
  2970. };
  2971. return $(items);
  2972. },
  2973. _removeCurrentsFromItems: function() {
  2974. var list = this.currentItem.find(":data(sortable-item)");
  2975. for (var i=0; i < this.items.length; i++) {
  2976. for (var j=0; j < list.length; j++) {
  2977. if(list[j] == this.items[i].item[0])
  2978. this.items.splice(i,1);
  2979. };
  2980. };
  2981. },
  2982. _refreshItems: function(event) {
  2983. this.items = [];
  2984. this.containers = [this];
  2985. var items = this.items;
  2986. var self = this;
  2987. var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
  2988. var connectWith = this._connectWith();
  2989. if(connectWith) {
  2990. for (var i = connectWith.length - 1; i >= 0; i--){
  2991. var cur = $(connectWith[i]);
  2992. for (var j = cur.length - 1; j >= 0; j--){
  2993. var inst = $.data(cur[j], 'sortable');
  2994. if(inst && inst != this && !inst.options.disabled) {
  2995. queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
  2996. this.containers.push(inst);
  2997. }
  2998. };
  2999. };
  3000. }
  3001. for (var i = queries.length - 1; i >= 0; i--) {
  3002. var targetData = queries[i][1];
  3003. var _queries = queries[i][0];
  3004. for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
  3005. var item = $(_queries[j]);
  3006. item.data('sortable-item', targetData); // Data for target checking (mouse manager)
  3007. items.push({
  3008. item: item,
  3009. instance: targetData,
  3010. width: 0, height: 0,
  3011. left: 0, top: 0
  3012. });
  3013. };
  3014. };
  3015. },
  3016. refreshPositions: function(fast) {
  3017. //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
  3018. if(this.offsetParent && this.helper) {
  3019. this.offset.parent = this._getParentOffset();
  3020. }
  3021. for (var i = this.items.length - 1; i >= 0; i--){
  3022. var item = this.items[i];
  3023. var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
  3024. if (!fast) {
  3025. item.width = t.outerWidth();
  3026. item.height = t.outerHeight();
  3027. }
  3028. var p = t.offset();
  3029. item.left = p.left;
  3030. item.top = p.top;
  3031. };
  3032. if(this.options.custom && this.options.custom.refreshContainers) {
  3033. this.options.custom.refreshContainers.call(this);
  3034. } else {
  3035. for (var i = this.containers.length - 1; i >= 0; i--){
  3036. var p = this.containers[i].element.offset();
  3037. this.containers[i].containerCache.left = p.left;
  3038. this.containers[i].containerCache.top = p.top;
  3039. this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
  3040. this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
  3041. };
  3042. }
  3043. return this;
  3044. },
  3045. _createPlaceholder: function(that) {
  3046. var self = that || this, o = self.options;
  3047. if(!o.placeholder || o.placeholder.constructor == String) {
  3048. var className = o.placeholder;
  3049. o.placeholder = {
  3050. element: function() {
  3051. var el = $(document.createElement(self.currentItem[0].nodeName))
  3052. .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
  3053. .removeClass("ui-sortable-helper")[0];
  3054. if(!className)
  3055. el.style.visibility = "hidden";
  3056. return el;
  3057. },
  3058. update: function(container, p) {
  3059. // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
  3060. // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
  3061. if(className && !o.forcePlaceholderSize) return;
  3062. //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
  3063. if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
  3064. if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
  3065. }
  3066. };
  3067. }
  3068. //Create the placeholder
  3069. self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
  3070. //Append it after the actual current item
  3071. self.currentItem.after(self.placeholder);
  3072. //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
  3073. o.placeholder.update(self, self.placeholder);
  3074. },
  3075. _contactContainers: function(event) {
  3076. // get innermost container that intersects with item
  3077. var innermostContainer = null, innermostIndex = null;
  3078. for (var i = this.containers.length - 1; i >= 0; i--){
  3079. // never consider a container that's located within the item itself
  3080. if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
  3081. continue;
  3082. if(this._intersectsWith(this.containers[i].containerCache)) {
  3083. // if we've already found a container and it's more "inner" than this, then continue
  3084. if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
  3085. continue;
  3086. innermostContainer = this.containers[i];
  3087. innermostIndex = i;
  3088. } else {
  3089. // container doesn't intersect. trigger "out" event if necessary
  3090. if(this.containers[i].containerCache.over) {
  3091. this.containers[i]._trigger("out", event, this._uiHash(this));
  3092. this.containers[i].containerCache.over = 0;
  3093. }
  3094. }
  3095. }
  3096. // if no intersecting containers found, return
  3097. if(!innermostContainer) return;
  3098. // move the item into the container if it's not there already
  3099. if(this.containers.length === 1) {
  3100. this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
  3101. this.containers[innermostIndex].containerCache.over = 1;
  3102. } else if(this.currentContainer != this.containers[innermostIndex]) {
  3103. //When entering a new container, we will find the item with the least distance and append our item near it
  3104. var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
  3105. for (var j = this.items.length - 1; j >= 0; j--) {
  3106. if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
  3107. var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top'];
  3108. if(Math.abs(cur - base) < dist) {
  3109. dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
  3110. }
  3111. }
  3112. if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
  3113. return;
  3114. this.currentContainer = this.containers[innermostIndex];
  3115. itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
  3116. this._trigger("change", event, this._uiHash());
  3117. this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
  3118. //Update the placeholder
  3119. this.options.placeholder.update(this.currentContainer, this.placeholder);
  3120. this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
  3121. this.containers[innermostIndex].containerCache.over = 1;
  3122. }
  3123. },
  3124. _createHelper: function(event) {
  3125. var o = this.options;
  3126. var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
  3127. if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
  3128. $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
  3129. if(helper[0] == this.currentItem[0])
  3130. this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
  3131. if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
  3132. if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
  3133. return helper;
  3134. },
  3135. _adjustOffsetFromHelper: function(obj) {
  3136. if (typeof obj == 'string') {
  3137. obj = obj.split(' ');
  3138. }
  3139. if ($.isArray(obj)) {
  3140. obj = {left: +obj[0], top: +obj[1] || 0};
  3141. }
  3142. if ('left' in obj) {
  3143. this.offset.click.left = obj.left + this.margins.left;
  3144. }
  3145. if ('right' in obj) {
  3146. this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  3147. }
  3148. if ('top' in obj) {
  3149. this.offset.click.top = obj.top + this.margins.top;
  3150. }
  3151. if ('bottom' in obj) {
  3152. this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  3153. }
  3154. },
  3155. _getParentOffset: function() {
  3156. //Get the offsetParent and cache its position
  3157. this.offsetParent = this.helper.offsetParent();
  3158. var po = this.offsetParent.offset();
  3159. // This is a special case where we need to modify a offset calculated on start, since the following happened:
  3160. // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
  3161. // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
  3162. // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
  3163. if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
  3164. po.left += this.scrollParent.scrollLeft();
  3165. po.top += this.scrollParent.scrollTop();
  3166. }
  3167. if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
  3168. || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
  3169. po = { top: 0, left: 0 };
  3170. return {
  3171. top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
  3172. left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
  3173. };
  3174. },
  3175. _getRelativeOffset: function() {
  3176. if(this.cssPosition == "relative") {
  3177. var p = this.currentItem.position();
  3178. return {
  3179. top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
  3180. left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
  3181. };
  3182. } else {
  3183. return { top: 0, left: 0 };
  3184. }
  3185. },
  3186. _cacheMargins: function() {
  3187. this.margins = {
  3188. left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
  3189. top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
  3190. };
  3191. },
  3192. _cacheHelperProportions: function() {
  3193. this.helperProportions = {
  3194. width: this.helper.outerWidth(),
  3195. height: this.helper.outerHeight()
  3196. };
  3197. },
  3198. _setContainment: function() {
  3199. var o = this.options;
  3200. if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
  3201. if(o.containment == 'document' || o.containment == 'window') this.containment = [
  3202. 0 - this.offset.relative.left - this.offset.parent.left,
  3203. 0 - this.offset.relative.top - this.offset.parent.top,
  3204. $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
  3205. ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
  3206. ];
  3207. if(!(/^(document|window|parent)$/).test(o.containment)) {
  3208. var ce = $(o.containment)[0];
  3209. var co = $(o.containment).offset();
  3210. var over = ($(ce).css("overflow") != 'hidden');
  3211. this.containment = [
  3212. co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
  3213. co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
  3214. co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
  3215. co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
  3216. ];
  3217. }
  3218. },
  3219. _convertPositionTo: function(d, pos) {
  3220. if(!pos) pos = this.position;
  3221. var mod = d == "absolute" ? 1 : -1;
  3222. var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  3223. return {
  3224. top: (
  3225. pos.top // The absolute mouse position
  3226. + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  3227. + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
  3228. - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
  3229. ),
  3230. left: (
  3231. pos.left // The absolute mouse position
  3232. + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  3233. + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
  3234. - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
  3235. )
  3236. };
  3237. },
  3238. _generatePosition: function(event) {
  3239. var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  3240. // This is another very weird special case that only happens for relative elements:
  3241. // 1. If the css position is relative
  3242. // 2. and the scroll parent is the document or similar to the offset parent
  3243. // we have to refresh the relative offset during the scroll so there are no jumps
  3244. if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
  3245. this.offset.relative = this._getRelativeOffset();
  3246. }
  3247. var pageX = event.pageX;
  3248. var pageY = event.pageY;
  3249. /*
  3250. * - Position constraining -
  3251. * Constrain the position to a mix of grid, containment.
  3252. */
  3253. if(this.originalPosition) { //If we are not dragging yet, we won't check for options
  3254. if(this.containment) {
  3255. if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
  3256. if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
  3257. if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
  3258. if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
  3259. }
  3260. if(o.grid) {
  3261. var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
  3262. pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
  3263. var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
  3264. pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
  3265. }
  3266. }
  3267. return {
  3268. top: (
  3269. pageY // The absolute mouse position
  3270. - this.offset.click.top // Click offset (relative to the element)
  3271. - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
  3272. - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
  3273. + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
  3274. ),
  3275. left: (
  3276. pageX // The absolute mouse position
  3277. - this.offset.click.left // Click offset (relative to the element)
  3278. - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
  3279. - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
  3280. + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
  3281. )
  3282. };
  3283. },
  3284. _rearrange: function(event, i, a, hardRefresh) {
  3285. a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
  3286. //Various things done here to improve the performance:
  3287. // 1. we create a setTimeout, that calls refreshPositions
  3288. // 2. on the instance, we have a counter variable, that get's higher after every append
  3289. // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
  3290. // 4. this lets only the last addition to the timeout stack through
  3291. this.counter = this.counter ? ++this.counter : 1;
  3292. var self = this, counter = this.counter;
  3293. window.setTimeout(function() {
  3294. if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
  3295. },0);
  3296. },
  3297. _clear: function(event, noPropagation) {
  3298. this.reverting = false;
  3299. // We delay all events that have to be triggered to after the point where the placeholder has been removed and
  3300. // everything else normalized again
  3301. var delayedTriggers = [], self = this;
  3302. // We first have to update the dom position of the actual currentItem
  3303. // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
  3304. if(!this._noFinalSort && this.currentItem[0].parentNode) this.placeholder.before(this.currentItem);
  3305. this._noFinalSort = null;
  3306. if(this.helper[0] == this.currentItem[0]) {
  3307. for(var i in this._storedCSS) {
  3308. if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
  3309. }
  3310. this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
  3311. } else {
  3312. this.currentItem.show();
  3313. }
  3314. if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
  3315. if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
  3316. if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
  3317. if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
  3318. for (var i = this.containers.length - 1; i >= 0; i--){
  3319. if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
  3320. delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
  3321. delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
  3322. }
  3323. };
  3324. };
  3325. //Post events to containers
  3326. for (var i = this.containers.length - 1; i >= 0; i--){
  3327. if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
  3328. if(this.containers[i].containerCache.over) {
  3329. delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
  3330. this.containers[i].containerCache.over = 0;
  3331. }
  3332. }
  3333. //Do what was originally in plugins
  3334. if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
  3335. if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
  3336. if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
  3337. this.dragging = false;
  3338. if(this.cancelHelperRemoval) {
  3339. if(!noPropagation) {
  3340. this._trigger("beforeStop", event, this._uiHash());
  3341. for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
  3342. this._trigger("stop", event, this._uiHash());
  3343. }
  3344. return false;
  3345. }
  3346. if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
  3347. //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
  3348. this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
  3349. if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
  3350. if(!noPropagation) {
  3351. for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
  3352. this._trigger("stop", event, this._uiHash());
  3353. }
  3354. this.fromOutside = false;
  3355. return true;
  3356. },
  3357. _trigger: function() {
  3358. if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
  3359. this.cancel();
  3360. }
  3361. },
  3362. _uiHash: function(inst) {
  3363. var self = inst || this;
  3364. return {
  3365. helper: self.helper,
  3366. placeholder: self.placeholder || $([]),
  3367. position: self.position,
  3368. originalPosition: self.originalPosition,
  3369. offset: self.positionAbs,
  3370. item: self.currentItem,
  3371. sender: inst ? inst.element : null
  3372. };
  3373. }
  3374. });
  3375. $.extend($.ui.sortable, {
  3376. version: "1.8.7"
  3377. });
  3378. })(jQuery);